1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4define i1 @bool_true_or_false(i1 %cond) { 5; CHECK-LABEL: @bool_true_or_false( 6; CHECK-NEXT: ret i1 [[COND:%.*]] 7; 8 %s = select i1 %cond, i1 true, i1 false 9 ret i1 %s 10} 11 12define i1 @cond_constexpr_bool_true_or_false(i1 %cond) { 13; CHECK-LABEL: @cond_constexpr_bool_true_or_false( 14; CHECK-NEXT: ret i1 ptrtoint (ptr @cond_constexpr_bool_true_or_false to i1) 15; 16 %s = select i1 ptrtoint (ptr @cond_constexpr_bool_true_or_false to i1), i1 true, i1 false 17 ret i1 %s 18} 19 20define <2 x i1> @bool_true_or_false_vec(<2 x i1> %cond) { 21; CHECK-LABEL: @bool_true_or_false_vec( 22; CHECK-NEXT: ret <2 x i1> [[COND:%.*]] 23; 24 %s = select <2 x i1> %cond, <2 x i1> <i1 true, i1 true>, <2 x i1> zeroinitializer 25 ret <2 x i1> %s 26} 27 28define <2 x i1> @bool_true_or_false_vec_poison(<2 x i1> %cond) { 29; CHECK-LABEL: @bool_true_or_false_vec_poison( 30; CHECK-NEXT: ret <2 x i1> [[COND:%.*]] 31; 32 %s = select <2 x i1> %cond, <2 x i1> <i1 poison, i1 true>, <2 x i1> <i1 false, i1 poison> 33 ret <2 x i1> %s 34} 35 36define i32 @cond_is_false(i32 %A, i32 %B) { 37; CHECK-LABEL: @cond_is_false( 38; CHECK-NEXT: ret i32 [[B:%.*]] 39; 40 %C = select i1 false, i32 %A, i32 %B 41 ret i32 %C 42} 43 44define i32 @cond_is_true(i32 %A, i32 %B) { 45; CHECK-LABEL: @cond_is_true( 46; CHECK-NEXT: ret i32 [[A:%.*]] 47; 48 %C = select i1 true, i32 %A, i32 %B 49 ret i32 %C 50} 51 52define i32 @equal_arms(i1 %cond, i32 %x) { 53; CHECK-LABEL: @equal_arms( 54; CHECK-NEXT: ret i32 [[X:%.*]] 55; 56 %V = select i1 %cond, i32 %x, i32 %x 57 ret i32 %V 58} 59 60define <2 x i32> @equal_arms_vec(<2 x i1> %cond, <2 x i32> %x) { 61; CHECK-LABEL: @equal_arms_vec( 62; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 63; 64 %V = select <2 x i1> %cond, <2 x i32> %x, <2 x i32> %x 65 ret <2 x i32> %V 66} 67 68define <2 x i32> @equal_arms_vec_poison(<2 x i1> %cond) { 69; CHECK-LABEL: @equal_arms_vec_poison( 70; CHECK-NEXT: ret <2 x i32> splat (i32 42) 71; 72 %V = select <2 x i1> %cond, <2 x i32> <i32 42, i32 poison>, <2 x i32> <i32 poison, i32 42> 73 ret <2 x i32> %V 74} 75 76define <3 x float> @equal_arms_vec_less_poison(<3 x i1> %cond) { 77; CHECK-LABEL: @equal_arms_vec_less_poison( 78; CHECK-NEXT: ret <3 x float> <float 4.200000e+01, float 4.200000e+01, float 4.300000e+01> 79; 80 %V = select <3 x i1> %cond, <3 x float> <float 42.0, float poison, float 43.0>, <3 x float> <float 42.0, float 42.0, float 43.0> 81 ret <3 x float> %V 82} 83 84define <3 x float> @equal_arms_vec_more_poison(<3 x i1> %cond) { 85; CHECK-LABEL: @equal_arms_vec_more_poison( 86; CHECK-NEXT: ret <3 x float> <float 4.200000e+01, float poison, float 4.300000e+01> 87; 88 %V = select <3 x i1> %cond, <3 x float> <float 42.0, float poison, float poison>, <3 x float> <float poison, float poison, float 43.0> 89 ret <3 x float> %V 90} 91 92define <2 x i8> @vsel_tvec(<2 x i8> %x, <2 x i8> %y) { 93; CHECK-LABEL: @vsel_tvec( 94; CHECK-NEXT: ret <2 x i8> [[X:%.*]] 95; 96 %s = select <2 x i1><i1 true, i1 true>, <2 x i8> %x, <2 x i8> %y 97 ret <2 x i8> %s 98} 99 100define <2 x i8> @vsel_fvec(<2 x i8> %x, <2 x i8> %y) { 101; CHECK-LABEL: @vsel_fvec( 102; CHECK-NEXT: ret <2 x i8> [[Y:%.*]] 103; 104 %s = select <2 x i1><i1 false, i1 false>, <2 x i8> %x, <2 x i8> %y 105 ret <2 x i8> %s 106} 107 108define <2 x i8> @vsel_mixedvec() { 109; CHECK-LABEL: @vsel_mixedvec( 110; CHECK-NEXT: ret <2 x i8> <i8 0, i8 3> 111; 112 %s = select <2 x i1><i1 true, i1 false>, <2 x i8> <i8 0, i8 1>, <2 x i8> <i8 2, i8 3> 113 ret <2 x i8> %s 114} 115 116define <3 x i8> @vsel_poison_true_op(<3 x i8> %x, <3 x i8> %y) { 117; CHECK-LABEL: @vsel_poison_true_op( 118; CHECK-NEXT: ret <3 x i8> [[X:%.*]] 119; 120 %s = select <3 x i1><i1 1, i1 poison, i1 1>, <3 x i8> %x, <3 x i8> %y 121 ret <3 x i8> %s 122} 123 124define <3 x i4> @vsel_poison_false_op(<3 x i4> %x, <3 x i4> %y) { 125; CHECK-LABEL: @vsel_poison_false_op( 126; CHECK-NEXT: ret <3 x i4> [[Y:%.*]] 127; 128 %s = select <3 x i1><i1 0, i1 poison, i1 poison>, <3 x i4> %x, <3 x i4> %y 129 ret <3 x i4> %s 130} 131 132define i32 @test1(i32 %x) { 133; CHECK-LABEL: @test1( 134; CHECK-NEXT: ret i32 [[X:%.*]] 135; 136 %and = and i32 %x, 1 137 %cmp = icmp eq i32 %and, 0 138 %and1 = and i32 %x, -2 139 %and1.x = select i1 %cmp, i32 %and1, i32 %x 140 ret i32 %and1.x 141} 142 143define i32 @test2(i32 %x) { 144; CHECK-LABEL: @test2( 145; CHECK-NEXT: ret i32 [[X:%.*]] 146; 147 %and = and i32 %x, 1 148 %cmp = icmp ne i32 %and, 0 149 %and1 = and i32 %x, -2 150 %and1.x = select i1 %cmp, i32 %x, i32 %and1 151 ret i32 %and1.x 152} 153 154define i32 @test3(i32 %x) { 155; CHECK-LABEL: @test3( 156; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], -2 157; CHECK-NEXT: ret i32 [[AND1]] 158; 159 %and = and i32 %x, 1 160 %cmp = icmp ne i32 %and, 0 161 %and1 = and i32 %x, -2 162 %and1.x = select i1 %cmp, i32 %and1, i32 %x 163 ret i32 %and1.x 164} 165 166define i32 @test4(i32 %X) { 167; CHECK-LABEL: @test4( 168; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 169; CHECK-NEXT: ret i32 [[OR]] 170; 171 %cmp = icmp slt i32 %X, 0 172 %or = or i32 %X, -2147483648 173 %cond = select i1 %cmp, i32 %X, i32 %or 174 ret i32 %cond 175} 176 177define i32 @test4_disjoint(i32 %X) { 178; CHECK-LABEL: @test4_disjoint( 179; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 180; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X]], -2147483648 181; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[OR]] 182; CHECK-NEXT: ret i32 [[COND]] 183; 184 %cmp = icmp slt i32 %X, 0 185 %or = or disjoint i32 %X, -2147483648 186 %cond = select i1 %cmp, i32 %X, i32 %or 187 ret i32 %cond 188} 189 190; Same as above, but the compare isn't canonical 191define i32 @test4noncanon(i32 %X) { 192; CHECK-LABEL: @test4noncanon( 193; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 194; CHECK-NEXT: ret i32 [[OR]] 195; 196 %cmp = icmp sle i32 %X, -1 197 %or = or i32 %X, -2147483648 198 %cond = select i1 %cmp, i32 %X, i32 %or 199 ret i32 %cond 200} 201 202define i32 @test5(i32 %X) { 203; CHECK-LABEL: @test5( 204; CHECK-NEXT: ret i32 [[X:%.*]] 205; 206 %cmp = icmp slt i32 %X, 0 207 %or = or i32 %X, -2147483648 208 %cond = select i1 %cmp, i32 %or, i32 %X 209 ret i32 %cond 210} 211 212define i32 @test5_disjoint(i32 %X) { 213; CHECK-LABEL: @test5_disjoint( 214; CHECK-NEXT: ret i32 [[X:%.*]] 215; 216 %cmp = icmp slt i32 %X, 0 217 %or = or disjoint i32 %X, -2147483648 218 %cond = select i1 %cmp, i32 %or, i32 %X 219 ret i32 %cond 220} 221 222define i32 @test6(i32 %X) { 223; CHECK-LABEL: @test6( 224; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2147483647 225; CHECK-NEXT: ret i32 [[AND]] 226; 227 %cmp = icmp slt i32 %X, 0 228 %and = and i32 %X, 2147483647 229 %cond = select i1 %cmp, i32 %and, i32 %X 230 ret i32 %cond 231} 232 233define i32 @test7(i32 %X) { 234; CHECK-LABEL: @test7( 235; CHECK-NEXT: ret i32 [[X:%.*]] 236; 237 %cmp = icmp slt i32 %X, 0 238 %and = and i32 %X, 2147483647 239 %cond = select i1 %cmp, i32 %X, i32 %and 240 ret i32 %cond 241} 242 243define i32 @test8(i32 %X) { 244; CHECK-LABEL: @test8( 245; CHECK-NEXT: ret i32 [[X:%.*]] 246; 247 %cmp = icmp sgt i32 %X, -1 248 %or = or i32 %X, -2147483648 249 %cond = select i1 %cmp, i32 %X, i32 %or 250 ret i32 %cond 251} 252 253define i32 @test8_disjoint(i32 %X) { 254; CHECK-LABEL: @test8_disjoint( 255; CHECK-NEXT: ret i32 [[X:%.*]] 256; 257 %cmp = icmp sgt i32 %X, -1 258 %or = or disjoint i32 %X, -2147483648 259 %cond = select i1 %cmp, i32 %X, i32 %or 260 ret i32 %cond 261} 262 263define i32 @test9(i32 %X) { 264; CHECK-LABEL: @test9( 265; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 266; CHECK-NEXT: ret i32 [[OR]] 267; 268 %cmp = icmp sgt i32 %X, -1 269 %or = or i32 %X, -2147483648 270 %cond = select i1 %cmp, i32 %or, i32 %X 271 ret i32 %cond 272} 273 274define i32 @test9_disjoint(i32 %X) { 275; CHECK-LABEL: @test9_disjoint( 276; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 277; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[X]], -2147483648 278; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[X]] 279; CHECK-NEXT: ret i32 [[COND]] 280; 281 %cmp = icmp sgt i32 %X, -1 282 %or = or disjoint i32 %X, -2147483648 283 %cond = select i1 %cmp, i32 %or, i32 %X 284 ret i32 %cond 285} 286 287; Same as above, but the compare isn't canonical 288define i32 @test9noncanon(i32 %X) { 289; CHECK-LABEL: @test9noncanon( 290; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 291; CHECK-NEXT: ret i32 [[OR]] 292; 293 %cmp = icmp sge i32 %X, 0 294 %or = or i32 %X, -2147483648 295 %cond = select i1 %cmp, i32 %or, i32 %X 296 ret i32 %cond 297} 298 299define i32 @test10(i32 %X) { 300; CHECK-LABEL: @test10( 301; CHECK-NEXT: ret i32 [[X:%.*]] 302; 303 %cmp = icmp sgt i32 %X, -1 304 %and = and i32 %X, 2147483647 305 %cond = select i1 %cmp, i32 %and, i32 %X 306 ret i32 %cond 307} 308 309define i32 @test11(i32 %X) { 310; CHECK-LABEL: @test11( 311; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2147483647 312; CHECK-NEXT: ret i32 [[AND]] 313; 314 %cmp = icmp sgt i32 %X, -1 315 %and = and i32 %X, 2147483647 316 %cond = select i1 %cmp, i32 %X, i32 %and 317 ret i32 %cond 318} 319 320define <2 x i8> @test11vec(<2 x i8> %X) { 321; CHECK-LABEL: @test11vec( 322; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 127) 323; CHECK-NEXT: ret <2 x i8> [[AND]] 324; 325 %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1> 326 %and = and <2 x i8> %X, <i8 127, i8 127> 327 %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and 328 ret <2 x i8> %sel 329} 330 331define i32 @test12(i32 %X) { 332; CHECK-LABEL: @test12( 333; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 334; CHECK-NEXT: ret i32 [[AND]] 335; 336 %cmp = icmp ult i32 %X, 4 337 %and = and i32 %X, 3 338 %cond = select i1 %cmp, i32 %X, i32 %and 339 ret i32 %cond 340} 341 342; Same as above, but the compare isn't canonical 343define i32 @test12noncanon(i32 %X) { 344; CHECK-LABEL: @test12noncanon( 345; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 346; CHECK-NEXT: ret i32 [[AND]] 347; 348 %cmp = icmp ule i32 %X, 3 349 %and = and i32 %X, 3 350 %cond = select i1 %cmp, i32 %X, i32 %and 351 ret i32 %cond 352} 353 354define i32 @test13(i32 %X) { 355; CHECK-LABEL: @test13( 356; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 357; CHECK-NEXT: ret i32 [[AND]] 358; 359 %cmp = icmp ugt i32 %X, 3 360 %and = and i32 %X, 3 361 %cond = select i1 %cmp, i32 %and, i32 %X 362 ret i32 %cond 363} 364 365; Same as above, but the compare isn't canonical 366define i32 @test13noncanon(i32 %X) { 367; CHECK-LABEL: @test13noncanon( 368; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 369; CHECK-NEXT: ret i32 [[AND]] 370; 371 %cmp = icmp uge i32 %X, 4 372 %and = and i32 %X, 3 373 %cond = select i1 %cmp, i32 %and, i32 %X 374 ret i32 %cond 375} 376 377define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) { 378; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8( 379; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 8 380; CHECK-NEXT: ret i32 [[OR]] 381; 382 %and = and i32 %x, 8 383 %cmp = icmp eq i32 %and, 0 384 %or = or i32 %x, 8 385 %sel = select i1 %cmp, i32 %or, i32 %x 386 ret i32 %sel 387} 388 389define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) { 390; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt( 391; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 8 392; CHECK-NEXT: ret i32 [[OR]] 393; 394 %and = and i32 %x, 8 395 %cmp = icmp ne i32 %and, 0 396 %or = or i32 %x, 8 397 %sel = select i1 %cmp, i32 %x, i32 %or 398 ret i32 %sel 399} 400 401define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) { 402; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8( 403; CHECK-NEXT: ret i32 [[X:%.*]] 404; 405 %and = and i32 %x, 8 406 %cmp = icmp ne i32 %and, 0 407 %or = or i32 %x, 8 408 %sel = select i1 %cmp, i32 %or, i32 %x 409 ret i32 %sel 410} 411 412define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) { 413; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt( 414; CHECK-NEXT: ret i32 [[X:%.*]] 415; 416 %and = and i32 %x, 8 417 %cmp = icmp eq i32 %and, 0 418 %or = or i32 %x, 8 419 %sel = select i1 %cmp, i32 %x, i32 %or 420 ret i32 %sel 421} 422 423define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) { 424; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8( 425; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], -9 426; CHECK-NEXT: ret i32 [[AND1]] 427; 428 %and = and i32 %x, 8 429 %cmp = icmp eq i32 %and, 0 430 %and1 = and i32 %x, -9 431 %sel = select i1 %cmp, i32 %x, i32 %and1 432 ret i32 %sel 433} 434 435define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) { 436; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt( 437; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], -9 438; CHECK-NEXT: ret i32 [[AND1]] 439; 440 %and = and i32 %x, 8 441 %cmp = icmp ne i32 %and, 0 442 %and1 = and i32 %x, -9 443 %sel = select i1 %cmp, i32 %and1, i32 %x 444 ret i32 %sel 445} 446 447define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) { 448; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8( 449; CHECK-NEXT: ret i32 [[X:%.*]] 450; 451 %and = and i32 %x, 8 452 %cmp = icmp ne i32 %and, 0 453 %and1 = and i32 %x, -9 454 %sel = select i1 %cmp, i32 %x, i32 %and1 455 ret i32 %sel 456} 457 458define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) { 459; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt( 460; CHECK-NEXT: ret i32 [[X:%.*]] 461; 462 %and = and i32 %x, 8 463 %cmp = icmp eq i32 %and, 0 464 %and1 = and i32 %x, -9 465 %sel = select i1 %cmp, i32 %and1, i32 %x 466 ret i32 %sel 467} 468 469; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466 470; Each of the previous 8 patterns has a variant that replaces the 471; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt. 472 473define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) { 474; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128( 475; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 128 476; CHECK-NEXT: ret i32 [[OR]] 477; 478 %trunc = trunc i32 %x to i8 479 %cmp = icmp sgt i8 %trunc, -1 480 %or = or i32 %x, 128 481 %sel = select i1 %cmp, i32 %or, i32 %x 482 ret i32 %sel 483} 484 485define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) { 486; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt( 487; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 128 488; CHECK-NEXT: ret i32 [[OR]] 489; 490 %trunc = trunc i32 %x to i8 491 %cmp = icmp slt i8 %trunc, 0 492 %or = or i32 %x, 128 493 %sel = select i1 %cmp, i32 %x, i32 %or 494 ret i32 %sel 495} 496 497define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) { 498; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128( 499; CHECK-NEXT: ret i32 [[X:%.*]] 500; 501 %trunc = trunc i32 %x to i8 502 %cmp = icmp slt i8 %trunc, 0 503 %or = or i32 %x, 128 504 %sel = select i1 %cmp, i32 %or, i32 %x 505 ret i32 %sel 506} 507 508define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) { 509; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt( 510; CHECK-NEXT: ret i32 [[X:%.*]] 511; 512 %trunc = trunc i32 %x to i8 513 %cmp = icmp sgt i8 %trunc, -1 514 %or = or i32 %x, 128 515 %sel = select i1 %cmp, i32 %x, i32 %or 516 ret i32 %sel 517} 518 519define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) { 520; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8( 521; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], -9 522; CHECK-NEXT: ret i32 [[AND]] 523; 524 %trunc = trunc i32 %x to i4 525 %cmp = icmp sgt i4 %trunc, -1 526 %and = and i32 %x, -9 527 %sel = select i1 %cmp, i32 %x, i32 %and 528 ret i32 %sel 529} 530 531define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) { 532; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt( 533; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], -9 534; CHECK-NEXT: ret i32 [[AND]] 535; 536 %trunc = trunc i32 %x to i4 537 %cmp = icmp slt i4 %trunc, 0 538 %and = and i32 %x, -9 539 %sel = select i1 %cmp, i32 %and, i32 %x 540 ret i32 %sel 541} 542 543define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) { 544; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8( 545; CHECK-NEXT: ret i32 [[X:%.*]] 546; 547 %trunc = trunc i32 %x to i4 548 %cmp = icmp slt i4 %trunc, 0 549 %and = and i32 %x, -9 550 %sel = select i1 %cmp, i32 %x, i32 %and 551 ret i32 %sel 552} 553 554define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) { 555; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt( 556; CHECK-NEXT: ret i32 [[X:%.*]] 557; 558 %trunc = trunc i32 %x to i4 559 %cmp = icmp sgt i4 %trunc, -1 560 %and = and i32 %x, -9 561 %sel = select i1 %cmp, i32 %and, i32 %x 562 ret i32 %sel 563} 564 565; Make sure that at least a few of the same patterns are repeated with vector types. 566 567define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) { 568; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec( 569; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 570; 571 %and = and <2 x i32> %x, <i32 8, i32 8> 572 %cmp = icmp ne <2 x i32> %and, zeroinitializer 573 %and1 = and <2 x i32> %x, <i32 -9, i32 -9> 574 %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1 575 ret <2 x i32> %sel 576} 577 578define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) { 579; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec( 580; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 581; 582 %trunc = trunc <2 x i32> %x to <2 x i4> 583 %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1> 584 %and = and <2 x i32> %x, <i32 -9, i32 -9> 585 %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x 586 ret <2 x i32> %sel 587} 588 589; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify? 590 591define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) { 592; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8( 593; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8 594; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 595; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -9 596; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND1]] 597; CHECK-NEXT: ret i32 [[Y_AND1]] 598; 599 %and = and i32 %x, 8 600 %cmp = icmp eq i32 %and, 0 601 %and1 = and i32 %y, -9 602 %y.and1 = select i1 %cmp, i32 %y, i32 %and1 603 ret i32 %y.and1 604} 605 606define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) { 607; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8( 608; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8 609; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 610; CHECK-NEXT: [[AND1:%.*]] = and i64 [[Y:%.*]], -9 611; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i64 [[Y]], i64 [[AND1]] 612; CHECK-NEXT: ret i64 [[Y_AND1]] 613; 614 %and = and i32 %x, 8 615 %cmp = icmp eq i32 %and, 0 616 %and1 = and i64 %y, -9 617 %y.and1 = select i1 %cmp, i64 %y, i64 %and1 618 ret i64 %y.and1 619} 620 621define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) { 622; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8( 623; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8 624; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 625; CHECK-NEXT: [[AND1:%.*]] = and i64 [[Y:%.*]], -9 626; CHECK-NEXT: [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 [[Y]] 627; CHECK-NEXT: ret i64 [[AND1_Y]] 628; 629 %and = and i32 %x, 8 630 %cmp = icmp eq i32 %and, 0 631 %and1 = and i64 %y, -9 632 %and1.y = select i1 %cmp, i64 %and1, i64 %y 633 ret i64 %and1.y 634} 635 636; Don't crash on a pointer or aggregate type. 637 638define ptr @select_icmp_pointers(ptr %x, ptr %y) { 639; CHECK-LABEL: @select_icmp_pointers( 640; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr [[X:%.*]], null 641; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], ptr [[X]], ptr [[Y:%.*]] 642; CHECK-NEXT: ret ptr [[SEL]] 643; 644 %cmp = icmp slt ptr %x, null 645 %sel = select i1 %cmp, ptr %x, ptr %y 646 ret ptr %sel 647} 648 649; If the condition is known, we don't need to select, but we're not 650; doing this fold here to avoid compile-time cost. 651 652declare void @llvm.assume(i1) 653 654define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 655; CHECK-LABEL: @assume_sel_cond( 656; CHECK-NEXT: call void @llvm.assume(i1 [[COND:%.*]]) 657; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 [[X:%.*]], i8 [[Y:%.*]] 658; CHECK-NEXT: ret i8 [[SEL]] 659; 660 call void @llvm.assume(i1 %cond) 661 %sel = select i1 %cond, i8 %x, i8 %y 662 ret i8 %sel 663} 664 665define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 666; CHECK-LABEL: @do_not_assume_sel_cond( 667; CHECK-NEXT: [[NOTCOND:%.*]] = icmp eq i1 [[COND:%.*]], false 668; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) 669; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 [[X:%.*]], i8 [[Y:%.*]] 670; CHECK-NEXT: ret i8 [[SEL]] 671; 672 %notcond = icmp eq i1 %cond, false 673 call void @llvm.assume(i1 %notcond) 674 %sel = select i1 %cond, i8 %x, i8 %y 675 ret i8 %sel 676} 677 678define ptr @select_icmp_eq_0_gep_operand(ptr %base, i64 %n) { 679; CHECK-LABEL: @select_icmp_eq_0_gep_operand( 680; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 [[N:%.*]] 681; CHECK-NEXT: ret ptr [[GEP]] 682; 683 %cond = icmp eq i64 %n, 0 684 %gep = getelementptr i32, ptr %base, i64 %n 685 %r = select i1 %cond, ptr %base, ptr %gep 686 ret ptr %r 687} 688 689define ptr @select_icmp_ne_0_gep_operand(ptr %base, i64 %n) { 690; CHECK-LABEL: @select_icmp_ne_0_gep_operand( 691; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 [[N:%.*]] 692; CHECK-NEXT: ret ptr [[GEP]] 693; 694 %cond = icmp ne i64 %n, 0 695 %gep = getelementptr i32, ptr %base, i64 %n 696 %r = select i1 %cond, ptr %gep, ptr %base 697 ret ptr %r 698} 699 700define i1 @and_cmps(i32 %x) { 701; CHECK-LABEL: @and_cmps( 702; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92 703; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[X]], 11 704; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false 705; CHECK-NEXT: ret i1 [[R]] 706; 707 %cmp1 = icmp slt i32 %x, 92 708 %cmp2 = icmp slt i32 %x, 11 709 %r = select i1 %cmp1, i1 %cmp2, i1 false 710 ret i1 %r 711} 712 713define <2 x i1> @and_cmps_vector(<2 x i32> %x) { 714; CHECK-LABEL: @and_cmps_vector( 715; CHECK-NEXT: [[CMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], splat (i32 92) 716; CHECK-NEXT: [[CMP2:%.*]] = icmp slt <2 x i32> [[X]], splat (i32 11) 717; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[CMP1]], <2 x i1> [[CMP2]], <2 x i1> zeroinitializer 718; CHECK-NEXT: ret <2 x i1> [[R]] 719; 720 %cmp1 = icmp slt <2 x i32> %x, <i32 92, i32 92> 721 %cmp2 = icmp slt <2 x i32> %x, <i32 11, i32 11> 722 %r = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> <i1 false, i1 false> 723 ret <2 x i1> %r 724} 725 726define i1 @or_cmps(float %x) { 727; CHECK-LABEL: @or_cmps( 728; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno float [[X:%.*]], 4.200000e+01 729; CHECK-NEXT: [[CMP2:%.*]] = fcmp uno float [[X]], 5.200000e+01 730; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]] 731; CHECK-NEXT: ret i1 [[R]] 732; 733 %cmp1 = fcmp uno float %x, 42.0 734 %cmp2 = fcmp uno float %x, 52.0 735 %r = select i1 %cmp1, i1 true, i1 %cmp2 736 ret i1 %r 737} 738 739define <2 x i1> @or_logic_vector(<2 x i1> %x, <2 x i1> %y) { 740; CHECK-LABEL: @or_logic_vector( 741; CHECK-NEXT: ret <2 x i1> [[X:%.*]] 742; 743 %a = and <2 x i1> %x, %y 744 %r = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %a 745 ret <2 x i1> %r 746} 747 748define i1 @and_not_cmps(i32 %x) { 749; CHECK-LABEL: @and_not_cmps( 750; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92 751; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[X]], 11 752; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]] 753; CHECK-NEXT: ret i1 [[R]] 754; 755 %cmp1 = icmp slt i32 %x, 92 756 %cmp2 = icmp slt i32 %x, 11 757 %r = select i1 %cmp1, i1 false, i1 %cmp2 758 ret i1 %r 759} 760 761define i1 @or_not_cmps(i32 %x) { 762; CHECK-LABEL: @or_not_cmps( 763; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92 764; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[X]], 11 765; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true 766; CHECK-NEXT: ret i1 [[R]] 767; 768 %cmp1 = icmp slt i32 %x, 92 769 %cmp2 = icmp slt i32 %x, 11 770 %r = select i1 %cmp1, i1 %cmp2, i1 true 771 ret i1 %r 772} 773 774define i8 @and_cmps_wrong_type(i32 %x) { 775; CHECK-LABEL: @and_cmps_wrong_type( 776; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 92 777; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[X]], 11 778; CHECK-NEXT: [[S:%.*]] = sext i1 [[CMP2]] to i8 779; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i8 [[S]], i8 0 780; CHECK-NEXT: ret i8 [[R]] 781; 782 %cmp1 = icmp slt i32 %x, 92 783 %cmp2 = icmp slt i32 %x, 11 784 %s = sext i1 %cmp2 to i8 785 %r = select i1 %cmp1, i8 %s, i8 0 786 ret i8 %r 787} 788 789define i1 @y_might_be_poison(float %x, float %y) { 790; CHECK-LABEL: @y_might_be_poison( 791; CHECK-NEXT: [[C1:%.*]] = fcmp ord float 0.000000e+00, [[X:%.*]] 792; CHECK-NEXT: [[C2:%.*]] = fcmp ord float [[X]], [[Y:%.*]] 793; CHECK-NEXT: [[C3:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false 794; CHECK-NEXT: ret i1 [[C3]] 795; 796 %c1 = fcmp ord float 0.0, %x 797 %c2 = fcmp ord float %x, %y 798 %c3 = select i1 %c1, i1 %c2, i1 false 799 ret i1 %c3 800} 801 802; Negative tests to ensure we don't remove selects with undef true/false values. 803; See https://bugs.llvm.org/show_bug.cgi?id=31633 804; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html 805; https://reviews.llvm.org/D83360 806define i32 @false_undef(i1 %cond, i32 %x) { 807; CHECK-LABEL: @false_undef( 808; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef 809; CHECK-NEXT: ret i32 [[S]] 810; 811 %s = select i1 %cond, i32 %x, i32 undef 812 ret i32 %s 813} 814 815define i32 @true_undef(i1 %cond, i32 %x) { 816; CHECK-LABEL: @true_undef( 817; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]] 818; CHECK-NEXT: ret i32 [[S]] 819; 820 %s = select i1 %cond, i32 undef, i32 %x 821 ret i32 %s 822} 823 824define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) { 825; CHECK-LABEL: @false_undef_vec( 826; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef 827; CHECK-NEXT: ret <2 x i32> [[S]] 828; 829 %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef 830 ret <2 x i32> %s 831} 832 833define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) { 834; CHECK-LABEL: @true_undef_vec( 835; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]] 836; CHECK-NEXT: ret <2 x i32> [[S]] 837; 838 %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x 839 ret <2 x i32> %s 840} 841 842; These can be folded because the other value is guaranteed not to be poison. 843define i32 @false_undef_true_constant(i1 %cond) { 844; CHECK-LABEL: @false_undef_true_constant( 845; CHECK-NEXT: ret i32 10 846; 847 %s = select i1 %cond, i32 10, i32 undef 848 ret i32 %s 849} 850 851define i32 @true_undef_false_constant(i1 %cond) { 852; CHECK-LABEL: @true_undef_false_constant( 853; CHECK-NEXT: ret i32 20 854; 855 %s = select i1 %cond, i32 undef, i32 20 856 ret i32 %s 857} 858 859define <2 x i32> @false_undef_true_constant_vec(i1 %cond) { 860; CHECK-LABEL: @false_undef_true_constant_vec( 861; CHECK-NEXT: ret <2 x i32> <i32 42, i32 -42> 862; 863 %s = select i1 %cond, <2 x i32> <i32 42, i32 -42>, <2 x i32> undef 864 ret <2 x i32> %s 865} 866 867define <2 x i32> @true_undef_false_constant_vec(i1 %cond) { 868; CHECK-LABEL: @true_undef_false_constant_vec( 869; CHECK-NEXT: ret <2 x i32> <i32 -42, i32 42> 870; 871 %s = select i1 %cond, <2 x i32> undef, <2 x i32> <i32 -42, i32 42> 872 ret <2 x i32> %s 873} 874 875; If one input is undef and the other is freeze, we can fold it to the freeze. 876define i32 @false_undef_true_freeze(i1 %cond, i32 %x) { 877; CHECK-LABEL: @false_undef_true_freeze( 878; CHECK-NEXT: [[XF:%.*]] = freeze i32 [[X:%.*]] 879; CHECK-NEXT: ret i32 [[XF]] 880; 881 %xf = freeze i32 %x 882 %s = select i1 %cond, i32 %xf, i32 undef 883 ret i32 %s 884} 885 886define i32 @false_undef_false_freeze(i1 %cond, i32 %x) { 887; CHECK-LABEL: @false_undef_false_freeze( 888; CHECK-NEXT: [[XF:%.*]] = freeze i32 [[X:%.*]] 889; CHECK-NEXT: ret i32 [[XF]] 890; 891 %xf = freeze i32 %x 892 %s = select i1 %cond, i32 undef, i32 %xf 893 ret i32 %s 894} 895 896@g = external global i32, align 1 897 898define <2 x i32> @false_undef_true_constextpr_vec(i1 %cond) { 899; CHECK-LABEL: @false_undef_true_constextpr_vec( 900; CHECK-NEXT: ret <2 x i32> <i32 ptrtoint (ptr @g to i32), i32 ptrtoint (ptr @g to i32)> 901; 902 %s = select i1 %cond, <2 x i32> <i32 undef, i32 ptrtoint (ptr @g to i32)>, <2 x i32> <i32 ptrtoint (ptr @g to i32), i32 undef> 903 ret <2 x i32> %s 904} 905 906define i32 @all_constant_true_undef() { 907; CHECK-LABEL: @all_constant_true_undef( 908; CHECK-NEXT: ret i32 1 909; 910 %s = select i1 ptrtoint (ptr @all_constant_true_undef to i1), i32 undef, i32 1 911 ret i32 %s 912} 913 914define float @all_constant_false_undef() { 915; CHECK-LABEL: @all_constant_false_undef( 916; CHECK-NEXT: ret float 1.000000e+00 917; 918 %s = select i1 ptrtoint (ptr @all_constant_false_undef to i1), float undef, float 1.0 919 ret float %s 920} 921 922define <2 x i32> @all_constant_true_undef_vec() { 923; CHECK-LABEL: @all_constant_true_undef_vec( 924; CHECK-NEXT: ret <2 x i32> <i32 1, i32 -1> 925; 926 %s = select i1 ptrtoint (ptr @all_constant_true_undef_vec to i1), <2 x i32> undef, <2 x i32> <i32 1, i32 -1> 927 ret <2 x i32> %s 928} 929 930define <2 x float> @all_constant_false_undef_vec() { 931; CHECK-LABEL: @all_constant_false_undef_vec( 932; CHECK-NEXT: ret <2 x float> <float 1.000000e+00, float -1.000000e+00> 933; 934 %s = select i1 ptrtoint (ptr @all_constant_false_undef_vec to i1), <2 x float> undef, <2 x float> <float 1.0, float -1.0> 935 ret <2 x float> %s 936} 937 938; Negative tests. Don't fold if the non-undef operand is a constexpr. 939define i32 @all_constant_false_undef_true_constexpr() { 940; CHECK-LABEL: @all_constant_false_undef_true_constexpr( 941; CHECK-NEXT: ret i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32) 942; 943 %s = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i1), i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32), i32 undef 944 ret i32 %s 945} 946 947define i32 @all_constant_true_undef_false_constexpr() { 948; CHECK-LABEL: @all_constant_true_undef_false_constexpr( 949; CHECK-NEXT: ret i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) 950; 951 %s = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i1), i32 undef, i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) 952 ret i32 %s 953} 954 955; Negative tests. Don't fold if the non-undef operand is a vector containing a constexpr. 956define <2 x i32> @all_constant_false_undef_true_constexpr_vec() { 957; CHECK-LABEL: @all_constant_false_undef_true_constexpr_vec( 958; CHECK-NEXT: ret <2 x i32> <i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr_vec to i32), i32 -1> 959; 960 %s = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr_vec to i1), <2 x i32> <i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr_vec to i32), i32 -1>, <2 x i32> undef 961 ret <2 x i32> %s 962} 963 964define <2 x i32> @all_constant_true_undef_false_constexpr_vec() { 965; CHECK-LABEL: @all_constant_true_undef_false_constexpr_vec( 966; CHECK-NEXT: ret <2 x i32> <i32 -1, i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr_vec to i32)> 967; 968 %s = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr_vec to i1), <2 x i32> undef, <2 x i32><i32 -1, i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr_vec to i32)> 969 ret <2 x i32> %s 970} 971 972define i1 @expand_binop_undef(i32 %x, i32 %y) { 973; CHECK-LABEL: @expand_binop_undef( 974; CHECK-NEXT: [[CMP15:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 975; CHECK-NEXT: ret i1 [[CMP15]] 976; 977 %cmp9.not.1 = icmp eq i32 %x, %y 978 %cmp15 = icmp slt i32 %x, %y 979 %spec.select39 = select i1 %cmp9.not.1, i1 undef, i1 %cmp15 980 %spec.select40 = xor i1 %cmp9.not.1, 1 981 %spec.select = and i1 %spec.select39, %spec.select40 982 ret i1 %spec.select 983} 984 985define i32 @pr47322_more_poisonous_replacement(i32 %arg) { 986; CHECK-LABEL: @pr47322_more_poisonous_replacement( 987; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0 988; CHECK-NEXT: [[TRAILING:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 true) 989; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[ARG]], [[TRAILING]] 990; CHECK-NEXT: [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]] 991; CHECK-NEXT: ret i32 [[R1_SROA_0_1]] 992; 993 %cmp = icmp eq i32 %arg, 0 994 %trailing = call i32 @llvm.cttz.i32(i32 %arg, i1 true) 995 %shifted = lshr i32 %arg, %trailing 996 %r1.sroa.0.1 = select i1 %cmp, i32 0, i32 %shifted 997 ret i32 %r1.sroa.0.1 998} 999declare i32 @llvm.cttz.i32(i32, i1 immarg) 1000 1001; Partial undef scalable vectors should be ignored. 1002define <vscale x 2 x i1> @ignore_scalable_undef(<vscale x 2 x i1> %cond) { 1003; CHECK-LABEL: @ignore_scalable_undef( 1004; CHECK-NEXT: ret <vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0) 1005; 1006 %vec = insertelement <vscale x 2 x i1> undef, i1 true, i32 0 1007 %s = select <vscale x 2 x i1> %cond, <vscale x 2 x i1> undef, <vscale x 2 x i1> %vec 1008 ret <vscale x 2 x i1> %s 1009} 1010 1011define i32 @select_neutral_add_rhs(i32 %x, i32 %y) { 1012; CHECK-LABEL: @select_neutral_add_rhs( 1013; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], [[Y:%.*]] 1014; CHECK-NEXT: ret i32 [[ADD]] 1015; 1016 %cmp = icmp ne i32 %y, 0 1017 %add = add i32 %x, %y 1018 %sel = select i1 %cmp, i32 %add, i32 %x 1019 ret i32 %sel 1020} 1021 1022define i32 @select_neutral_add_lhs(i32 %x, i32 %y) { 1023; CHECK-LABEL: @select_neutral_add_lhs( 1024; CHECK-NEXT: [[ADD:%.*]] = add i32 [[Y:%.*]], [[X:%.*]] 1025; CHECK-NEXT: ret i32 [[ADD]] 1026; 1027 %cmp = icmp ne i32 %y, 0 1028 %add = add i32 %y, %x 1029 %sel = select i1 %cmp, i32 %add, i32 %x 1030 ret i32 %sel 1031} 1032 1033define <2 x i32> @select_neutral_add_rhs_vec(<2 x i32> %x, <2 x i32> %y) { 1034; CHECK-LABEL: @select_neutral_add_rhs_vec( 1035; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[X:%.*]], [[Y:%.*]] 1036; CHECK-NEXT: ret <2 x i32> [[ADD]] 1037; 1038 %cmp = icmp ne <2 x i32> %y, zeroinitializer 1039 %add = add <2 x i32> %x, %y 1040 %sel = select <2 x i1> %cmp, <2 x i32> %add, <2 x i32> %x 1041 ret <2 x i32> %sel 1042} 1043 1044define <2 x i32> @select_neutral_add_lhs_vec(<2 x i32> %x, <2 x i32> %y) { 1045; CHECK-LABEL: @select_neutral_add_lhs_vec( 1046; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[Y:%.*]], [[X:%.*]] 1047; CHECK-NEXT: ret <2 x i32> [[ADD]] 1048; 1049 %cmp = icmp ne <2 x i32> %y, zeroinitializer 1050 %add = add <2 x i32> %y, %x 1051 %sel = select <2 x i1> %cmp, <2 x i32> %add, <2 x i32> %x 1052 ret <2 x i32> %sel 1053} 1054 1055define i32 @select_neutral_sub_rhs(i32 %x, i32 %y) { 1056; CHECK-LABEL: @select_neutral_sub_rhs( 1057; CHECK-NEXT: [[ADD:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 1058; CHECK-NEXT: ret i32 [[ADD]] 1059; 1060 %cmp = icmp ne i32 %y, 0 1061 %add = sub i32 %x, %y 1062 %sel = select i1 %cmp, i32 %add, i32 %x 1063 ret i32 %sel 1064} 1065 1066define i32 @select_neutral_sub_lhs(i32 %x, i32 %y) { 1067; CHECK-LABEL: @select_neutral_sub_lhs( 1068; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[Y:%.*]], 0 1069; CHECK-NEXT: [[ADD:%.*]] = sub i32 [[Y]], [[X:%.*]] 1070; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 [[X]] 1071; CHECK-NEXT: ret i32 [[SEL]] 1072; 1073 %cmp = icmp ne i32 %y, 0 1074 %add = sub i32 %y, %x 1075 %sel = select i1 %cmp, i32 %add, i32 %x 1076 ret i32 %sel 1077} 1078 1079define i32 @select_ctpop_zero(i32 %x) { 1080; CHECK-LABEL: @select_ctpop_zero( 1081; CHECK-NEXT: [[T1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]) 1082; CHECK-NEXT: ret i32 [[T1]] 1083; 1084 %t0 = icmp eq i32 %x, 0 1085 %t1 = call i32 @llvm.ctpop.i32(i32 %x) 1086 %sel = select i1 %t0, i32 0, i32 %t1 1087 ret i32 %sel 1088} 1089 1090define <2 x i32> @select_ctpop_zero_vec(<2 x i32> %x) { 1091; CHECK-LABEL: @select_ctpop_zero_vec( 1092; CHECK-NEXT: [[T1:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]]) 1093; CHECK-NEXT: ret <2 x i32> [[T1]] 1094; 1095 %t0 = icmp eq <2 x i32> %x, zeroinitializer 1096 %t1 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %x) 1097 %sel = select <2 x i1> %t0, <2 x i32> zeroinitializer, <2 x i32> %t1 1098 ret <2 x i32> %sel 1099} 1100 1101; Negative test: Cannot fold due to cross-lane intrinsic. 1102define <2 x i32> @select_vector_reverse(<2 x i32> %x) { 1103; CHECK-LABEL: @select_vector_reverse( 1104; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer 1105; CHECK-NEXT: [[REV:%.*]] = call <2 x i32> @llvm.vector.reverse.v2i32(<2 x i32> [[X]]) 1106; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i32> zeroinitializer, <2 x i32> [[REV]] 1107; CHECK-NEXT: ret <2 x i32> [[SEL]] 1108; 1109 %cmp = icmp eq <2 x i32> %x, zeroinitializer 1110 %rev = call <2 x i32> @llvm.vector.reverse.v2i32(<2 x i32> %x) 1111 %sel = select <2 x i1> %cmp, <2 x i32> zeroinitializer, <2 x i32> %rev 1112 ret <2 x i32> %sel 1113} 1114 1115declare i32 @llvm.ctpop.i32(i32) 1116declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>) 1117declare <2 x i32> @llvm.vector.reverse.v2i32(<2 x i32>) 1118 1119define <2 x i32> @vec_select_no_equivalence(<2 x i32> %x, <2 x i32> %y) { 1120; CHECK-LABEL: @vec_select_no_equivalence( 1121; CHECK-NEXT: [[X10:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> undef, <2 x i32> <i32 1, i32 0> 1122; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer 1123; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[X10]], <2 x i32> zeroinitializer 1124; CHECK-NEXT: ret <2 x i32> [[S]] 1125; 1126 %x10 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 0> 1127 %cond = icmp eq <2 x i32> %x, zeroinitializer 1128 %s = select <2 x i1> %cond, <2 x i32> %x10, <2 x i32> zeroinitializer 1129 ret <2 x i32> %s 1130} 1131 1132define i8 @select_eq_xor_recursive(i8 %a, i8 %b) { 1133; CHECK-LABEL: @select_eq_xor_recursive( 1134; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A:%.*]], [[B:%.*]] 1135; CHECK-NEXT: [[INV:%.*]] = xor i8 [[XOR]], -1 1136; CHECK-NEXT: ret i8 [[INV]] 1137; 1138 %xor = xor i8 %a, %b 1139 %inv = xor i8 %xor, -1 1140 %cmp = icmp eq i8 %a, %b 1141 %sel = select i1 %cmp, i8 -1, i8 %inv 1142 ret i8 %sel 1143} 1144 1145define i8 @select_eq_xor_recursive2(i8 %a, i8 %b) { 1146; CHECK-LABEL: @select_eq_xor_recursive2( 1147; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A:%.*]], [[B:%.*]] 1148; CHECK-NEXT: [[INV:%.*]] = xor i8 [[XOR]], -1 1149; CHECK-NEXT: [[ADD:%.*]] = add i8 [[INV]], 10 1150; CHECK-NEXT: ret i8 [[ADD]] 1151; 1152 %xor = xor i8 %a, %b 1153 %inv = xor i8 %xor, -1 1154 %add = add i8 %inv, 10 1155 %cmp = icmp eq i8 %a, %b 1156 %sel = select i1 %cmp, i8 9, i8 %add 1157 ret i8 %sel 1158} 1159 1160define i8 @select_eq_xor_recursive3(i8 %a, i8 %b) { 1161; CHECK-LABEL: @select_eq_xor_recursive3( 1162; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A:%.*]], [[B:%.*]] 1163; CHECK-NEXT: [[INV:%.*]] = xor i8 [[XOR]], -1 1164; CHECK-NEXT: [[ADD:%.*]] = add i8 [[INV]], 10 1165; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[ADD]], 3 1166; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[B]] 1167; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 9, i8 [[MUL]] 1168; CHECK-NEXT: ret i8 [[SEL]] 1169; 1170 %xor = xor i8 %a, %b 1171 %inv = xor i8 %xor, -1 1172 %add = add i8 %inv, 10 1173 %mul = mul i8 %add, 3 1174 %cmp = icmp eq i8 %a, %b 1175 %sel = select i1 %cmp, i8 9, i8 %mul 1176 ret i8 %sel 1177} 1178 1179; Cannot drop select, because this would propagate poison from %a. 1180define i8 @select_eq_xor_recursive_propagates_poison(i8 %a, i8 %b) { 1181; CHECK-LABEL: @select_eq_xor_recursive_propagates_poison( 1182; CHECK-NEXT: [[XOR1:%.*]] = add i8 [[A:%.*]], [[B:%.*]] 1183; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[A]], [[XOR1]] 1184; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 0 1185; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[XOR2]] 1186; CHECK-NEXT: ret i8 [[SEL]] 1187; 1188 %xor1 = add i8 %a, %b 1189 %xor2 = xor i8 %a, %xor1 1190 %cmp = icmp eq i8 %b, 0 1191 %sel = select i1 %cmp, i8 0, i8 %xor2 1192 ret i8 %sel 1193} 1194 1195define i8 @select_eq_and_recursive(i8 %a) { 1196; CHECK-LABEL: @select_eq_and_recursive( 1197; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[A:%.*]] 1198; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[A]] 1199; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], 1 1200; CHECK-NEXT: ret i8 [[ADD]] 1201; 1202 %neg = sub i8 0, %a 1203 %and = and i8 %neg, %a 1204 %add = add i8 %and, 1 1205 %cmp = icmp eq i8 %a, 0 1206 %sel = select i1 %cmp, i8 1, i8 %add 1207 ret i8 %sel 1208} 1209 1210; Cannot drop select, because this would propagate poison from %b. 1211define i8 @select_eq_and_recursive_propagates_poison(i8 %a, i8 %b) { 1212; CHECK-LABEL: @select_eq_and_recursive_propagates_poison( 1213; CHECK-NEXT: [[NEG:%.*]] = sub i8 [[B:%.*]], [[A:%.*]] 1214; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[A]] 1215; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], 1 1216; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0 1217; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 1, i8 [[ADD]] 1218; CHECK-NEXT: ret i8 [[SEL]] 1219; 1220 %neg = sub i8 %b, %a 1221 %and = and i8 %neg, %a 1222 %add = add i8 %and, 1 1223 %cmp = icmp eq i8 %a, 0 1224 %sel = select i1 %cmp, i8 1, i8 %add 1225 ret i8 %sel 1226} 1227 1228define i8 @select_eq_xor_recursive_allow_refinement(i8 %a, i8 %b) { 1229; CHECK-LABEL: @select_eq_xor_recursive_allow_refinement( 1230; CHECK-NEXT: ret i8 0 1231; 1232 %xor1 = add i8 %a, %b 1233 %xor2 = xor i8 %a, %xor1 1234 %cmp = icmp eq i8 %b, 0 1235 %sel = select i1 %cmp, i8 %xor2, i8 0 1236 ret i8 %sel 1237} 1238 1239define i8 @select_eq_mul_absorber(i8 %x, i8 noundef %y) { 1240; CHECK-LABEL: @select_eq_mul_absorber( 1241; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], -1 1242; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[ADD]], [[Y:%.*]] 1243; CHECK-NEXT: ret i8 [[MUL]] 1244; 1245 %cmp = icmp eq i8 %x, 1 1246 %add = add i8 %x, -1 1247 %mul = mul i8 %add, %y 1248 %sel = select i1 %cmp, i8 0, i8 %mul 1249 ret i8 %sel 1250} 1251 1252define i8 @select_eq_mul_not_absorber(i8 %x, i8 noundef %y) { 1253; CHECK-LABEL: @select_eq_mul_not_absorber( 1254; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0 1255; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], -1 1256; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[ADD]], [[Y:%.*]] 1257; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[MUL]] 1258; CHECK-NEXT: ret i8 [[SEL]] 1259; 1260 %cmp = icmp eq i8 %x, 0 1261 %add = add i8 %x, -1 1262 %mul = mul i8 %add, %y 1263 %sel = select i1 %cmp, i8 0, i8 %mul 1264 ret i8 %sel 1265} 1266 1267; Vector to scalar options should be treated as lane-crossing. 1268define <2 x i8> @select_eq_vector_insert_extract(<2 x i8> %a, <2 x i8> %b) { 1269; CHECK-LABEL: @select_eq_vector_insert_extract( 1270; CHECK-NEXT: [[EXTRACT0:%.*]] = extractelement <2 x i8> [[A:%.*]], i64 0 1271; CHECK-NEXT: [[EXTRACT1:%.*]] = extractelement <2 x i8> [[A]], i64 1 1272; CHECK-NEXT: [[INSERT0:%.*]] = insertelement <2 x i8> poison, i8 [[EXTRACT1]], i64 0 1273; CHECK-NEXT: [[INSERT1:%.*]] = insertelement <2 x i8> [[INSERT0]], i8 [[EXTRACT0]], i64 1 1274; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[A]], zeroinitializer 1275; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[INSERT1]], <2 x i8> zeroinitializer 1276; CHECK-NEXT: ret <2 x i8> [[SEL]] 1277; 1278 %extract0 = extractelement <2 x i8> %a, i64 0 1279 %extract1 = extractelement <2 x i8> %a, i64 1 1280 %insert0 = insertelement <2 x i8> poison, i8 %extract1, i64 0 1281 %insert1 = insertelement <2 x i8> %insert0, i8 %extract0, i64 1 1282 %cmp = icmp eq <2 x i8> %a, zeroinitializer 1283 %sel = select <2 x i1> %cmp, <2 x i8> %insert1, <2 x i8> zeroinitializer 1284 ret <2 x i8> %sel 1285} 1286 1287define i32 @poison(i32 %x, i32 %y) { 1288; CHECK-LABEL: @poison( 1289; CHECK-NEXT: ret i32 [[X:%.*]] 1290; 1291 %v = select i1 undef, i32 %x, i32 %y 1292 ret i32 %v 1293} 1294 1295define i32 @poison2(i1 %cond, i32 %x) { 1296; CHECK-LABEL: @poison2( 1297; CHECK-NEXT: ret i32 [[X:%.*]] 1298; 1299 %v = select i1 %cond, i32 poison, i32 %x 1300 ret i32 %v 1301} 1302 1303define i32 @poison3(i1 %cond, i32 %x) { 1304; CHECK-LABEL: @poison3( 1305; CHECK-NEXT: ret i32 [[X:%.*]] 1306; 1307 %v = select i1 %cond, i32 %x, i32 poison 1308 ret i32 %v 1309} 1310 1311define <2 x i32> @poison4(<2 x i1> %cond, <2 x i32> %x) { 1312; CHECK-LABEL: @poison4( 1313; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 1314; 1315 %v = select <2 x i1> %cond, <2 x i32> %x, <2 x i32> poison 1316 ret <2 x i32> %v 1317} 1318 1319; 0 is the absorber constant for 'and'. 1320; The 'select' can't block extra poison because both sides of 'and' have 'x' operand. 1321 1322define i8 @replace_false_op_eq_neg_and(i8 %x) { 1323; CHECK-LABEL: @replace_false_op_eq_neg_and( 1324; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X:%.*]] 1325; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[X]] 1326; CHECK-NEXT: ret i8 [[AND]] 1327; 1328 %eq0 = icmp eq i8 %x, 0 1329 %neg = sub i8 0, %x 1330 %and = and i8 %neg, %x 1331 %sel = select i1 %eq0, i8 0, i8 %and 1332 ret i8 %sel 1333} 1334 1335; same as above, but commute 'and' 1336 1337define i8 @replace_false_op_eq_neg_and_commute(i8 %x) { 1338; CHECK-LABEL: @replace_false_op_eq_neg_and_commute( 1339; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X:%.*]] 1340; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[NEG]] 1341; CHECK-NEXT: ret i8 [[AND]] 1342; 1343 %eq0 = icmp eq i8 %x, 0 1344 %neg = sub i8 0, %x 1345 %and = and i8 %x, %neg 1346 %sel = select i1 %eq0, i8 0, i8 %and 1347 ret i8 %sel 1348} 1349 1350; same as above, but swap 'select' 1351 1352define i8 @replace_false_op_ne_neg_and(i8 %x) { 1353; CHECK-LABEL: @replace_false_op_ne_neg_and( 1354; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X:%.*]] 1355; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[X]] 1356; CHECK-NEXT: ret i8 [[AND]] 1357; 1358 %ne0 = icmp ne i8 %x, 0 1359 %neg = sub i8 0, %x 1360 %and = and i8 %neg, %x 1361 %sel = select i1 %ne0, i8 %and, i8 0 1362 ret i8 %sel 1363} 1364 1365; same as above, but commute 'and' and swap 'select' 1366 1367define i8 @replace_false_op_ne_neg_and_commute(i8 %x) { 1368; CHECK-LABEL: @replace_false_op_ne_neg_and_commute( 1369; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X:%.*]] 1370; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[NEG]] 1371; CHECK-NEXT: ret i8 [[AND]] 1372; 1373 %ne0 = icmp ne i8 %x, 0 1374 %neg = sub i8 0, %x 1375 %and = and i8 %x, %neg 1376 %sel = select i1 %ne0, i8 %and, i8 0 1377 ret i8 %sel 1378} 1379 1380; the first binop can be anything as long as it has the common operand 1381 1382define i8 @replace_false_op_eq_dec_and(i8 %x) { 1383; CHECK-LABEL: @replace_false_op_eq_dec_and( 1384; CHECK-NEXT: [[DEC:%.*]] = add i8 [[X:%.*]], -1 1385; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[X]] 1386; CHECK-NEXT: ret i8 [[AND]] 1387; 1388 %eq0 = icmp eq i8 %x, 0 1389 %dec = add i8 %x, -1 1390 %and = and i8 %dec, %x 1391 %sel = select i1 %eq0, i8 0, i8 %and 1392 ret i8 %sel 1393} 1394 1395; mul has the same absorber constant - "0" 1396 1397define i8 @replace_false_op_eq_add_mul(i8 %x) { 1398; CHECK-LABEL: @replace_false_op_eq_add_mul( 1399; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], 42 1400; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[ADD]], [[X]] 1401; CHECK-NEXT: ret i8 [[MUL]] 1402; 1403 %eq0 = icmp eq i8 %x, 0 1404 %add = add i8 %x, 42 1405 %mul = mul i8 %add, %x 1406 %sel = select i1 %eq0, i8 0, i8 %mul 1407 ret i8 %sel 1408} 1409 1410; or has a different absorber constant = "-1" 1411 1412define i8 @replace_false_op_eq_shl_or(i8 %x) { 1413; CHECK-LABEL: @replace_false_op_eq_shl_or( 1414; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 3 1415; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], [[SHL]] 1416; CHECK-NEXT: ret i8 [[OR]] 1417; 1418 %eq0 = icmp eq i8 %x, -1 1419 %shl = shl i8 %x, 3 1420 %or = or i8 %x, %shl 1421 %sel = select i1 %eq0, i8 -1, i8 %or 1422 ret i8 %sel 1423} 1424 1425define i8 @replace_false_op_eq_shl_or_disjoint(i8 %x) { 1426; CHECK-LABEL: @replace_false_op_eq_shl_or_disjoint( 1427; CHECK-NEXT: [[EQ0:%.*]] = icmp eq i8 [[X:%.*]], -1 1428; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X]], 3 1429; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X]], [[SHL]] 1430; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ0]], i8 -1, i8 [[OR]] 1431; CHECK-NEXT: ret i8 [[SEL]] 1432; 1433 %eq0 = icmp eq i8 %x, -1 1434 %shl = shl i8 %x, 3 1435 %or = or disjoint i8 %x, %shl 1436 %sel = select i1 %eq0, i8 -1, i8 %or 1437 ret i8 %sel 1438} 1439 1440; negative test - wrong cmp predicate 1441 1442define i8 @replace_false_op_sgt_neg_and(i8 %x) { 1443; CHECK-LABEL: @replace_false_op_sgt_neg_and( 1444; CHECK-NEXT: [[EQ0:%.*]] = icmp sgt i8 [[X:%.*]], 0 1445; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X]] 1446; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[X]] 1447; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ0]], i8 0, i8 [[AND]] 1448; CHECK-NEXT: ret i8 [[SEL]] 1449; 1450 %eq0 = icmp sgt i8 %x, 0 1451 %neg = sub i8 0, %x 1452 %and = and i8 %neg, %x 1453 %sel = select i1 %eq0, i8 0, i8 %and 1454 ret i8 %sel 1455} 1456 1457; negative test - the binop must use a compare operand 1458 1459define i8 @replace_false_op_eq_shl_or_wrong_cmp_op(i8 %x, i8 %y) { 1460; CHECK-LABEL: @replace_false_op_eq_shl_or_wrong_cmp_op( 1461; CHECK-NEXT: [[EQ0:%.*]] = icmp eq i8 [[Y:%.*]], -1 1462; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 3 1463; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], [[SHL]] 1464; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ0]], i8 -1, i8 [[OR]] 1465; CHECK-NEXT: ret i8 [[SEL]] 1466; 1467 %eq0 = icmp eq i8 %y, -1 1468 %shl = shl i8 %x, 3 1469 %or = or i8 %x, %shl 1470 %sel = select i1 %eq0, i8 -1, i8 %or 1471 ret i8 %sel 1472} 1473 1474; negative test - can't have extra source of potential poison 1475 1476define i8 @replace_false_op_eq_neg_and_leak1(i8 %x, i8 %y) { 1477; CHECK-LABEL: @replace_false_op_eq_neg_and_leak1( 1478; CHECK-NEXT: [[EQ0:%.*]] = icmp eq i8 [[X:%.*]], 0 1479; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[Y:%.*]] 1480; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[X]] 1481; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ0]], i8 0, i8 [[AND]] 1482; CHECK-NEXT: ret i8 [[SEL]] 1483; 1484 %eq0 = icmp eq i8 %x, 0 1485 %neg = sub i8 0, %y 1486 %and = and i8 %neg, %x 1487 %sel = select i1 %eq0, i8 0, i8 %and 1488 ret i8 %sel 1489} 1490 1491; negative test - can't have extra source of potential poison 1492 1493define i8 @replace_false_op_eq_neg_and_leak2(i8 %x, i8 %y) { 1494; CHECK-LABEL: @replace_false_op_eq_neg_and_leak2( 1495; CHECK-NEXT: [[EQ0:%.*]] = icmp eq i8 [[X:%.*]], 0 1496; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X]] 1497; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[Y:%.*]] 1498; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ0]], i8 0, i8 [[AND]] 1499; CHECK-NEXT: ret i8 [[SEL]] 1500; 1501 %eq0 = icmp eq i8 %x, 0 1502 %neg = sub i8 0, %x 1503 %and = and i8 %neg, %y 1504 %sel = select i1 %eq0, i8 0, i8 %and 1505 ret i8 %sel 1506} 1507 1508; negative test - can't have extra source of potential poison 1509 1510define i8 @replace_false_op_eq_add_mul_leak3(i8 %x, i8 %y) { 1511; CHECK-LABEL: @replace_false_op_eq_add_mul_leak3( 1512; CHECK-NEXT: [[EQ0:%.*]] = icmp eq i8 [[X:%.*]], 0 1513; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], [[Y:%.*]] 1514; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[ADD]], [[X]] 1515; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ0]], i8 0, i8 [[MUL]] 1516; CHECK-NEXT: ret i8 [[SEL]] 1517; 1518 %eq0 = icmp eq i8 %x, 0 1519 %add = add i8 %x, %y 1520 %mul = mul i8 %add, %x 1521 %sel = select i1 %eq0, i8 0, i8 %mul 1522 ret i8 %sel 1523} 1524 1525; negative test - can't have extra source of potential poison 1526 1527define i8 @replace_false_op_eq_shl_or_leak4(i8 %x, i8 %y) { 1528; CHECK-LABEL: @replace_false_op_eq_shl_or_leak4( 1529; CHECK-NEXT: [[EQ0:%.*]] = icmp eq i8 [[X:%.*]], -1 1530; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[Y:%.*]], [[X]] 1531; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], [[SHL]] 1532; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ0]], i8 -1, i8 [[OR]] 1533; CHECK-NEXT: ret i8 [[SEL]] 1534; 1535 %eq0 = icmp eq i8 %x, -1 1536 %shl = shl i8 %y, %x 1537 %or = or i8 %x, %shl 1538 %sel = select i1 %eq0, i8 -1, i8 %or 1539 ret i8 %sel 1540} 1541 1542; negative test - wrong cmp constant 1543 1544define i8 @replace_false_op_eq42_neg_and(i8 %x) { 1545; CHECK-LABEL: @replace_false_op_eq42_neg_and( 1546; CHECK-NEXT: [[EQ42:%.*]] = icmp eq i8 [[X:%.*]], 42 1547; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X]] 1548; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[X]] 1549; CHECK-NEXT: [[SEL:%.*]] = select i1 [[EQ42]], i8 0, i8 [[AND]] 1550; CHECK-NEXT: ret i8 [[SEL]] 1551; 1552 %eq42 = icmp eq i8 %x, 42 1553 %neg = sub i8 0, %x 1554 %and = and i8 %neg, %x 1555 %sel = select i1 %eq42, i8 0, i8 %and 1556 ret i8 %sel 1557} 1558 1559define ptr @select_op_replacement_in_phi(ptr %head) { 1560; CHECK-LABEL: @select_op_replacement_in_phi( 1561; CHECK-NEXT: entry: 1562; CHECK-NEXT: br label [[LOOP:%.*]] 1563; CHECK: loop: 1564; CHECK-NEXT: [[CURRENT:%.*]] = phi ptr [ [[HEAD:%.*]], [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LATCH:%.*]] ] 1565; CHECK-NEXT: [[PREV:%.*]] = phi ptr [ null, [[ENTRY]] ], [ [[CURRENT]], [[LATCH]] ] 1566; CHECK-NEXT: [[CURRENT_NULL:%.*]] = icmp eq ptr [[CURRENT]], null 1567; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CURRENT_NULL]], ptr [[PREV]], ptr null 1568; CHECK-NEXT: br i1 [[CURRENT_NULL]], label [[EXIT:%.*]], label [[LATCH]] 1569; CHECK: latch: 1570; CHECK-NEXT: [[NEXT]] = load ptr, ptr [[CURRENT]], align 8 1571; CHECK-NEXT: br label [[LOOP]] 1572; CHECK: exit: 1573; CHECK-NEXT: ret ptr [[SEL]] 1574; 1575entry: 1576 br label %loop 1577 1578loop: 1579 %current = phi ptr [ %head, %entry ], [ %next, %latch ] 1580 %prev = phi ptr [ null, %entry ], [ %current, %latch ] 1581 %current.null = icmp eq ptr %current, null 1582 %sel = select i1 %current.null, ptr %prev, ptr null 1583 br i1 %current.null, label %exit, label %latch 1584 1585latch: 1586 %next = load ptr, ptr %current 1587 br label %loop 1588 1589exit: 1590 ret ptr %sel 1591} 1592 1593define i8 @select_sub_cmp(i8 %0, i8 %1) { 1594; CHECK-LABEL: @select_sub_cmp( 1595; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i8 [[TMP1:%.*]], [[TMP0:%.*]] 1596; CHECK-NEXT: ret i8 [[TMP3]] 1597; 1598 %3 = icmp eq i8 %1, %0 1599 %4 = sub nsw i8 %1, %0 1600 %5 = select i1 %3, i8 0, i8 %4 1601 ret i8 %5 1602} 1603 1604define <2 x i8> @select_sub_cmp_vec(<2 x i8> %0, <2 x i8> %1) { 1605; CHECK-LABEL: @select_sub_cmp_vec( 1606; CHECK-NEXT: [[TMP3:%.*]] = sub nsw <2 x i8> [[TMP1:%.*]], [[TMP0:%.*]] 1607; CHECK-NEXT: ret <2 x i8> [[TMP3]] 1608; 1609 %3 = icmp eq <2 x i8> %1, %0 1610 %4 = sub nsw <2 x i8> %1, %0 1611 %5 = select <2 x i1> %3, <2 x i8> <i8 0, i8 0>, <2 x i8> %4 1612 ret <2 x i8> %5 1613} 1614 1615define i8 @select_sub_cmp_swap(i8 %0, i8 %1) { 1616; CHECK-LABEL: @select_sub_cmp_swap( 1617; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i8 [[TMP0:%.*]], [[TMP1:%.*]] 1618; CHECK-NEXT: ret i8 [[TMP3]] 1619; 1620 %3 = icmp eq i8 %1, %0 1621 %4 = sub nsw i8 %0, %1 1622 %5 = select i1 %3, i8 0, i8 %4 1623 ret i8 %5 1624} 1625 1626define <2 x i8> @select_sub_cmp_vec_swap(<2 x i8> %0, <2 x i8> %1) { 1627; CHECK-LABEL: @select_sub_cmp_vec_swap( 1628; CHECK-NEXT: [[TMP3:%.*]] = sub nsw <2 x i8> [[TMP0:%.*]], [[TMP1:%.*]] 1629; CHECK-NEXT: ret <2 x i8> [[TMP3]] 1630; 1631 %3 = icmp eq <2 x i8> %1, %0 1632 %4 = sub nsw <2 x i8> %0, %1 1633 %5 = select <2 x i1> %3, <2 x i8> <i8 0, i8 0>, <2 x i8> %4 1634 ret <2 x i8> %5 1635} 1636 1637; negative test 1638define i8 @select_sub_cmp_nonzero(i8 %0, i8 %1) { 1639; CHECK-LABEL: @select_sub_cmp_nonzero( 1640; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1:%.*]], [[TMP0:%.*]] 1641; CHECK-NEXT: [[TMP4:%.*]] = sub nsw i8 [[TMP1]], [[TMP0]] 1642; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], i8 42, i8 [[TMP4]] 1643; CHECK-NEXT: ret i8 [[TMP5]] 1644; 1645 %3 = icmp eq i8 %1, %0 1646 %4 = sub nsw i8 %1, %0 1647 %5 = select i1 %3, i8 42, i8 %4 1648 ret i8 %5 1649} 1650 1651; X == Y ? 0 : X ^ Y --> X ^ Y, https://alive2.llvm.org/ce/z/cykffE 1652define i8 @select_xor_cmp(i8 %0, i8 %1) { 1653; CHECK-LABEL: @select_xor_cmp( 1654; CHECK-NEXT: [[TMP3:%.*]] = xor i8 [[TMP1:%.*]], [[TMP0:%.*]] 1655; CHECK-NEXT: ret i8 [[TMP3]] 1656; 1657 %3 = icmp eq i8 %1, %0 1658 %4 = xor i8 %1, %0 1659 %5 = select i1 %3, i8 0, i8 %4 1660 ret i8 %5 1661} 1662 1663define <2 x i8> @select_xor_cmp_vec(<2 x i8> %0, <2 x i8> %1) { 1664; CHECK-LABEL: @select_xor_cmp_vec( 1665; CHECK-NEXT: [[TMP3:%.*]] = xor <2 x i8> [[TMP1:%.*]], [[TMP0:%.*]] 1666; CHECK-NEXT: ret <2 x i8> [[TMP3]] 1667; 1668 %3 = icmp eq <2 x i8> %1, %0 1669 %4 = xor <2 x i8> %1, %0 1670 %5 = select <2 x i1> %3, <2 x i8> <i8 0, i8 0>, <2 x i8> %4 1671 ret <2 x i8> %5 1672} 1673 1674define i8 @select_xor_cmp_swap(i8 %0, i8 %1) { 1675; CHECK-LABEL: @select_xor_cmp_swap( 1676; CHECK-NEXT: [[TMP3:%.*]] = xor i8 [[TMP0:%.*]], [[TMP1:%.*]] 1677; CHECK-NEXT: ret i8 [[TMP3]] 1678; 1679 %3 = icmp eq i8 %1, %0 1680 %4 = xor i8 %0, %1 1681 %5 = select i1 %3, i8 0, i8 %4 1682 ret i8 %5 1683} 1684 1685define <2 x i8> @select_xor_cmp_vec_swap(<2 x i8> %0, <2 x i8> %1) { 1686; CHECK-LABEL: @select_xor_cmp_vec_swap( 1687; CHECK-NEXT: [[TMP3:%.*]] = xor <2 x i8> [[TMP0:%.*]], [[TMP1:%.*]] 1688; CHECK-NEXT: ret <2 x i8> [[TMP3]] 1689; 1690 %3 = icmp eq <2 x i8> %1, %0 1691 %4 = xor <2 x i8> %0, %1 1692 %5 = select <2 x i1> %3, <2 x i8> <i8 0, i8 0>, <2 x i8> %4 1693 ret <2 x i8> %5 1694} 1695 1696; Negative test: the xor operands are not %0 and %1 1697define i8 @select_xor_cmp_unmatched_operands(i8 %0, i8 %1, i8 %c) { 1698; CHECK-LABEL: @select_xor_cmp_unmatched_operands( 1699; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1:%.*]], [[TMP0:%.*]] 1700; CHECK-NEXT: [[TMP4:%.*]] = xor i8 [[TMP1]], [[C:%.*]] 1701; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], i8 0, i8 [[TMP4]] 1702; CHECK-NEXT: ret i8 [[TMP5]] 1703; 1704 %3 = icmp eq i8 %1, %0 1705 %4 = xor i8 %1, %c 1706 %5 = select i1 %3, i8 0, i8 %4 1707 ret i8 %5 1708} 1709 1710define i8 @select_or_eq(i8 %x, i8 %y) { 1711; CHECK-LABEL: @select_or_eq( 1712; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 1713; CHECK-NEXT: ret i8 [[OR]] 1714; 1715 %cmp = icmp eq i8 %x, %y 1716 %or = or i8 %x, %y 1717 %sel = select i1 %cmp, i8 %x, i8 %or 1718 ret i8 %sel 1719} 1720 1721define i8 @select_or_disjoint_eq(i8 %x, i8 %y) { 1722; CHECK-LABEL: @select_or_disjoint_eq( 1723; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 1724; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X]], [[Y]] 1725; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[OR]] 1726; CHECK-NEXT: ret i8 [[SEL]] 1727; 1728 %cmp = icmp eq i8 %x, %y 1729 %or = or disjoint i8 %x, %y 1730 %sel = select i1 %cmp, i8 %x, i8 %or 1731 ret i8 %sel 1732} 1733 1734define <4 x i32> @select_vector_cmp_with_bitcasts(<2 x i64> %x, <4 x i32> %y) { 1735; CHECK-LABEL: @select_vector_cmp_with_bitcasts( 1736; CHECK-NEXT: [[X_BC:%.*]] = bitcast <2 x i64> [[X:%.*]] to <4 x i32> 1737; CHECK-NEXT: [[Y_BC:%.*]] = bitcast <4 x i32> [[Y:%.*]] to <2 x i64> 1738; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i64> [[X]], [[Y_BC]] 1739; CHECK-NEXT: [[SUB_BC:%.*]] = bitcast <2 x i64> [[SUB]] to <4 x i32> 1740; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[Y]], [[X_BC]] 1741; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[SUB_BC]], <4 x i32> zeroinitializer 1742; CHECK-NEXT: ret <4 x i32> [[SEL]] 1743; 1744 %x.bc = bitcast <2 x i64> %x to <4 x i32> 1745 %y.bc = bitcast <4 x i32> %y to <2 x i64> 1746 %sub = sub <2 x i64> %x, %y.bc 1747 %sub.bc = bitcast <2 x i64> %sub to <4 x i32> 1748 %cmp = icmp eq <4 x i32> %y, %x.bc 1749 %sel = select <4 x i1> %cmp, <4 x i32> %sub.bc, <4 x i32> zeroinitializer 1750 ret <4 x i32> %sel 1751} 1752 1753define i8 @bittest_trunc_or(i8 %x) { 1754; CHECK-LABEL: @bittest_trunc_or( 1755; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X1:%.*]] to i1 1756; CHECK-NEXT: [[OR:%.*]] = or i8 [[X1]], 1 1757; CHECK-NEXT: [[X:%.*]] = select i1 [[TRUNC]], i8 [[OR]], i8 [[X1]] 1758; CHECK-NEXT: ret i8 [[X]] 1759; 1760 %trunc = trunc i8 %x to i1 1761 %or = or i8 %x, 1 1762 %cond = select i1 %trunc, i8 %or, i8 %x 1763 ret i8 %cond 1764} 1765 1766define i8 @bittest_trunc_not_or(i8 %x) { 1767; CHECK-LABEL: @bittest_trunc_not_or( 1768; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1 1769; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true 1770; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], 1 1771; CHECK-NEXT: [[COND:%.*]] = select i1 [[NOT]], i8 [[OR]], i8 [[X]] 1772; CHECK-NEXT: ret i8 [[COND]] 1773; 1774 %trunc = trunc i8 %x to i1 1775 %not = xor i1 %trunc, true 1776 %or = or i8 %x, 1 1777 %cond = select i1 %not, i8 %or, i8 %x 1778 ret i8 %cond 1779} 1780