1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -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 <2 x i1> @bool_true_or_false_vec(<2 x i1> %cond) { 13; CHECK-LABEL: @bool_true_or_false_vec( 14; CHECK-NEXT: ret <2 x i1> [[COND:%.*]] 15; 16 %s = select <2 x i1> %cond, <2 x i1> <i1 true, i1 true>, <2 x i1> zeroinitializer 17 ret <2 x i1> %s 18} 19 20define <2 x i1> @bool_true_or_false_vec_undef(<2 x i1> %cond) { 21; CHECK-LABEL: @bool_true_or_false_vec_undef( 22; CHECK-NEXT: ret <2 x i1> [[COND:%.*]] 23; 24 %s = select <2 x i1> %cond, <2 x i1> <i1 undef, i1 true>, <2 x i1> <i1 false, i1 undef> 25 ret <2 x i1> %s 26} 27 28define i32 @cond_is_false(i32 %A, i32 %B) { 29; CHECK-LABEL: @cond_is_false( 30; CHECK-NEXT: ret i32 [[B:%.*]] 31; 32 %C = select i1 false, i32 %A, i32 %B 33 ret i32 %C 34} 35 36define i32 @cond_is_true(i32 %A, i32 %B) { 37; CHECK-LABEL: @cond_is_true( 38; CHECK-NEXT: ret i32 [[A:%.*]] 39; 40 %C = select i1 true, i32 %A, i32 %B 41 ret i32 %C 42} 43 44define i32 @equal_arms(i1 %cond, i32 %x) { 45; CHECK-LABEL: @equal_arms( 46; CHECK-NEXT: ret i32 [[X:%.*]] 47; 48 %V = select i1 %cond, i32 %x, i32 %x 49 ret i32 %V 50} 51 52define <2 x i32> @equal_arms_vec(<2 x i1> %cond, <2 x i32> %x) { 53; CHECK-LABEL: @equal_arms_vec( 54; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 55; 56 %V = select <2 x i1> %cond, <2 x i32> %x, <2 x i32> %x 57 ret <2 x i32> %V 58} 59 60define <2 x i32> @equal_arms_vec_undef(<2 x i1> %cond) { 61; CHECK-LABEL: @equal_arms_vec_undef( 62; CHECK-NEXT: [[V:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> <i32 42, i32 undef>, <2 x i32> <i32 undef, i32 42> 63; CHECK-NEXT: ret <2 x i32> [[V]] 64; 65 %V = select <2 x i1> %cond, <2 x i32> <i32 42, i32 undef>, <2 x i32> <i32 undef, i32 42> 66 ret <2 x i32> %V 67} 68 69define <2 x i8> @vsel_tvec(<2 x i8> %x, <2 x i8> %y) { 70; CHECK-LABEL: @vsel_tvec( 71; CHECK-NEXT: ret <2 x i8> [[X:%.*]] 72; 73 %s = select <2 x i1><i1 true, i1 true>, <2 x i8> %x, <2 x i8> %y 74 ret <2 x i8> %s 75} 76 77define <2 x i8> @vsel_fvec(<2 x i8> %x, <2 x i8> %y) { 78; CHECK-LABEL: @vsel_fvec( 79; CHECK-NEXT: ret <2 x i8> [[Y:%.*]] 80; 81 %s = select <2 x i1><i1 false, i1 false>, <2 x i8> %x, <2 x i8> %y 82 ret <2 x i8> %s 83} 84 85define <2 x i8> @vsel_mixedvec() { 86; CHECK-LABEL: @vsel_mixedvec( 87; CHECK-NEXT: ret <2 x i8> <i8 0, i8 3> 88; 89 %s = select <2 x i1><i1 true, i1 false>, <2 x i8> <i8 0, i8 1>, <2 x i8> <i8 2, i8 3> 90 ret <2 x i8> %s 91} 92 93; FIXME: Allow for undef elements in a constant vector condition. 94 95define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) { 96; CHECK-LABEL: @vsel_undef_true_op( 97; CHECK-NEXT: [[S:%.*]] = select <3 x i1> <i1 true, i1 undef, i1 true>, <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]] 98; CHECK-NEXT: ret <3 x i8> [[S]] 99; 100 %s = select <3 x i1><i1 1, i1 undef, i1 1>, <3 x i8> %x, <3 x i8> %y 101 ret <3 x i8> %s 102} 103 104define <3 x i4> @vsel_undef_false_op(<3 x i4> %x, <3 x i4> %y) { 105; CHECK-LABEL: @vsel_undef_false_op( 106; CHECK-NEXT: [[S:%.*]] = select <3 x i1> <i1 false, i1 undef, i1 undef>, <3 x i4> [[X:%.*]], <3 x i4> [[Y:%.*]] 107; CHECK-NEXT: ret <3 x i4> [[S]] 108; 109 %s = select <3 x i1><i1 0, i1 undef, i1 undef>, <3 x i4> %x, <3 x i4> %y 110 ret <3 x i4> %s 111} 112 113define i32 @test1(i32 %x) { 114; CHECK-LABEL: @test1( 115; CHECK-NEXT: ret i32 [[X:%.*]] 116; 117 %and = and i32 %x, 1 118 %cmp = icmp eq i32 %and, 0 119 %and1 = and i32 %x, -2 120 %and1.x = select i1 %cmp, i32 %and1, i32 %x 121 ret i32 %and1.x 122} 123 124define i32 @test2(i32 %x) { 125; CHECK-LABEL: @test2( 126; CHECK-NEXT: ret i32 [[X:%.*]] 127; 128 %and = and i32 %x, 1 129 %cmp = icmp ne i32 %and, 0 130 %and1 = and i32 %x, -2 131 %and1.x = select i1 %cmp, i32 %x, i32 %and1 132 ret i32 %and1.x 133} 134 135define i32 @test3(i32 %x) { 136; CHECK-LABEL: @test3( 137; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], -2 138; CHECK-NEXT: ret i32 [[AND1]] 139; 140 %and = and i32 %x, 1 141 %cmp = icmp ne i32 %and, 0 142 %and1 = and i32 %x, -2 143 %and1.x = select i1 %cmp, i32 %and1, i32 %x 144 ret i32 %and1.x 145} 146 147define i32 @test4(i32 %X) { 148; CHECK-LABEL: @test4( 149; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 150; CHECK-NEXT: ret i32 [[OR]] 151; 152 %cmp = icmp slt i32 %X, 0 153 %or = or i32 %X, -2147483648 154 %cond = select i1 %cmp, i32 %X, i32 %or 155 ret i32 %cond 156} 157 158; Same as above, but the compare isn't canonical 159define i32 @test4noncanon(i32 %X) { 160; CHECK-LABEL: @test4noncanon( 161; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 162; CHECK-NEXT: ret i32 [[OR]] 163; 164 %cmp = icmp sle i32 %X, -1 165 %or = or i32 %X, -2147483648 166 %cond = select i1 %cmp, i32 %X, i32 %or 167 ret i32 %cond 168} 169 170define i32 @test5(i32 %X) { 171; CHECK-LABEL: @test5( 172; CHECK-NEXT: ret i32 [[X:%.*]] 173; 174 %cmp = icmp slt i32 %X, 0 175 %or = or i32 %X, -2147483648 176 %cond = select i1 %cmp, i32 %or, i32 %X 177 ret i32 %cond 178} 179 180define i32 @test6(i32 %X) { 181; CHECK-LABEL: @test6( 182; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2147483647 183; CHECK-NEXT: ret i32 [[AND]] 184; 185 %cmp = icmp slt i32 %X, 0 186 %and = and i32 %X, 2147483647 187 %cond = select i1 %cmp, i32 %and, i32 %X 188 ret i32 %cond 189} 190 191define i32 @test7(i32 %X) { 192; CHECK-LABEL: @test7( 193; CHECK-NEXT: ret i32 [[X:%.*]] 194; 195 %cmp = icmp slt i32 %X, 0 196 %and = and i32 %X, 2147483647 197 %cond = select i1 %cmp, i32 %X, i32 %and 198 ret i32 %cond 199} 200 201define i32 @test8(i32 %X) { 202; CHECK-LABEL: @test8( 203; CHECK-NEXT: ret i32 [[X:%.*]] 204; 205 %cmp = icmp sgt i32 %X, -1 206 %or = or i32 %X, -2147483648 207 %cond = select i1 %cmp, i32 %X, i32 %or 208 ret i32 %cond 209} 210 211define i32 @test9(i32 %X) { 212; CHECK-LABEL: @test9( 213; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 214; CHECK-NEXT: ret i32 [[OR]] 215; 216 %cmp = icmp sgt i32 %X, -1 217 %or = or i32 %X, -2147483648 218 %cond = select i1 %cmp, i32 %or, i32 %X 219 ret i32 %cond 220} 221 222; Same as above, but the compare isn't canonical 223define i32 @test9noncanon(i32 %X) { 224; CHECK-LABEL: @test9noncanon( 225; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 226; CHECK-NEXT: ret i32 [[OR]] 227; 228 %cmp = icmp sge i32 %X, 0 229 %or = or i32 %X, -2147483648 230 %cond = select i1 %cmp, i32 %or, i32 %X 231 ret i32 %cond 232} 233 234define i32 @test10(i32 %X) { 235; CHECK-LABEL: @test10( 236; CHECK-NEXT: ret i32 [[X:%.*]] 237; 238 %cmp = icmp sgt i32 %X, -1 239 %and = and i32 %X, 2147483647 240 %cond = select i1 %cmp, i32 %and, i32 %X 241 ret i32 %cond 242} 243 244define i32 @test11(i32 %X) { 245; CHECK-LABEL: @test11( 246; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2147483647 247; CHECK-NEXT: ret i32 [[AND]] 248; 249 %cmp = icmp sgt i32 %X, -1 250 %and = and i32 %X, 2147483647 251 %cond = select i1 %cmp, i32 %X, i32 %and 252 ret i32 %cond 253} 254 255define <2 x i8> @test11vec(<2 x i8> %X) { 256; CHECK-LABEL: @test11vec( 257; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 127, i8 127> 258; CHECK-NEXT: ret <2 x i8> [[AND]] 259; 260 %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1> 261 %and = and <2 x i8> %X, <i8 127, i8 127> 262 %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and 263 ret <2 x i8> %sel 264} 265 266define i32 @test12(i32 %X) { 267; CHECK-LABEL: @test12( 268; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 269; CHECK-NEXT: ret i32 [[AND]] 270; 271 %cmp = icmp ult i32 %X, 4 272 %and = and i32 %X, 3 273 %cond = select i1 %cmp, i32 %X, i32 %and 274 ret i32 %cond 275} 276 277; Same as above, but the compare isn't canonical 278define i32 @test12noncanon(i32 %X) { 279; CHECK-LABEL: @test12noncanon( 280; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 281; CHECK-NEXT: ret i32 [[AND]] 282; 283 %cmp = icmp ule i32 %X, 3 284 %and = and i32 %X, 3 285 %cond = select i1 %cmp, i32 %X, i32 %and 286 ret i32 %cond 287} 288 289define i32 @test13(i32 %X) { 290; CHECK-LABEL: @test13( 291; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 292; CHECK-NEXT: ret i32 [[AND]] 293; 294 %cmp = icmp ugt i32 %X, 3 295 %and = and i32 %X, 3 296 %cond = select i1 %cmp, i32 %and, i32 %X 297 ret i32 %cond 298} 299 300; Same as above, but the compare isn't canonical 301define i32 @test13noncanon(i32 %X) { 302; CHECK-LABEL: @test13noncanon( 303; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 304; CHECK-NEXT: ret i32 [[AND]] 305; 306 %cmp = icmp uge i32 %X, 4 307 %and = and i32 %X, 3 308 %cond = select i1 %cmp, i32 %and, i32 %X 309 ret i32 %cond 310} 311 312define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) { 313; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8( 314; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 8 315; CHECK-NEXT: ret i32 [[OR]] 316; 317 %and = and i32 %x, 8 318 %cmp = icmp eq i32 %and, 0 319 %or = or i32 %x, 8 320 %sel = select i1 %cmp, i32 %or, i32 %x 321 ret i32 %sel 322} 323 324define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) { 325; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt( 326; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 8 327; CHECK-NEXT: ret i32 [[OR]] 328; 329 %and = and i32 %x, 8 330 %cmp = icmp ne i32 %and, 0 331 %or = or i32 %x, 8 332 %sel = select i1 %cmp, i32 %x, i32 %or 333 ret i32 %sel 334} 335 336define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) { 337; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8( 338; CHECK-NEXT: ret i32 [[X:%.*]] 339; 340 %and = and i32 %x, 8 341 %cmp = icmp ne i32 %and, 0 342 %or = or i32 %x, 8 343 %sel = select i1 %cmp, i32 %or, i32 %x 344 ret i32 %sel 345} 346 347define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) { 348; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt( 349; CHECK-NEXT: ret i32 [[X:%.*]] 350; 351 %and = and i32 %x, 8 352 %cmp = icmp eq i32 %and, 0 353 %or = or i32 %x, 8 354 %sel = select i1 %cmp, i32 %x, i32 %or 355 ret i32 %sel 356} 357 358define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) { 359; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8( 360; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], -9 361; CHECK-NEXT: ret i32 [[AND1]] 362; 363 %and = and i32 %x, 8 364 %cmp = icmp eq i32 %and, 0 365 %and1 = and i32 %x, -9 366 %sel = select i1 %cmp, i32 %x, i32 %and1 367 ret i32 %sel 368} 369 370define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) { 371; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt( 372; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], -9 373; CHECK-NEXT: ret i32 [[AND1]] 374; 375 %and = and i32 %x, 8 376 %cmp = icmp ne i32 %and, 0 377 %and1 = and i32 %x, -9 378 %sel = select i1 %cmp, i32 %and1, i32 %x 379 ret i32 %sel 380} 381 382define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) { 383; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8( 384; CHECK-NEXT: ret i32 [[X:%.*]] 385; 386 %and = and i32 %x, 8 387 %cmp = icmp ne i32 %and, 0 388 %and1 = and i32 %x, -9 389 %sel = select i1 %cmp, i32 %x, i32 %and1 390 ret i32 %sel 391} 392 393define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) { 394; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt( 395; CHECK-NEXT: ret i32 [[X:%.*]] 396; 397 %and = and i32 %x, 8 398 %cmp = icmp eq i32 %and, 0 399 %and1 = and i32 %x, -9 400 %sel = select i1 %cmp, i32 %and1, i32 %x 401 ret i32 %sel 402} 403 404; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466 405; Each of the previous 8 patterns has a variant that replaces the 406; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt. 407 408define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) { 409; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128( 410; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 128 411; CHECK-NEXT: ret i32 [[OR]] 412; 413 %trunc = trunc i32 %x to i8 414 %cmp = icmp sgt i8 %trunc, -1 415 %or = or i32 %x, 128 416 %sel = select i1 %cmp, i32 %or, i32 %x 417 ret i32 %sel 418} 419 420define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) { 421; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt( 422; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 128 423; CHECK-NEXT: ret i32 [[OR]] 424; 425 %trunc = trunc i32 %x to i8 426 %cmp = icmp slt i8 %trunc, 0 427 %or = or i32 %x, 128 428 %sel = select i1 %cmp, i32 %x, i32 %or 429 ret i32 %sel 430} 431 432define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) { 433; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128( 434; CHECK-NEXT: ret i32 [[X:%.*]] 435; 436 %trunc = trunc i32 %x to i8 437 %cmp = icmp slt i8 %trunc, 0 438 %or = or i32 %x, 128 439 %sel = select i1 %cmp, i32 %or, i32 %x 440 ret i32 %sel 441} 442 443define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) { 444; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt( 445; CHECK-NEXT: ret i32 [[X:%.*]] 446; 447 %trunc = trunc i32 %x to i8 448 %cmp = icmp sgt i8 %trunc, -1 449 %or = or i32 %x, 128 450 %sel = select i1 %cmp, i32 %x, i32 %or 451 ret i32 %sel 452} 453 454define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) { 455; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8( 456; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], -9 457; CHECK-NEXT: ret i32 [[AND]] 458; 459 %trunc = trunc i32 %x to i4 460 %cmp = icmp sgt i4 %trunc, -1 461 %and = and i32 %x, -9 462 %sel = select i1 %cmp, i32 %x, i32 %and 463 ret i32 %sel 464} 465 466define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) { 467; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt( 468; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], -9 469; CHECK-NEXT: ret i32 [[AND]] 470; 471 %trunc = trunc i32 %x to i4 472 %cmp = icmp slt i4 %trunc, 0 473 %and = and i32 %x, -9 474 %sel = select i1 %cmp, i32 %and, i32 %x 475 ret i32 %sel 476} 477 478define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) { 479; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8( 480; CHECK-NEXT: ret i32 [[X:%.*]] 481; 482 %trunc = trunc i32 %x to i4 483 %cmp = icmp slt i4 %trunc, 0 484 %and = and i32 %x, -9 485 %sel = select i1 %cmp, i32 %x, i32 %and 486 ret i32 %sel 487} 488 489define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) { 490; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt( 491; CHECK-NEXT: ret i32 [[X:%.*]] 492; 493 %trunc = trunc i32 %x to i4 494 %cmp = icmp sgt i4 %trunc, -1 495 %and = and i32 %x, -9 496 %sel = select i1 %cmp, i32 %and, i32 %x 497 ret i32 %sel 498} 499 500; Make sure that at least a few of the same patterns are repeated with vector types. 501 502define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) { 503; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec( 504; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 505; 506 %and = and <2 x i32> %x, <i32 8, i32 8> 507 %cmp = icmp ne <2 x i32> %and, zeroinitializer 508 %and1 = and <2 x i32> %x, <i32 -9, i32 -9> 509 %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1 510 ret <2 x i32> %sel 511} 512 513define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) { 514; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec( 515; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 516; 517 %trunc = trunc <2 x i32> %x to <2 x i4> 518 %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1> 519 %and = and <2 x i32> %x, <i32 -9, i32 -9> 520 %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x 521 ret <2 x i32> %sel 522} 523 524; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify? 525 526define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) { 527; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8( 528; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8 529; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 530; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -9 531; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND1]] 532; CHECK-NEXT: ret i32 [[Y_AND1]] 533; 534 %and = and i32 %x, 8 535 %cmp = icmp eq i32 %and, 0 536 %and1 = and i32 %y, -9 537 %y.and1 = select i1 %cmp, i32 %y, i32 %and1 538 ret i32 %y.and1 539} 540 541define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) { 542; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8( 543; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8 544; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 545; CHECK-NEXT: [[AND1:%.*]] = and i64 [[Y:%.*]], -9 546; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i64 [[Y]], i64 [[AND1]] 547; CHECK-NEXT: ret i64 [[Y_AND1]] 548; 549 %and = and i32 %x, 8 550 %cmp = icmp eq i32 %and, 0 551 %and1 = and i64 %y, -9 552 %y.and1 = select i1 %cmp, i64 %y, i64 %and1 553 ret i64 %y.and1 554} 555 556define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) { 557; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8( 558; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8 559; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 560; CHECK-NEXT: [[AND1:%.*]] = and i64 [[Y:%.*]], -9 561; CHECK-NEXT: [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 [[Y]] 562; CHECK-NEXT: ret i64 [[AND1_Y]] 563; 564 %and = and i32 %x, 8 565 %cmp = icmp eq i32 %and, 0 566 %and1 = and i64 %y, -9 567 %and1.y = select i1 %cmp, i64 %and1, i64 %y 568 ret i64 %and1.y 569} 570 571; Don't crash on a pointer or aggregate type. 572 573define i32* @select_icmp_pointers(i32* %x, i32* %y) { 574; CHECK-LABEL: @select_icmp_pointers( 575; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32* [[X:%.*]], null 576; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32* [[X]], i32* [[Y:%.*]] 577; CHECK-NEXT: ret i32* [[SEL]] 578; 579 %cmp = icmp slt i32* %x, null 580 %sel = select i1 %cmp, i32* %x, i32* %y 581 ret i32* %sel 582} 583 584; If the condition is known, we don't need to select, but we're not 585; doing this fold here to avoid compile-time cost. 586 587declare void @llvm.assume(i1) 588 589define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 590; CHECK-LABEL: @assume_sel_cond( 591; CHECK-NEXT: call void @llvm.assume(i1 [[COND:%.*]]) 592; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 [[X:%.*]], i8 [[Y:%.*]] 593; CHECK-NEXT: ret i8 [[SEL]] 594; 595 call void @llvm.assume(i1 %cond) 596 %sel = select i1 %cond, i8 %x, i8 %y 597 ret i8 %sel 598} 599 600define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 601; CHECK-LABEL: @do_not_assume_sel_cond( 602; CHECK-NEXT: [[NOTCOND:%.*]] = icmp eq i1 [[COND:%.*]], false 603; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) 604; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 [[X:%.*]], i8 [[Y:%.*]] 605; CHECK-NEXT: ret i8 [[SEL]] 606; 607 %notcond = icmp eq i1 %cond, false 608 call void @llvm.assume(i1 %notcond) 609 %sel = select i1 %cond, i8 %x, i8 %y 610 ret i8 %sel 611} 612 613define i32* @select_icmp_eq_0_gep_operand(i32* %base, i64 %n) { 614; CHECK-LABEL: @select_icmp_eq_0_gep_operand( 615; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[BASE:%.*]], i64 [[N:%.*]] 616; CHECK-NEXT: ret i32* [[GEP]] 617; 618 %cond = icmp eq i64 %n, 0 619 %gep = getelementptr i32, i32* %base, i64 %n 620 %r = select i1 %cond, i32* %base, i32* %gep 621 ret i32* %r 622} 623 624define i32* @select_icmp_ne_0_gep_operand(i32* %base, i64 %n) { 625; CHECK-LABEL: @select_icmp_ne_0_gep_operand( 626; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[BASE:%.*]], i64 [[N:%.*]] 627; CHECK-NEXT: ret i32* [[GEP]] 628; 629 %cond = icmp ne i64 %n, 0 630 %gep = getelementptr i32, i32* %base, i64 %n 631 %r = select i1 %cond, i32* %gep, i32* %base 632 ret i32* %r 633} 634