1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4declare void @use(<2 x i1>) 5declare void @use2(i1) 6 7define i32 @select_xor_icmp(i32 %x, i32 %y, i32 %z) { 8; CHECK-LABEL: @select_xor_icmp( 9; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 10; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 11; CHECK-NEXT: ret i32 [[C]] 12; 13 %A = icmp eq i32 %x, 0 14 %B = xor i32 %x, %z 15 %C = select i1 %A, i32 %B, i32 %y 16 ret i32 %C 17} 18 19define i32 @select_xor_icmp2(i32 %x, i32 %y, i32 %z) { 20; CHECK-LABEL: @select_xor_icmp2( 21; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0 22; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Z:%.*]], i32 [[Y:%.*]] 23; CHECK-NEXT: ret i32 [[C]] 24; 25 %A = icmp ne i32 %x, 0 26 %B = xor i32 %x, %z 27 %C = select i1 %A, i32 %y, i32 %B 28 ret i32 %C 29} 30 31define i32 @select_xor_icmp_meta(i32 %x, i32 %y, i32 %z) { 32; CHECK-LABEL: @select_xor_icmp_meta( 33; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 34; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]], !prof !0 35; CHECK-NEXT: ret i32 [[C]] 36; 37 %A = icmp eq i32 %x, 0 38 %B = xor i32 %x, %z 39 %C = select i1 %A, i32 %B, i32 %y, !prof !0 40 ret i32 %C 41} 42 43define i32 @select_mul_icmp(i32 %x, i32 %y, i32 %z) { 44; CHECK-LABEL: @select_mul_icmp( 45; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 46; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 47; CHECK-NEXT: ret i32 [[C]] 48; 49 %A = icmp eq i32 %x, 1 50 %B = mul i32 %x, %z 51 %C = select i1 %A, i32 %B, i32 %y 52 ret i32 %C 53} 54 55define i32 @select_add_icmp(i32 %x, i32 %y, i32 %z) { 56; CHECK-LABEL: @select_add_icmp( 57; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 58; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 59; CHECK-NEXT: ret i32 [[C]] 60; 61 %A = icmp eq i32 %x, 0 62 %B = add i32 %x, %z 63 %C = select i1 %A, i32 %B, i32 %y 64 ret i32 %C 65} 66 67define i32 @select_or_icmp(i32 %x, i32 %y, i32 %z) { 68; CHECK-LABEL: @select_or_icmp( 69; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 70; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 71; CHECK-NEXT: ret i32 [[C]] 72; 73 %A = icmp eq i32 %x, 0 74 %B = or i32 %x, %z 75 %C = select i1 %A, i32 %B, i32 %y 76 ret i32 %C 77} 78 79define i32 @select_and_icmp(i32 %x, i32 %y, i32 %z) { 80; CHECK-LABEL: @select_and_icmp( 81; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], -1 82; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 83; CHECK-NEXT: ret i32 [[C]] 84; 85 %A = icmp eq i32 %x, -1 86 %B = and i32 %x, %z 87 %C = select i1 %A, i32 %B, i32 %y 88 ret i32 %C 89} 90 91define <2 x i8> @select_xor_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 92; CHECK-LABEL: @select_xor_icmp_vec( 93; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer 94; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]] 95; CHECK-NEXT: ret <2 x i8> [[C]] 96; 97 %A = icmp eq <2 x i8> %x, <i8 0, i8 0> 98 %B = xor <2 x i8> %x, %z 99 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 100 ret <2 x i8> %C 101} 102 103define <2 x i8> @select_xor_icmp_vec_use(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 104; CHECK-LABEL: @select_xor_icmp_vec_use( 105; CHECK-NEXT: [[A:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer 106; CHECK-NEXT: call void @use(<2 x i1> [[A]]) 107; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]] 108; CHECK-NEXT: ret <2 x i8> [[C]] 109; 110 %A = icmp ne <2 x i8> %x, <i8 0, i8 0> 111 call void @use(<2 x i1> %A) 112 %B = xor <2 x i8> %x, %z 113 %C = select <2 x i1> %A, <2 x i8> %y, <2 x i8> %B 114 ret <2 x i8> %C 115} 116 117define i32 @select_xor_inv_icmp(i32 %x, i32 %y, i32 %z) { 118; CHECK-LABEL: @select_xor_inv_icmp( 119; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 120; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 121; CHECK-NEXT: ret i32 [[C]] 122; 123 %A = icmp eq i32 %x, 0 124 %B = xor i32 %z, %x 125 %C = select i1 %A, i32 %B, i32 %y 126 ret i32 %C 127} 128 129define i32 @select_xor_inv_icmp2(i32 %x, i32 %y, i32 %z) { 130; CHECK-LABEL: @select_xor_inv_icmp2( 131; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 132; CHECK-NEXT: call void @use2(i1 [[A]]) 133; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 134; CHECK-NEXT: ret i32 [[C]] 135; 136 %A = icmp ne i32 %x, 0 137 call void @use2(i1 %A) ; thwart predicate canonicalization 138 %B = xor i32 %x, %z 139 %C = select i1 %A, i32 %y, i32 %B 140 ret i32 %C 141} 142 143define float @select_fadd_fcmp(float %x, float %y, float %z) { 144; CHECK-LABEL: @select_fadd_fcmp( 145; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 146; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 147; CHECK-NEXT: ret float [[C]] 148; 149 %A = fcmp oeq float %x, -0.0 150 %B = fadd nsz float %x, %z 151 %C = select i1 %A, float %B, float %y 152 ret float %C 153} 154 155; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 156 157define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) { 158; CHECK-LABEL: @select_fadd_fcmp_poszero( 159; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 160; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 161; CHECK-NEXT: ret float [[C]] 162; 163 %A = fcmp oeq float %x, 0.0 164 %B = fadd nsz float %z, %x 165 %C = select i1 %A, float %B, float %y 166 ret float %C 167} 168 169define float @select_fadd_fcmp_2(float %x, float %y, float %v) { 170; CHECK-LABEL: @select_fadd_fcmp_2( 171; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 172; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 173; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]] 174; CHECK-NEXT: ret float [[C]] 175; 176 %A = fcmp une float %x, -0.0 177 %z = fadd float %v, 0.0 ; cannot produce -0.0 178 %B = fadd float %z, %x 179 %C = select i1 %A, float %y, float %B 180 ret float %C 181} 182 183; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 184 185define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) { 186; CHECK-LABEL: @select_fadd_fcmp_2_poszero( 187; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 188; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 189; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]] 190; CHECK-NEXT: ret float [[C]] 191; 192 %A = fcmp une float %x, 0.0 193 %z = fadd float %v, 0.0 ; cannot produce -0.0 194 %B = fadd float %z, %x 195 %C = select i1 %A, float %y, float %B 196 ret float %C 197} 198 199define float @select_fadd_fcmp_3(float %x, float %y) { 200; CHECK-LABEL: @select_fadd_fcmp_3( 201; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 202; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00 203; CHECK-NEXT: ret float [[C]] 204; 205 %A = fcmp une float %x, -0.0 206 %B = fadd float 6.0, %x 207 %C = select i1 %A, float %y, float %B 208 ret float %C 209} 210 211; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 212 213define float @select_fadd_fcmp_3_poszero(float %x, float %y) { 214; CHECK-LABEL: @select_fadd_fcmp_3_poszero( 215; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 216; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00 217; CHECK-NEXT: ret float [[C]] 218; 219 %A = fcmp une float %x, 0.0 220 %B = fadd float 6.0, %x 221 %C = select i1 %A, float %y, float %B 222 ret float %C 223} 224 225define float @select_fadd_fcmp_4(float %x, float %y, float %z) { 226; CHECK-LABEL: @select_fadd_fcmp_4( 227; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 228; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]] 229; CHECK-NEXT: ret float [[C]] 230; 231 %A = fcmp une float %x, -0.0 232 %B = fadd nsz float %z, %x 233 %C = select i1 %A, float %y, float %B 234 ret float %C 235} 236 237; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 238 239define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) { 240; CHECK-LABEL: @select_fadd_fcmp_4_poszero( 241; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 242; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]] 243; CHECK-NEXT: ret float [[C]] 244; 245 %A = fcmp une float %x, 0.0 246 %B = fadd nsz float %z, %x 247 %C = select i1 %A, float %y, float %B 248 ret float %C 249} 250 251define float @select_fadd_fcmp_5(float %x, float %y, float %v) { 252; CHECK-LABEL: @select_fadd_fcmp_5( 253; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 254; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 255; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]] 256; CHECK-NEXT: ret float [[C]] 257; 258 %A = fcmp oeq float %x, -0.0 259 %z = fadd float %v, 0.0 ; cannot produce -0.0 260 %B = fadd float %z, %x 261 %C = select i1 %A, float %B, float %y 262 ret float %C 263} 264 265; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 266 267define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) { 268; CHECK-LABEL: @select_fadd_fcmp_5_poszero( 269; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 270; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 271; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]] 272; CHECK-NEXT: ret float [[C]] 273; 274 %A = fcmp oeq float %x, 0.0 275 %z = fadd float %v, 0.0 ; cannot produce -0.0 276 %B = fadd float %z, %x 277 %C = select i1 %A, float %B, float %y 278 ret float %C 279} 280 281define float @select_fadd_fcmp_6(float %x, float %y, float %z) { 282; CHECK-LABEL: @select_fadd_fcmp_6( 283; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 284; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]] 285; CHECK-NEXT: ret float [[C]] 286; 287 %A = fcmp oeq float %x, -0.0 288 %B = fadd float %x, 6.0 289 %C = select i1 %A, float %B, float %y 290 ret float %C 291} 292 293; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 294 295define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) { 296; CHECK-LABEL: @select_fadd_fcmp_6_poszero( 297; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 298; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]] 299; CHECK-NEXT: ret float [[C]] 300; 301 %A = fcmp oeq float %x, 0.0 302 %B = fadd float %x, 6.0 303 %C = select i1 %A, float %B, float %y 304 ret float %C 305} 306 307define float @select_fmul_fcmp(float %x, float %y, float %z) { 308; CHECK-LABEL: @select_fmul_fcmp( 309; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 310; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 311; CHECK-NEXT: ret float [[C]] 312; 313 %A = fcmp oeq float %x, 1.0 314 %B = fmul nsz float %x, %z 315 %C = select i1 %A, float %B, float %y 316 ret float %C 317} 318 319define float @select_fsub_fcmp(float %x, float %y, float %z) { 320; CHECK-LABEL: @select_fsub_fcmp( 321; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 322; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 323; CHECK-NEXT: ret float [[C]] 324; 325 %A = fcmp oeq float %x, 0.0 326 %B = fsub nsz float %z, %x 327 %C = select i1 %A, float %B, float %y 328 ret float %C 329} 330 331; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 332 333define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) { 334; CHECK-LABEL: @select_fsub_fcmp_negzero( 335; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 336; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 337; CHECK-NEXT: ret float [[C]] 338; 339 %A = fcmp oeq float %x, -0.0 340 %B = fsub nsz float %z, %x 341 %C = select i1 %A, float %B, float %y 342 ret float %C 343} 344 345define float @select_fdiv_fcmp(float %x, float %y, float %z) { 346; CHECK-LABEL: @select_fdiv_fcmp( 347; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 348; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 349; CHECK-NEXT: ret float [[C]] 350; 351 %A = fcmp oeq float %x, 1.0 352 %B = fdiv nsz float %z, %x 353 %C = select i1 %A, float %B, float %y 354 ret float %C 355} 356 357define i32 @select_sub_icmp(i32 %x, i32 %y, i32 %z) { 358; CHECK-LABEL: @select_sub_icmp( 359; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 360; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 361; CHECK-NEXT: ret i32 [[C]] 362; 363 %A = icmp eq i32 %x, 0 364 %B = sub i32 %z, %x 365 %C = select i1 %A, i32 %B, i32 %y 366 ret i32 %C 367} 368 369define i32 @select_sub_icmp_2(i32 %x, i32 %y, i32 %z) { 370; CHECK-LABEL: @select_sub_icmp_2( 371; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 372; CHECK-NEXT: call void @use2(i1 [[A]]) 373; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 374; CHECK-NEXT: ret i32 [[C]] 375; 376 %A = icmp eq i32 %x, 0 377 call void @use2(i1 %A) 378 %B = sub i32 %z, %x 379 %C = select i1 %A, i32 %B, i32 %y 380 ret i32 %C 381} 382 383define i32 @select_sub_icmp_3(i32 %x, i32 %y, i32 %z) { 384; CHECK-LABEL: @select_sub_icmp_3( 385; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 386; CHECK-NEXT: call void @use2(i1 [[A]]) 387; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 388; CHECK-NEXT: ret i32 [[C]] 389; 390 %A = icmp ne i32 %x, 0 391 call void @use2(i1 %A) 392 %B = sub i32 %z, %x 393 %C = select i1 %A, i32 %y, i32 %B 394 ret i32 %C 395} 396 397define <2 x i8> @select_sub_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 398; CHECK-LABEL: @select_sub_icmp_vec( 399; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer 400; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]] 401; CHECK-NEXT: ret <2 x i8> [[C]] 402; 403 %A = icmp eq <2 x i8> %x, <i8 0, i8 0> 404 %B = sub <2 x i8> %z, %x 405 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 406 ret <2 x i8> %C 407} 408 409define i32 @select_shl_icmp(i32 %x, i32 %y, i32 %z) { 410; CHECK-LABEL: @select_shl_icmp( 411; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 412; CHECK-NEXT: call void @use2(i1 [[A]]) 413; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 414; CHECK-NEXT: ret i32 [[C]] 415; 416 %A = icmp ne i32 %x, 0 417 call void @use2(i1 %A) ; thwart predicate canonicalization 418 %B = shl i32 %z, %x 419 %C = select i1 %A, i32 %y, i32 %B 420 ret i32 %C 421} 422 423define i32 @select_lshr_icmp(i32 %x, i32 %y, i32 %z) { 424; CHECK-LABEL: @select_lshr_icmp( 425; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 426; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 427; CHECK-NEXT: ret i32 [[C]] 428; 429 %A = icmp eq i32 %x, 0 430 %B = lshr i32 %z, %x 431 %C = select i1 %A, i32 %B, i32 %y 432 ret i32 %C 433} 434 435define i32 @select_ashr_icmp(i32 %x, i32 %y, i32 %z) { 436; CHECK-LABEL: @select_ashr_icmp( 437; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 438; CHECK-NEXT: call void @use2(i1 [[A]]) 439; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 440; CHECK-NEXT: ret i32 [[C]] 441; 442 %A = icmp ne i32 %x, 0 443 call void @use2(i1 %A) ; thwart predicate canonicalization 444 %B = ashr i32 %z, %x 445 %C = select i1 %A, i32 %y, i32 %B 446 ret i32 %C 447} 448 449define i32 @select_udiv_icmp(i32 %x, i32 %y, i32 %z) { 450; CHECK-LABEL: @select_udiv_icmp( 451; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 452; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 453; CHECK-NEXT: ret i32 [[C]] 454; 455 %A = icmp eq i32 %x, 1 456 %B = udiv i32 %z, %x 457 %C = select i1 %A, i32 %B, i32 %y 458 ret i32 %C 459} 460 461define i32 @select_sdiv_icmp(i32 %x, i32 %y, i32 %z) { 462; CHECK-LABEL: @select_sdiv_icmp( 463; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 1 464; CHECK-NEXT: call void @use2(i1 [[A]]) 465; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 466; CHECK-NEXT: ret i32 [[C]] 467; 468 %A = icmp ne i32 %x, 1 469 call void @use2(i1 %A) ; thwart predicate canonicalization 470 %B = sdiv i32 %z, %x 471 %C = select i1 %A, i32 %y, i32 %B 472 ret i32 %C 473} 474 475; Negative tests 476define i32 @select_xor_icmp_bad_1(i32 %x, i32 %y, i32 %z, i32 %k) { 477; CHECK-LABEL: @select_xor_icmp_bad_1( 478; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]] 479; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]] 480; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 481; CHECK-NEXT: ret i32 [[C]] 482; 483 %A = icmp eq i32 %x, %k 484 %B = xor i32 %x, %z 485 %C = select i1 %A, i32 %B, i32 %y 486 ret i32 %C 487} 488 489define i32 @select_xor_icmp_bad_2(i32 %x, i32 %y, i32 %z, i32 %k) { 490; CHECK-LABEL: @select_xor_icmp_bad_2( 491; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 492; CHECK-NEXT: [[B:%.*]] = xor i32 [[K:%.*]], [[Z:%.*]] 493; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 494; CHECK-NEXT: ret i32 [[C]] 495; 496 %A = icmp eq i32 %x, 0 497 %B = xor i32 %k, %z 498 %C = select i1 %A, i32 %B, i32 %y 499 ret i32 %C 500} 501 502define i32 @select_xor_icmp_bad_3(i32 %x, i32 %y, i32 %z) { 503; CHECK-LABEL: @select_xor_icmp_bad_3( 504; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 505; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]] 506; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 507; CHECK-NEXT: ret i32 [[C]] 508; 509 %A = icmp eq i32 %x, 3 510 %B = xor i32 %x, %z 511 %C = select i1 %A, i32 %B, i32 %y 512 ret i32 %C 513} 514 515define i32 @select_xor_fcmp_bad_4(i32 %x, i32 %y, i32 %z, float %k) { 516; CHECK-LABEL: @select_xor_fcmp_bad_4( 517; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[K:%.*]], 0.000000e+00 518; CHECK-NEXT: [[B:%.*]] = xor i32 [[X:%.*]], [[Z:%.*]] 519; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 520; CHECK-NEXT: ret i32 [[C]] 521; 522 %A = fcmp oeq float %k, 0.0 523 %B = xor i32 %x, %z 524 %C = select i1 %A, i32 %B, i32 %y 525 ret i32 %C 526} 527 528define i32 @select_xor_icmp_bad_5(i32 %x, i32 %y, i32 %z) { 529; CHECK-LABEL: @select_xor_icmp_bad_5( 530; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0 531; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]] 532; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Y:%.*]], i32 [[B]] 533; CHECK-NEXT: ret i32 [[C]] 534; 535 %A = icmp ne i32 %x, 0 536 %B = xor i32 %x, %z 537 %C = select i1 %A, i32 %B, i32 %y 538 ret i32 %C 539} 540 541define i32 @select_xor_icmp_bad_6(i32 %x, i32 %y, i32 %z) { 542; CHECK-LABEL: @select_xor_icmp_bad_6( 543; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 1 544; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]] 545; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[B]], i32 [[Y:%.*]] 546; CHECK-NEXT: ret i32 [[C]] 547; 548 %A = icmp ne i32 %x, 1 549 %B = xor i32 %x, %z 550 %C = select i1 %A, i32 %y, i32 %B 551 ret i32 %C 552} 553 554define <2 x i8> @select_xor_icmp_vec_bad(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 555; CHECK-LABEL: @select_xor_icmp_vec_bad( 556; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 5, i8 3> 557; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]] 558; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]] 559; CHECK-NEXT: ret <2 x i8> [[C]] 560; 561 %A = icmp eq <2 x i8> %x, <i8 5, i8 3> 562 %B = xor <2 x i8> %x, %z 563 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 564 ret <2 x i8> %C 565} 566 567; Folding this would only be legal if we sanitized undef to 0. 568define <2 x i8> @select_xor_icmp_vec_undef(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 569; CHECK-LABEL: @select_xor_icmp_vec_undef( 570; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 0, i8 undef> 571; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]] 572; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]] 573; CHECK-NEXT: ret <2 x i8> [[C]] 574; 575 %A = icmp eq <2 x i8> %x, <i8 0, i8 undef> 576 %B = xor <2 x i8> %x, %z 577 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 578 ret <2 x i8> %C 579} 580 581define i32 @select_mul_icmp_bad(i32 %x, i32 %y, i32 %z, i32 %k) { 582; CHECK-LABEL: @select_mul_icmp_bad( 583; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 584; CHECK-NEXT: [[B:%.*]] = mul i32 [[X]], [[Z:%.*]] 585; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 586; CHECK-NEXT: ret i32 [[C]] 587; 588 %A = icmp eq i32 %x, 3 589 %B = mul i32 %x, %z 590 %C = select i1 %A, i32 %B, i32 %y 591 ret i32 %C 592} 593 594define i32 @select_add_icmp_bad(i32 %x, i32 %y, i32 %z) { 595; CHECK-LABEL: @select_add_icmp_bad( 596; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 597; CHECK-NEXT: [[B:%.*]] = add i32 [[X]], [[Z:%.*]] 598; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 599; CHECK-NEXT: ret i32 [[C]] 600; 601 %A = icmp eq i32 %x, 1 602 %B = add i32 %x, %z 603 %C = select i1 %A, i32 %B, i32 %y 604 ret i32 %C 605} 606 607define i32 @select_and_icmp_zero(i32 %x, i32 %y, i32 %z) { 608; CHECK-LABEL: @select_and_icmp_zero( 609; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 610; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 0, i32 [[Y:%.*]] 611; CHECK-NEXT: ret i32 [[C]] 612; 613 %A = icmp eq i32 %x, 0 614 %B = and i32 %x, %z 615 %C = select i1 %A, i32 %B, i32 %y 616 ret i32 %C 617} 618 619define i32 @select_or_icmp_bad(i32 %x, i32 %y, i32 %z) { 620; CHECK-LABEL: @select_or_icmp_bad( 621; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 622; CHECK-NEXT: [[B:%.*]] = or i32 [[X]], [[Z:%.*]] 623; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 624; CHECK-NEXT: ret i32 [[C]] 625; 626 %A = icmp eq i32 %x, 3 627 %B = or i32 %x, %z 628 %C = select i1 %A, i32 %B, i32 %y 629 ret i32 %C 630} 631 632; Invalid identity constant for FP op 633define float @select_fadd_fcmp_bad(float %x, float %y, float %z) { 634; CHECK-LABEL: @select_fadd_fcmp_bad( 635; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00 636; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]] 637; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 638; CHECK-NEXT: ret float [[C]] 639; 640 %A = fcmp oeq float %x, -1.0 641 %B = fadd nsz float %x, %z 642 %C = select i1 %A, float %B, float %y 643 ret float %C 644} 645 646; Invalid comparison type 647define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) { 648; CHECK-LABEL: @select_fadd_fcmp_bad_2( 649; CHECK-NEXT: [[A:%.*]] = fcmp ueq float [[X:%.*]], -1.000000e+00 650; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 651; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 652; CHECK-NEXT: ret float [[C]] 653; 654 %A = fcmp ueq float %x, -1.0 655 %B = fadd float %x, %z 656 %C = select i1 %A, float %B, float %y 657 ret float %C 658} 659 660; Invalid comparison type 661define float @select_fadd_fcmp_bad_3(float %x, float %y, float %z, float %k) { 662; CHECK-LABEL: @select_fadd_fcmp_bad_3( 663; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], [[K:%.*]] 664; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 665; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 666; CHECK-NEXT: ret float [[C]] 667; 668 %A = fcmp one float %x, %k 669 %B = fadd float %x, %z 670 %C = select i1 %A, float %y, float %B 671 ret float %C 672} 673 674; Invalid order of operands of select 675define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) { 676; CHECK-LABEL: @select_fadd_fcmp_bad_4( 677; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 678; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 679; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 680; CHECK-NEXT: ret float [[C]] 681; 682 %A = fcmp une float %x, -0.0 683 %B = fadd float %x, %z 684 %C = select i1 %A, float %B, float %y 685 ret float %C 686} 687 688; Invalid comparison type 689define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) { 690; CHECK-LABEL: @select_fadd_fcmp_bad_5( 691; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 692; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]] 693; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 694; CHECK-NEXT: ret float [[C]] 695; 696 %A = fcmp one float %x, -0.0 697 %B = fadd nsz float %z, %x 698 %C = select i1 %A, float %y, float %B 699 ret float %C 700} 701 702; Invalid order of operands of select 703define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) { 704; CHECK-LABEL: @select_fadd_fcmp_bad_6( 705; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 706; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]] 707; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 708; CHECK-NEXT: ret float [[C]] 709; 710 %A = fcmp oeq float %x, -0.0 711 %B = fadd nsz float %z, %x 712 %C = select i1 %A, float %y, float %B 713 ret float %C 714} 715 716; Do not transform if we have signed zeros and if Z is possibly negative zero 717define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) { 718; CHECK-LABEL: @select_fadd_fcmp_bad_7( 719; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 720; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 721; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 722; CHECK-NEXT: ret float [[C]] 723; 724 %A = fcmp oeq float %x, -0.0 725 %B = fadd float %x, %z 726 %C = select i1 %A, float %B, float %y 727 ret float %C 728} 729 730; Invalid comparison type 731define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) { 732; CHECK-LABEL: @select_fadd_fcmp_bad_8( 733; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 734; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00 735; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]] 736; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 737; CHECK-NEXT: ret float [[C]] 738; 739 %A = fcmp one float %x, -0.0 740 %z = fadd float %v, -1.0 741 %B = fadd float %z, %x 742 %C = select i1 %A, float %y, float %B 743 ret float %C 744} 745 746; Invalid comparison type 747define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) { 748; CHECK-LABEL: @select_fadd_fcmp_bad_9( 749; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 750; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]] 751; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 752; CHECK-NEXT: ret float [[C]] 753; 754 %A = fcmp one float %x, -0.0 755 %B = fadd nsz float %z, %x 756 %C = select i1 %A, float %y, float %B 757 ret float %C 758} 759 760; Invalid comparison type 761define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) { 762; CHECK-LABEL: @select_fadd_fcmp_bad_10( 763; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 764; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 765; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]] 766; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 767; CHECK-NEXT: ret float [[C]] 768; 769 %A = fcmp one float %x, -0.0 770 %z = fadd float %v, 0.0 ; cannot produce -0.0 771 %B = fadd float %z, %x 772 %C = select i1 %A, float %y, float %B 773 ret float %C 774} 775 776; Do not transform if Z is possibly negative zero 777define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) { 778; CHECK-LABEL: @select_fadd_fcmp_bad_11( 779; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 780; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00 781; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]] 782; CHECK-NEXT: ret float [[C]] 783; 784 %A = fcmp une float %x, -0.0 785 %z = fadd float %v, -1.0 786 %B = fadd nsz float %z, %x 787 %C = select i1 %A, float %y, float %B 788 ret float %C 789} 790 791; Do not transform if we have signed zeros and if Z is possibly negative zero 792define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) { 793; CHECK-LABEL: @select_fadd_fcmp_bad_12( 794; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 795; CHECK-NEXT: [[B:%.*]] = fadd float [[Z:%.*]], [[X]] 796; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 797; CHECK-NEXT: ret float [[C]] 798; 799 %A = fcmp une float %x, -0.0 800 %B = fadd float %z, %x 801 %C = select i1 %A, float %y, float %B 802 ret float %C 803} 804 805; Invalid order of operands of select 806define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) { 807; CHECK-LABEL: @select_fadd_fcmp_bad_13( 808; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 809; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]] 810; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 811; CHECK-NEXT: ret float [[C]] 812; 813 %A = fcmp oeq float %x, -0.0 814 %B = fadd nsz float %x, %z 815 %C = select i1 %A, float %y, float %B 816 ret float %C 817} 818 819; Invalid identity constant for FP op 820define float @select_fadd_fcmp_bad_14(float %x, float %y, float %z) { 821; CHECK-LABEL: @select_fadd_fcmp_bad_14( 822; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00 823; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]] 824; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 825; CHECK-NEXT: ret float [[C]] 826; 827 %A = fcmp une float %x, -1.0 828 %B = fadd nsz float %x, %z 829 %C = select i1 %A, float %y, float %B 830 ret float %C 831} 832 833define float @select_fmul_fcmp_bad(float %x, float %y, float %z) { 834; CHECK-LABEL: @select_fmul_fcmp_bad( 835; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00 836; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[X]], [[Z:%.*]] 837; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 838; CHECK-NEXT: ret float [[C]] 839; 840 %A = fcmp oeq float %x, 3.0 841 %B = fmul nsz float %x, %z 842 %C = select i1 %A, float %B, float %y 843 ret float %C 844} 845 846define float @select_fmul_fcmp_bad_2(float %x, float %y, float %z) { 847; CHECK-LABEL: @select_fmul_fcmp_bad_2( 848; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 849; CHECK-NEXT: [[B:%.*]] = fmul float [[X]], [[Z:%.*]] 850; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 851; CHECK-NEXT: ret float [[C]] 852; 853 %A = fcmp oeq float %x, 1.0 854 %B = fmul float %x, %z 855 %C = select i1 %A, float %B, float %y 856 ret float %C 857} 858 859define float @select_fmul_icmp_bad(float %x, float %y, float %z, i32 %k) { 860; CHECK-LABEL: @select_fmul_icmp_bad( 861; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0 862; CHECK-NEXT: [[B:%.*]] = fmul float [[X:%.*]], [[Z:%.*]] 863; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 864; CHECK-NEXT: ret float [[C]] 865; 866 %A = icmp eq i32 %k, 0 867 %B = fmul float %x, %z 868 %C = select i1 %A, float %B, float %y 869 ret float %C 870} 871 872define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) { 873; CHECK-LABEL: @select_fmul_icmp_bad_2( 874; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0 875; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[X:%.*]], [[Z:%.*]] 876; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 877; CHECK-NEXT: ret float [[C]] 878; 879 %A = icmp eq i32 %k, 0 880 %B = fmul nsz float %x, %z 881 %C = select i1 %A, float %B, float %y 882 ret float %C 883} 884 885define float @select_fdiv_fcmp_bad(float %x, float %y, float %z) { 886; CHECK-LABEL: @select_fdiv_fcmp_bad( 887; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 888; CHECK-NEXT: [[B:%.*]] = fdiv float [[X]], [[Z:%.*]] 889; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 890; CHECK-NEXT: ret float [[C]] 891; 892 %A = fcmp oeq float %x, 1.0 893 %B = fdiv float %x, %z 894 %C = select i1 %A, float %B, float %y 895 ret float %C 896} 897 898define float @select_fdiv_fcmp_bad_2(float %x, float %y, float %z) { 899; CHECK-LABEL: @select_fdiv_fcmp_bad_2( 900; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00 901; CHECK-NEXT: [[B:%.*]] = fdiv nsz float [[X]], [[Z:%.*]] 902; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 903; CHECK-NEXT: ret float [[C]] 904; 905 %A = fcmp oeq float %x, 3.0 906 %B = fdiv nsz float %x, %z 907 %C = select i1 %A, float %B, float %y 908 ret float %C 909} 910 911; The transform is not valid when x = -0.0 and z = -0.0 912; (optimized code would return -0.0, but this returns +0.0). 913 914define float @select_fsub_fcmp_bad(float %x, float %y, float %z) { 915; CHECK-LABEL: @select_fsub_fcmp_bad( 916; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 917; CHECK-NEXT: [[B:%.*]] = fsub float [[Z:%.*]], [[X]] 918; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 919; CHECK-NEXT: ret float [[C]] 920; 921 %A = fcmp oeq float %x, 0.0 922 %B = fsub float %z, %x 923 %C = select i1 %A, float %B, float %y 924 ret float %C 925} 926 927define float @select_fsub_fcmp_bad_2(float %x, float %y, float %z) { 928; CHECK-LABEL: @select_fsub_fcmp_bad_2( 929; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 930; CHECK-NEXT: [[B:%.*]] = fsub nsz float [[Z:%.*]], [[X]] 931; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 932; CHECK-NEXT: ret float [[C]] 933; 934 %A = fcmp oeq float %x, 1.0 935 %B = fsub nsz float %z, %x 936 %C = select i1 %A, float %B, float %y 937 ret float %C 938} 939 940define i32 @select_sub_icmp_bad(i32 %x, i32 %y, i32 %z) { 941; CHECK-LABEL: @select_sub_icmp_bad( 942; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 943; CHECK-NEXT: [[B:%.*]] = sub i32 [[X]], [[Z:%.*]] 944; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 945; CHECK-NEXT: ret i32 [[C]] 946; 947 %A = icmp eq i32 %x, 0 948 %B = sub i32 %x, %z 949 %C = select i1 %A, i32 %B, i32 %y 950 ret i32 %C 951} 952 953define i32 @select_sub_icmp_bad_2(i32 %x, i32 %y, i32 %z) { 954; CHECK-LABEL: @select_sub_icmp_bad_2( 955; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 956; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]] 957; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 958; CHECK-NEXT: ret i32 [[C]] 959; 960 %A = icmp eq i32 %x, 1 961 %B = sub i32 %z, %x 962 %C = select i1 %A, i32 %B, i32 %y 963 ret i32 %C 964} 965 966define i32 @select_sub_icmp_bad_3(i32 %x, i32 %y, i32 %z) { 967; CHECK-LABEL: @select_sub_icmp_bad_3( 968; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 969; CHECK-NEXT: call void @use2(i1 [[A]]) 970; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]] 971; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 972; CHECK-NEXT: ret i32 [[C]] 973; 974 %A = icmp ne i32 %x, 0 975 call void @use2(i1 %A) 976 %B = sub i32 %z, %x 977 %C = select i1 %A, i32 %B, i32 %y 978 ret i32 %C 979} 980 981define i32 @select_sub_icmp_4(i32 %x, i32 %y, i32 %z) { 982; CHECK-LABEL: @select_sub_icmp_4( 983; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 984; CHECK-NEXT: call void @use2(i1 [[A]]) 985; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]] 986; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 987; CHECK-NEXT: ret i32 [[C]] 988; 989 %A = icmp ne i32 %x, 0 990 call void @use2(i1 %A) 991 %B = sub i32 %z, %x 992 %C = select i1 %A, i32 %B, i32 %y 993 ret i32 %C 994} 995 996define i32 @select_sub_icmp_bad_4(i32 %x, i32 %y, i32 %z, i32 %k) { 997; CHECK-LABEL: @select_sub_icmp_bad_4( 998; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 999; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[K:%.*]] 1000; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1001; CHECK-NEXT: ret i32 [[C]] 1002; 1003 %A = icmp eq i32 %x, 0 1004 %B = sub i32 %z, %k 1005 %C = select i1 %A, i32 %B, i32 %y 1006 ret i32 %C 1007} 1008 1009define i32 @select_sub_icmp_bad_5(i32 %x, i32 %y, i32 %z, i32 %k) { 1010; CHECK-LABEL: @select_sub_icmp_bad_5( 1011; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]] 1012; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]] 1013; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1014; CHECK-NEXT: ret i32 [[C]] 1015; 1016 %A = icmp eq i32 %x, %k 1017 %B = sub i32 %z, %x 1018 %C = select i1 %A, i32 %B, i32 %y 1019 ret i32 %C 1020} 1021 1022define i32 @select_shl_icmp_bad(i32 %x, i32 %y, i32 %z) { 1023; CHECK-LABEL: @select_shl_icmp_bad( 1024; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 1025; CHECK-NEXT: [[B:%.*]] = shl i32 [[Z:%.*]], [[X]] 1026; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1027; CHECK-NEXT: ret i32 [[C]] 1028; 1029 %A = icmp eq i32 %x, 1 1030 %B = shl i32 %z, %x 1031 %C = select i1 %A, i32 %B, i32 %y 1032 ret i32 %C 1033} 1034 1035define i32 @select_lshr_icmp_bad(i32 %x, i32 %y, i32 %z) { 1036; CHECK-LABEL: @select_lshr_icmp_bad( 1037; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 1038; CHECK-NEXT: [[B:%.*]] = lshr i32 [[Z:%.*]], [[X]] 1039; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1040; CHECK-NEXT: ret i32 [[C]] 1041; 1042 %A = icmp eq i32 %x, 1 1043 %B = lshr i32 %z, %x 1044 %C = select i1 %A, i32 %B, i32 %y 1045 ret i32 %C 1046} 1047 1048define i32 @select_ashr_icmp_bad(i32 %x, i32 %y, i32 %z) { 1049; CHECK-LABEL: @select_ashr_icmp_bad( 1050; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 1051; CHECK-NEXT: [[B:%.*]] = ashr i32 [[Z:%.*]], [[X]] 1052; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1053; CHECK-NEXT: ret i32 [[C]] 1054; 1055 %A = icmp eq i32 %x, 1 1056 %B = ashr i32 %z, %x 1057 %C = select i1 %A, i32 %B, i32 %y 1058 ret i32 %C 1059} 1060 1061define i32 @select_udiv_icmp_bad(i32 %x, i32 %y, i32 %z) { 1062; CHECK-LABEL: @select_udiv_icmp_bad( 1063; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 1064; CHECK-NEXT: [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]] 1065; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1066; CHECK-NEXT: ret i32 [[C]] 1067; 1068 %A = icmp eq i32 %x, 3 1069 %B = udiv i32 %z, %x 1070 %C = select i1 %A, i32 %B, i32 %y 1071 ret i32 %C 1072} 1073 1074define i32 @select_sdiv_icmp_bad(i32 %x, i32 %y, i32 %z) { 1075; CHECK-LABEL: @select_sdiv_icmp_bad( 1076; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 1077; CHECK-NEXT: [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]] 1078; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1079; CHECK-NEXT: ret i32 [[C]] 1080; 1081 %A = icmp eq i32 %x, 3 1082 %B = sdiv i32 %z, %x 1083 %C = select i1 %A, i32 %B, i32 %y 1084 ret i32 %C 1085} 1086 1087!0 = !{!"branch_weights", i32 2, i32 10} 1088