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