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