1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3; RUN: opt < %s -passes=instcombine -use-constant-int-for-fixed-length-splat -S | FileCheck %s 4 5declare void @use(i64) 6declare void @use_i32(i32) 7 8declare i32 @llvm.cttz.i32(i32, i1 immarg) 9declare <2 x i8> @llvm.cttz.v2i8(<2 x i8>, i1 immarg) 10 11define <4 x i32> @lshr_non_splat_vector(<4 x i32> %A) { 12; CHECK-LABEL: @lshr_non_splat_vector( 13; CHECK-NEXT: [[B:%.*]] = lshr <4 x i32> [[A:%.*]], <i32 32, i32 1, i32 2, i32 3> 14; CHECK-NEXT: ret <4 x i32> [[B]] 15; 16 %B = lshr <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3> 17 ret <4 x i32> %B 18} 19 20define <4 x i32> @shl_non_splat_vector(<4 x i32> %A) { 21; CHECK-LABEL: @shl_non_splat_vector( 22; CHECK-NEXT: [[B:%.*]] = shl <4 x i32> [[A:%.*]], <i32 32, i32 1, i32 2, i32 3> 23; CHECK-NEXT: ret <4 x i32> [[B]] 24; 25 %B = shl <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3> 26 ret <4 x i32> %B 27} 28 29define i32 @test6(i32 %A) { 30; CHECK-LABEL: @test6( 31; CHECK-NEXT: [[C:%.*]] = mul i32 [[A:%.*]], 6 32; CHECK-NEXT: ret i32 [[C]] 33; 34 %B = shl i32 %A, 1 ;; convert to an mul instruction 35 %C = mul i32 %B, 3 36 ret i32 %C 37} 38 39define i32 @test6a(i32 %A) { 40; CHECK-LABEL: @test6a( 41; CHECK-NEXT: [[C:%.*]] = mul i32 [[A:%.*]], 6 42; CHECK-NEXT: ret i32 [[C]] 43; 44 %B = mul i32 %A, 3 45 %C = shl i32 %B, 1 ;; convert to an mul instruction 46 ret i32 %C 47} 48 49;; (A << 5) << 3 === A << 8 == 0 50define i8 @test8(i8 %A) { 51; CHECK-LABEL: @test8( 52; CHECK-NEXT: ret i8 0 53; 54 %B = shl i8 %A, 5 55 %C = shl i8 %B, 3 56 ret i8 %C 57} 58 59;; (A << 7) >> 7 === A & 1 60define i8 @test9(i8 %A) { 61; CHECK-LABEL: @test9( 62; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 1 63; CHECK-NEXT: ret i8 [[B]] 64; 65 %B = shl i8 %A, 7 66 %C = lshr i8 %B, 7 67 ret i8 %C 68} 69 70;; (A >> 7) << 7 === A & 128 71 72define i8 @test10(i8 %A) { 73; CHECK-LABEL: @test10( 74; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], -128 75; CHECK-NEXT: ret i8 [[B]] 76; 77 %B = lshr i8 %A, 7 78 %C = shl i8 %B, 7 79 ret i8 %C 80} 81 82;; Allow the simplification when the lshr shift is exact. 83define i8 @test10a(i8 %A) { 84; CHECK-LABEL: @test10a( 85; CHECK-NEXT: ret i8 [[A:%.*]] 86; 87 %B = lshr exact i8 %A, 7 88 %C = shl i8 %B, 7 89 ret i8 %C 90} 91 92;; (A >> 3) << 4 === (A & 0x1F) << 1 93define i8 @test11(i8 %x) { 94; CHECK-LABEL: @test11( 95; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 6 96; CHECK-NEXT: [[C:%.*]] = and i8 [[TMP1]], -16 97; CHECK-NEXT: ret i8 [[C]] 98; 99 %a = mul i8 %x, 3 100 %B = lshr i8 %a, 3 101 %C = shl i8 %B, 4 102 ret i8 %C 103} 104 105;; Allow the simplification in InstCombine when the lshr shift is exact. 106define i8 @test11a(i8 %A) { 107; CHECK-LABEL: @test11a( 108; CHECK-NEXT: [[C:%.*]] = mul i8 [[A:%.*]], 6 109; CHECK-NEXT: ret i8 [[C]] 110; 111 %a = mul i8 %A, 3 112 %B = lshr exact i8 %a, 3 113 %C = shl i8 %B, 4 114 ret i8 %C 115} 116 117;; (A >> 8) << 8 === A & -256 118define i32 @test12(i32 %A) { 119; CHECK-LABEL: @test12( 120; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -256 121; CHECK-NEXT: ret i32 [[B]] 122; 123 %B = ashr i32 %A, 8 124 %C = shl i32 %B, 8 125 ret i32 %C 126} 127 128;; ((A >>s 6) << 6 === (A & FFFFFFC0) 129define i8 @shishi(i8 %x) { 130; CHECK-LABEL: @shishi( 131; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 6 132; CHECK-NEXT: [[B:%.*]] = and i8 [[X]], -64 133; CHECK-NEXT: [[EXTRA_USE_OF_A:%.*]] = mul nsw i8 [[A]], 5 134; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[EXTRA_USE_OF_A]], [[B]] 135; CHECK-NEXT: ret i8 [[R]] 136; 137 %a = ashr i8 %x, 6 138 %b = shl i8 %a, 6 139 %extra_use_of_a = mul i8 %a, 5 140 %r = sdiv i8 %extra_use_of_a, %b 141 ret i8 %r 142} 143 144;; (A >> 3) << 4 === (A & -8) * 2 145define i8 @test13(i8 %x) { 146; CHECK-LABEL: @test13( 147; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 6 148; CHECK-NEXT: [[C:%.*]] = and i8 [[TMP1]], -16 149; CHECK-NEXT: ret i8 [[C]] 150; 151 %a = mul i8 %x, 3 152 %B = ashr i8 %a, 3 153 %C = shl i8 %B, 4 154 ret i8 %C 155} 156 157define i8 @test13a(i8 %A) { 158; CHECK-LABEL: @test13a( 159; CHECK-NEXT: [[C:%.*]] = mul i8 [[A:%.*]], 6 160; CHECK-NEXT: ret i8 [[C]] 161; 162 %a = mul i8 %A, 3 163 %B = ashr exact i8 %a, 3 164 %C = shl i8 %B, 4 165 ret i8 %C 166} 167 168;; D = ((B | 1234) << 4) === ((B << 4)|(1234 << 4) 169define i32 @test14(i32 %A) { 170; CHECK-LABEL: @test14( 171; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -19760 172; CHECK-NEXT: [[C:%.*]] = or disjoint i32 [[B]], 19744 173; CHECK-NEXT: ret i32 [[C]] 174; 175 %B = lshr i32 %A, 4 176 %C = or i32 %B, 1234 177 %D = shl i32 %C, 4 178 ret i32 %D 179} 180 181;; D = ((B | 1234) << 4) === ((B << 4)|(1234 << 4) 182define i32 @test14a(i32 %A) { 183; CHECK-LABEL: @test14a( 184; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 77 185; CHECK-NEXT: ret i32 [[C]] 186; 187 %B = shl i32 %A, 4 188 %C = and i32 %B, 1234 189 %D = lshr i32 %C, 4 190 ret i32 %D 191} 192 193define i32 @test15(i1 %C) { 194; CHECK-LABEL: @test15( 195; CHECK-NEXT: [[A:%.*]] = select i1 [[C:%.*]], i32 12, i32 4 196; CHECK-NEXT: ret i32 [[A]] 197; 198 %A = select i1 %C, i32 3, i32 1 199 %V = shl i32 %A, 2 200 ret i32 %V 201} 202 203define i32 @test15a(i1 %C) { 204; CHECK-LABEL: @test15a( 205; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 512, i32 128 206; CHECK-NEXT: ret i32 [[V]] 207; 208 %A = select i1 %C, i8 3, i8 1 209 %shift.upgrd.4 = zext i8 %A to i32 210 %V = shl i32 64, %shift.upgrd.4 211 ret i32 %V 212} 213 214define i1 @test16(i32 %X) { 215; CHECK-LABEL: @test16( 216; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 16 217; CHECK-NEXT: [[I_7:%.*]] = icmp ne i32 [[TMP1]], 0 218; CHECK-NEXT: ret i1 [[I_7]] 219; 220 %i.3 = ashr i32 %X, 4 221 %i.6 = and i32 %i.3, 1 222 %i.7 = icmp ne i32 %i.6, 0 223 ret i1 %i.7 224} 225 226define i1 @test17(i32 %A) { 227; CHECK-LABEL: @test17( 228; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[A:%.*]], -8 229; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[B_MASK]], 9872 230; CHECK-NEXT: ret i1 [[C]] 231; 232 %B = lshr i32 %A, 3 233 %C = icmp eq i32 %B, 1234 234 ret i1 %C 235} 236 237define <2 x i1> @test17vec(<2 x i32> %A) { 238; CHECK-LABEL: @test17vec( 239; CHECK-NEXT: [[B_MASK:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -8) 240; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[B_MASK]], splat (i32 9872) 241; CHECK-NEXT: ret <2 x i1> [[C]] 242; 243 %B = lshr <2 x i32> %A, <i32 3, i32 3> 244 %C = icmp eq <2 x i32> %B, <i32 1234, i32 1234> 245 ret <2 x i1> %C 246} 247 248define i1 @test18(i8 %A) { 249; CHECK-LABEL: @test18( 250; CHECK-NEXT: ret i1 false 251; 252 %B = lshr i8 %A, 7 253 ;; false 254 %C = icmp eq i8 %B, 123 255 ret i1 %C 256} 257 258define i1 @test19(i32 %A) { 259; CHECK-LABEL: @test19( 260; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A:%.*]], 4 261; CHECK-NEXT: ret i1 [[C]] 262; 263 %B = ashr i32 %A, 2 264 ;; (X & -4) == 0 265 %C = icmp eq i32 %B, 0 266 ret i1 %C 267} 268 269define <2 x i1> @test19vec(<2 x i32> %A) { 270; CHECK-LABEL: @test19vec( 271; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 4) 272; CHECK-NEXT: ret <2 x i1> [[C]] 273; 274 %B = ashr <2 x i32> %A, <i32 2, i32 2> 275 %C = icmp eq <2 x i32> %B, zeroinitializer 276 ret <2 x i1> %C 277} 278 279;; X >u ~4 280define i1 @test19a(i32 %A) { 281; CHECK-LABEL: @test19a( 282; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5 283; CHECK-NEXT: ret i1 [[C]] 284; 285 %B = ashr i32 %A, 2 286 %C = icmp eq i32 %B, -1 287 ret i1 %C 288} 289 290define <2 x i1> @test19a_vec(<2 x i32> %A) { 291; CHECK-LABEL: @test19a_vec( 292; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 -5) 293; CHECK-NEXT: ret <2 x i1> [[C]] 294; 295 %B = ashr <2 x i32> %A, <i32 2, i32 2> 296 %C = icmp eq <2 x i32> %B, <i32 -1, i32 -1> 297 ret <2 x i1> %C 298} 299 300define i1 @test20(i8 %A) { 301; CHECK-LABEL: @test20( 302; CHECK-NEXT: ret i1 false 303; 304 %B = ashr i8 %A, 7 305 ;; false 306 %C = icmp eq i8 %B, 123 307 ret i1 %C 308} 309 310define i1 @test21(i8 %A) { 311; CHECK-LABEL: @test21( 312; CHECK-NEXT: [[B_MASK:%.*]] = and i8 [[A:%.*]], 15 313; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B_MASK]], 8 314; CHECK-NEXT: ret i1 [[C]] 315; 316 %B = shl i8 %A, 4 317 %C = icmp eq i8 %B, -128 318 ret i1 %C 319} 320 321define i1 @test22(i8 %A) { 322; CHECK-LABEL: @test22( 323; CHECK-NEXT: [[B_MASK:%.*]] = and i8 [[A:%.*]], 15 324; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B_MASK]], 0 325; CHECK-NEXT: ret i1 [[C]] 326; 327 %B = shl i8 %A, 4 328 %C = icmp eq i8 %B, 0 329 ret i1 %C 330} 331 332define i8 @test23(i32 %A) { 333; CHECK-LABEL: @test23( 334; CHECK-NEXT: [[D:%.*]] = trunc i32 [[A:%.*]] to i8 335; CHECK-NEXT: ret i8 [[D]] 336; 337 ;; casts not needed 338 %B = shl i32 %A, 24 339 %C = ashr i32 %B, 24 340 %D = trunc i32 %C to i8 341 ret i8 %D 342} 343 344define i8 @test24(i8 %X) { 345; CHECK-LABEL: @test24( 346; CHECK-NEXT: [[Z:%.*]] = and i8 [[X:%.*]], 3 347; CHECK-NEXT: ret i8 [[Z]] 348; 349 %Y = and i8 %X, -5 350 %Z = shl i8 %Y, 5 351 %Q = ashr i8 %Z, 5 352 ret i8 %Q 353} 354 355;; handle casts between shifts. 356define i32 @test26(i32 %A) { 357; CHECK-LABEL: @test26( 358; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], -2 359; CHECK-NEXT: ret i32 [[B]] 360; 361 %B = lshr i32 %A, 1 362 %C = bitcast i32 %B to i32 363 %D = shl i32 %C, 1 364 ret i32 %D 365} 366 367define i1 @test27(i32 %x) { 368; CHECK-LABEL: @test27( 369; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 8 370; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[TMP1]], 0 371; CHECK-NEXT: ret i1 [[Z]] 372; 373 %y = lshr i32 %x, 3 374 %z = trunc i32 %y to i1 375 ret i1 %z 376} 377 378define i1 @test28(i8 %x) { 379; CHECK-LABEL: @test28( 380; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0 381; CHECK-NEXT: ret i1 [[CMP]] 382; 383 %shr = lshr i8 %x, 7 384 %cmp = icmp ne i8 %shr, 0 385 ret i1 %cmp 386} 387 388define <2 x i1> @test28vec(<2 x i8> %x) { 389; CHECK-LABEL: @test28vec( 390; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer 391; CHECK-NEXT: ret <2 x i1> [[CMP]] 392; 393 %shr = lshr <2 x i8> %x, <i8 7, i8 7> 394 %cmp = icmp ne <2 x i8> %shr, zeroinitializer 395 ret <2 x i1> %cmp 396} 397 398define i8 @test28a(i8 %x, i8 %y) { 399; CHECK-LABEL: @test28a( 400; CHECK-NEXT: entry: 401; CHECK-NEXT: [[COND1_NOT:%.*]] = icmp sgt i8 [[X:%.*]], -1 402; CHECK-NEXT: br i1 [[COND1_NOT]], label [[BB2:%.*]], label [[BB1:%.*]] 403; CHECK: bb1: 404; CHECK-NEXT: ret i8 1 405; CHECK: bb2: 406; CHECK-NEXT: ret i8 [[Y:%.*]] 407; 408entry: 409; This shouldn't be transformed. 410 %i1 = lshr i8 %x, 7 411 %cond1 = icmp ne i8 %i1, 0 412 br i1 %cond1, label %bb1, label %bb2 413bb1: 414 ret i8 %i1 415bb2: 416 %i2 = add i8 %i1, %y 417 ret i8 %i2 418} 419 420define i32 @test29(i64 %d18) { 421; CHECK-LABEL: @test29( 422; CHECK-NEXT: entry: 423; CHECK-NEXT: [[SUM_SHIFT:%.*]] = lshr i64 [[D18:%.*]], 63 424; CHECK-NEXT: [[I101:%.*]] = trunc nuw nsw i64 [[SUM_SHIFT]] to i32 425; CHECK-NEXT: ret i32 [[I101]] 426; 427entry: 428 %i916 = lshr i64 %d18, 32 429 %i917 = trunc i64 %i916 to i32 430 %i10 = lshr i32 %i917, 31 431 ret i32 %i10 432} 433 434define <2 x i32> @test29_uniform(<2 x i64> %d18) { 435; CHECK-LABEL: @test29_uniform( 436; CHECK-NEXT: entry: 437; CHECK-NEXT: [[SUM_SHIFT:%.*]] = lshr <2 x i64> [[D18:%.*]], splat (i64 63) 438; CHECK-NEXT: [[I101:%.*]] = trunc nuw nsw <2 x i64> [[SUM_SHIFT]] to <2 x i32> 439; CHECK-NEXT: ret <2 x i32> [[I101]] 440; 441entry: 442 %i916 = lshr <2 x i64> %d18, <i64 32, i64 32> 443 %i917 = trunc <2 x i64> %i916 to <2 x i32> 444 %i10 = lshr <2 x i32> %i917, <i32 31, i32 31> 445 ret <2 x i32> %i10 446} 447 448define <2 x i32> @test29_nonuniform(<2 x i64> %d18) { 449; CHECK-LABEL: @test29_nonuniform( 450; CHECK-NEXT: entry: 451; CHECK-NEXT: [[I916:%.*]] = lshr <2 x i64> [[D18:%.*]], <i64 32, i64 15> 452; CHECK-NEXT: [[I917:%.*]] = trunc <2 x i64> [[I916]] to <2 x i32> 453; CHECK-NEXT: [[I10:%.*]] = lshr <2 x i32> [[I917]], <i32 31, i32 22> 454; CHECK-NEXT: ret <2 x i32> [[I10]] 455; 456entry: 457 %i916 = lshr <2 x i64> %d18, <i64 32, i64 15> 458 %i917 = trunc <2 x i64> %i916 to <2 x i32> 459 %i10 = lshr <2 x i32> %i917, <i32 31, i32 22> 460 ret <2 x i32> %i10 461} 462 463define <2 x i32> @test29_poison(<2 x i64> %d18) { 464; CHECK-LABEL: @test29_poison( 465; CHECK-NEXT: entry: 466; CHECK-NEXT: [[I916:%.*]] = lshr <2 x i64> [[D18:%.*]], <i64 32, i64 poison> 467; CHECK-NEXT: [[I917:%.*]] = trunc nuw <2 x i64> [[I916]] to <2 x i32> 468; CHECK-NEXT: [[I10:%.*]] = lshr <2 x i32> [[I917]], <i32 31, i32 poison> 469; CHECK-NEXT: ret <2 x i32> [[I10]] 470; 471entry: 472 %i916 = lshr <2 x i64> %d18, <i64 32, i64 poison> 473 %i917 = trunc <2 x i64> %i916 to <2 x i32> 474 %i10 = lshr <2 x i32> %i917, <i32 31, i32 poison> 475 ret <2 x i32> %i10 476} 477 478define i32 @test30(i32 %A, i32 %B, i32 %C) { 479; CHECK-LABEL: @test30( 480; CHECK-NEXT: [[X1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 481; CHECK-NEXT: [[Z:%.*]] = shl i32 [[X1]], [[C:%.*]] 482; CHECK-NEXT: ret i32 [[Z]] 483; 484 %X = shl i32 %A, %C 485 %Y = shl i32 %B, %C 486 %Z = and i32 %X, %Y 487 ret i32 %Z 488} 489 490define i32 @test31(i32 %A, i32 %B, i32 %C) { 491; CHECK-LABEL: @test31( 492; CHECK-NEXT: [[X1:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 493; CHECK-NEXT: [[Z:%.*]] = lshr i32 [[X1]], [[C:%.*]] 494; CHECK-NEXT: ret i32 [[Z]] 495; 496 %X = lshr i32 %A, %C 497 %Y = lshr i32 %B, %C 498 %Z = or i32 %X, %Y 499 ret i32 %Z 500} 501 502define i32 @test32(i32 %A, i32 %B, i32 %C) { 503; CHECK-LABEL: @test32( 504; CHECK-NEXT: [[X1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 505; CHECK-NEXT: [[Z:%.*]] = ashr i32 [[X1]], [[C:%.*]] 506; CHECK-NEXT: ret i32 [[Z]] 507; 508 %X = ashr i32 %A, %C 509 %Y = ashr i32 %B, %C 510 %Z = xor i32 %X, %Y 511 ret i32 %Z 512} 513 514define i1 @test33(i32 %X) { 515; CHECK-LABEL: @test33( 516; CHECK-NEXT: [[I1_MASK:%.*]] = and i32 [[X:%.*]], 16777216 517; CHECK-NEXT: [[I2:%.*]] = icmp ne i32 [[I1_MASK]], 0 518; CHECK-NEXT: ret i1 [[I2]] 519; 520 %i1 = shl i32 %X, 7 521 %i2 = icmp slt i32 %i1, 0 522 ret i1 %i2 523} 524 525define <2 x i1> @test33vec(<2 x i32> %X) { 526; CHECK-LABEL: @test33vec( 527; CHECK-NEXT: [[I1_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 16777216) 528; CHECK-NEXT: [[I2:%.*]] = icmp ne <2 x i32> [[I1_MASK]], zeroinitializer 529; CHECK-NEXT: ret <2 x i1> [[I2]] 530; 531 %i1 = shl <2 x i32> %X, <i32 7, i32 7> 532 %i2 = icmp slt <2 x i32> %i1, zeroinitializer 533 ret <2 x i1> %i2 534} 535 536define i1 @test34(i32 %X) { 537; CHECK-LABEL: @test34( 538; CHECK-NEXT: ret i1 false 539; 540 %i1 = lshr i32 %X, 7 541 %i2 = icmp slt i32 %i1, 0 542 ret i1 %i2 543} 544 545define i1 @test35(i32 %X) { 546; CHECK-LABEL: @test35( 547; CHECK-NEXT: [[I2:%.*]] = icmp slt i32 [[X:%.*]], 0 548; CHECK-NEXT: ret i1 [[I2]] 549; 550 %i1 = ashr i32 %X, 7 551 %i2 = icmp slt i32 %i1, 0 552 ret i1 %i2 553} 554 555define <2 x i1> @test35vec(<2 x i32> %X) { 556; CHECK-LABEL: @test35vec( 557; CHECK-NEXT: [[I2:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer 558; CHECK-NEXT: ret <2 x i1> [[I2]] 559; 560 %i1 = ashr <2 x i32> %X, <i32 7, i32 7> 561 %i2 = icmp slt <2 x i32> %i1, zeroinitializer 562 ret <2 x i1> %i2 563} 564 565define i128 @test36(i128 %A, i128 %B) { 566; CHECK-LABEL: @test36( 567; CHECK-NEXT: [[I231:%.*]] = or i128 [[B:%.*]], [[A:%.*]] 568; CHECK-NEXT: [[INS:%.*]] = and i128 [[I231]], 18446744073709551615 569; CHECK-NEXT: ret i128 [[INS]] 570; 571 %i27 = shl i128 %A, 64 572 %i23 = shl i128 %B, 64 573 %ins = or i128 %i23, %i27 574 %i45 = lshr i128 %ins, 64 575 ret i128 %i45 576} 577 578define i64 @test37(i128 %A, i32 %B) { 579; CHECK-LABEL: @test37( 580; CHECK-NEXT: [[I22:%.*]] = zext i32 [[B:%.*]] to i128 581; CHECK-NEXT: [[I23:%.*]] = shl nuw nsw i128 [[I22]], 32 582; CHECK-NEXT: [[INS:%.*]] = or i128 [[I23]], [[A:%.*]] 583; CHECK-NEXT: [[I46:%.*]] = trunc i128 [[INS]] to i64 584; CHECK-NEXT: ret i64 [[I46]] 585; 586 %i27 = shl i128 %A, 64 587 %i22 = zext i32 %B to i128 588 %i23 = shl i128 %i22, 96 589 %ins = or i128 %i23, %i27 590 %i45 = lshr i128 %ins, 64 591 %i46 = trunc i128 %i45 to i64 592 ret i64 %i46 593} 594 595define <2 x i32> @shl_nuw_nsw_splat_vec(<2 x i8> %x) { 596; CHECK-LABEL: @shl_nuw_nsw_splat_vec( 597; CHECK-NEXT: [[T2:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32> 598; CHECK-NEXT: [[T3:%.*]] = shl nuw nsw <2 x i32> [[T2]], splat (i32 17) 599; CHECK-NEXT: ret <2 x i32> [[T3]] 600; 601 %t2 = zext <2 x i8> %x to <2 x i32> 602 %t3 = shl <2 x i32> %t2, <i32 17, i32 17> 603 ret <2 x i32> %t3 604} 605 606define i32 @test38(i32 %x) { 607; CHECK-LABEL: @test38( 608; CHECK-NEXT: [[REM1:%.*]] = and i32 [[X:%.*]], 31 609; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[REM1]] 610; CHECK-NEXT: ret i32 [[SHL]] 611; 612 %rem = srem i32 %x, 32 613 %shl = shl i32 1, %rem 614 ret i32 %shl 615} 616 617define <2 x i32> @test38_uniform(<2 x i32> %x) { 618; CHECK-LABEL: @test38_uniform( 619; CHECK-NEXT: [[REM1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 31) 620; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i32> splat (i32 1), [[REM1]] 621; CHECK-NEXT: ret <2 x i32> [[SHL]] 622; 623 %rem = srem <2 x i32> %x, <i32 32, i32 32> 624 %shl = shl <2 x i32> <i32 1, i32 1>, %rem 625 ret <2 x i32> %shl 626} 627 628define <3 x i32> @test38_nonuniform(<3 x i32> %x) { 629; CHECK-LABEL: @test38_nonuniform( 630; CHECK-NEXT: [[REM1:%.*]] = and <3 x i32> [[X:%.*]], <i32 31, i32 15, i32 0> 631; CHECK-NEXT: [[SHL:%.*]] = shl nuw <3 x i32> splat (i32 1), [[REM1]] 632; CHECK-NEXT: ret <3 x i32> [[SHL]] 633; 634 %rem = srem <3 x i32> %x, <i32 32, i32 16, i32 1> 635 %shl = shl <3 x i32> <i32 1, i32 1, i32 1>, %rem 636 ret <3 x i32> %shl 637} 638 639define <2 x i32> @test38_poison(<2 x i32> %x) { 640; CHECK-LABEL: @test38_poison( 641; CHECK-NEXT: ret <2 x i32> poison 642; 643 %rem = srem <2 x i32> %x, <i32 32, i32 poison> 644 %shl = shl <2 x i32> <i32 1, i32 1>, %rem 645 ret <2 x i32> %shl 646} 647 648; <rdar://problem/8756731> 649define i8 @test39(i32 %a0) { 650; CHECK-LABEL: @test39( 651; CHECK-NEXT: entry: 652; CHECK-NEXT: [[I4:%.*]] = trunc i32 [[A0:%.*]] to i8 653; CHECK-NEXT: [[I5:%.*]] = shl i8 [[I4]], 5 654; CHECK-NEXT: [[I49:%.*]] = shl i8 [[I4]], 6 655; CHECK-NEXT: [[I50:%.*]] = and i8 [[I49]], 64 656; CHECK-NEXT: [[I51:%.*]] = xor i8 [[I50]], [[I5]] 657; CHECK-NEXT: [[TMP0:%.*]] = lshr exact i8 [[I5]], 3 658; CHECK-NEXT: [[I54:%.*]] = and i8 [[TMP0]], 16 659; CHECK-NEXT: [[I55:%.*]] = or disjoint i8 [[I54]], [[I51]] 660; CHECK-NEXT: ret i8 [[I55]] 661; 662entry: 663 %i4 = trunc i32 %a0 to i8 664 %i5 = shl i8 %i4, 5 665 %i48 = and i8 %i5, 32 666 %i49 = lshr i8 %i48, 5 667 %i50 = mul i8 %i49, 64 668 %i51 = xor i8 %i50, %i5 669 %i52 = and i8 %i51, -128 670 %i53 = lshr i8 %i52, 7 671 %i54 = mul i8 %i53, 16 672 %i55 = xor i8 %i54, %i51 673 ret i8 %i55 674} 675 676define i32 @test42(i32 %a, i32 %b) { 677; CHECK-LABEL: @test42( 678; CHECK-NEXT: [[TMP1:%.*]] = sub i32 12, [[B:%.*]] 679; CHECK-NEXT: [[DIV2:%.*]] = lshr i32 [[A:%.*]], [[TMP1]] 680; CHECK-NEXT: ret i32 [[DIV2]] 681; 682 %div = lshr i32 4096, %b ; must be exact otherwise we'd divide by zero 683 %div2 = udiv i32 %a, %div 684 ret i32 %div2 685} 686 687define <2 x i32> @test42vec(<2 x i32> %a, <2 x i32> %b) { 688; CHECK-LABEL: @test42vec( 689; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> splat (i32 12), [[B:%.*]] 690; CHECK-NEXT: [[DIV2:%.*]] = lshr <2 x i32> [[A:%.*]], [[TMP1]] 691; CHECK-NEXT: ret <2 x i32> [[DIV2]] 692; 693 %div = lshr <2 x i32> <i32 4096, i32 4096>, %b ; must be exact otherwise we'd divide by zero 694 %div2 = udiv <2 x i32> %a, %div 695 ret <2 x i32> %div2 696} 697 698define i32 @test43(i32 %a, i32 %b) { 699; CHECK-LABEL: @test43( 700; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], 12 701; CHECK-NEXT: [[DIV21:%.*]] = lshr i32 [[A:%.*]], [[TMP1]] 702; CHECK-NEXT: ret i32 [[DIV21]] 703; 704 %div = shl i32 4096, %b ; must be exact otherwise we'd divide by zero 705 %div2 = udiv i32 %a, %div 706 ret i32 %div2 707} 708 709define i32 @test44(i32 %a) { 710; CHECK-LABEL: @test44( 711; CHECK-NEXT: [[Y:%.*]] = shl i32 [[A:%.*]], 5 712; CHECK-NEXT: ret i32 [[Y]] 713; 714 %y = shl nuw i32 %a, 1 715 %z = shl i32 %y, 4 716 ret i32 %z 717} 718 719define i32 @test44_multiuse(i32 %a) { 720; CHECK-LABEL: @test44_multiuse( 721; CHECK-NEXT: [[Y:%.*]] = shl nuw i32 [[A:%.*]], 1 722; CHECK-NEXT: call void @use_i32(i32 [[Y]]) 723; CHECK-NEXT: [[Z:%.*]] = shl i32 [[A]], 5 724; CHECK-NEXT: ret i32 [[Z]] 725; 726 %y = shl nuw i32 %a, 1 727 call void @use_i32(i32 %y) 728 %z = shl i32 %y, 4 729 ret i32 %z 730} 731 732define i32 @test45(i32 %a) { 733; CHECK-LABEL: @test45( 734; CHECK-NEXT: [[Y:%.*]] = lshr i32 [[A:%.*]], 5 735; CHECK-NEXT: ret i32 [[Y]] 736; 737 %y = lshr exact i32 %a, 1 738 %z = lshr i32 %y, 4 739 ret i32 %z 740} 741 742define i32 @test45_multiuse(i32 %a) { 743; CHECK-LABEL: @test45_multiuse( 744; CHECK-NEXT: [[Y:%.*]] = lshr exact i32 [[A:%.*]], 1 745; CHECK-NEXT: call void @use_i32(i32 [[Y]]) 746; CHECK-NEXT: [[Z:%.*]] = lshr i32 [[A]], 5 747; CHECK-NEXT: ret i32 [[Z]] 748; 749 %y = lshr exact i32 %a, 1 750 call void @use_i32(i32 %y) 751 %z = lshr i32 %y, 4 752 ret i32 %z 753} 754 755; (X >>?exact C1) << C2 --> X >>?exact (C1-C2) 756 757define i32 @test46(i32 %a) { 758; CHECK-LABEL: @test46( 759; CHECK-NEXT: [[Z:%.*]] = ashr exact i32 [[A:%.*]], 2 760; CHECK-NEXT: ret i32 [[Z]] 761; 762 %y = ashr exact i32 %a, 3 763 %z = shl i32 %y, 1 764 ret i32 %z 765} 766 767; (X >>?exact C1) << C2 --> X >>?exact (C1-C2) 768 769define <2 x i32> @test46_splat_vec(<2 x i32> %a) { 770; CHECK-LABEL: @test46_splat_vec( 771; CHECK-NEXT: [[Z:%.*]] = ashr exact <2 x i32> [[A:%.*]], splat (i32 2) 772; CHECK-NEXT: ret <2 x i32> [[Z]] 773; 774 %y = ashr exact <2 x i32> %a, <i32 3, i32 3> 775 %z = shl <2 x i32> %y, <i32 1, i32 1> 776 ret <2 x i32> %z 777} 778 779; (X >>?exact C1) << C2 --> X >>?exact (C1-C2) 780 781define i8 @test47(i8 %a) { 782; CHECK-LABEL: @test47( 783; CHECK-NEXT: [[Z:%.*]] = lshr exact i8 [[A:%.*]], 2 784; CHECK-NEXT: ret i8 [[Z]] 785; 786 %y = lshr exact i8 %a, 3 787 %z = shl i8 %y, 1 788 ret i8 %z 789} 790 791; (X >>?exact C1) << C2 --> X >>?exact (C1-C2) 792 793define <2 x i8> @test47_splat_vec(<2 x i8> %a) { 794; CHECK-LABEL: @test47_splat_vec( 795; CHECK-NEXT: [[Z:%.*]] = lshr exact <2 x i8> [[A:%.*]], splat (i8 2) 796; CHECK-NEXT: ret <2 x i8> [[Z]] 797; 798 %y = lshr exact <2 x i8> %a, <i8 3, i8 3> 799 %z = shl <2 x i8> %y, <i8 1, i8 1> 800 ret <2 x i8> %z 801} 802 803; (X >>u,exact C1) << C2 --> X << (C2-C1) when C2 > C1 804 805define i32 @test48(i32 %x) { 806; CHECK-LABEL: @test48( 807; CHECK-NEXT: [[B:%.*]] = shl i32 [[X:%.*]], 2 808; CHECK-NEXT: ret i32 [[B]] 809; 810 %A = lshr exact i32 %x, 1 811 %B = shl i32 %A, 3 812 ret i32 %B 813} 814 815; Verify that wrap flags are preserved from the original 'shl'. 816 817define i32 @test48_nuw_nsw(i32 %x) { 818; CHECK-LABEL: @test48_nuw_nsw( 819; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 [[X:%.*]], 2 820; CHECK-NEXT: ret i32 [[B]] 821; 822 %A = lshr exact i32 %x, 1 823 %B = shl nuw nsw i32 %A, 3 824 ret i32 %B 825} 826 827; (X >>u,exact C1) << C2 --> X << (C2-C1) when splatted C2 > C1 828 829define <2 x i32> @test48_splat_vec(<2 x i32> %x) { 830; CHECK-LABEL: @test48_splat_vec( 831; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[X:%.*]], splat (i32 2) 832; CHECK-NEXT: ret <2 x i32> [[B]] 833; 834 %A = lshr exact <2 x i32> %x, <i32 1, i32 1> 835 %B = shl nsw nuw <2 x i32> %A, <i32 3, i32 3> 836 ret <2 x i32> %B 837} 838 839; (X >>s,exact C1) << C2 --> X << (C2-C1) when C2 > C1 840 841define i32 @test49(i32 %x) { 842; CHECK-LABEL: @test49( 843; CHECK-NEXT: [[B:%.*]] = shl i32 [[X:%.*]], 2 844; CHECK-NEXT: ret i32 [[B]] 845; 846 %A = ashr exact i32 %x, 1 847 %B = shl i32 %A, 3 848 ret i32 %B 849} 850 851; Verify that wrap flags are preserved from the original 'shl'. 852 853define i32 @test49_nuw_nsw(i32 %x) { 854; CHECK-LABEL: @test49_nuw_nsw( 855; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 [[X:%.*]], 2 856; CHECK-NEXT: ret i32 [[B]] 857; 858 %A = ashr exact i32 %x, 1 859 %B = shl nuw nsw i32 %A, 3 860 ret i32 %B 861} 862 863; (X >>s,exact C1) << C2 --> X << (C2-C1) when splatted C2 > C1 864 865define <2 x i32> @test49_splat_vec(<2 x i32> %x) { 866; CHECK-LABEL: @test49_splat_vec( 867; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[X:%.*]], splat (i32 2) 868; CHECK-NEXT: ret <2 x i32> [[B]] 869; 870 %A = ashr exact <2 x i32> %x, <i32 1, i32 1> 871 %B = shl nsw nuw <2 x i32> %A, <i32 3, i32 3> 872 ret <2 x i32> %B 873} 874 875; (X <<nsw C1) >>s C2 --> X >>s (C2-C1) 876 877define i32 @test50(i32 %x) { 878; CHECK-LABEL: @test50( 879; CHECK-NEXT: [[B:%.*]] = ashr i32 [[X:%.*]], 2 880; CHECK-NEXT: ret i32 [[B]] 881; 882 %A = shl nsw i32 %x, 1 883 %B = ashr i32 %A, 3 884 ret i32 %B 885} 886 887; (X <<nsw C1) >>s C2 --> X >>s (C2-C1) 888; Also, check that exact is propagated. 889 890define <2 x i32> @test50_splat_vec(<2 x i32> %x) { 891; CHECK-LABEL: @test50_splat_vec( 892; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i32> [[X:%.*]], splat (i32 2) 893; CHECK-NEXT: ret <2 x i32> [[B]] 894; 895 %A = shl nsw <2 x i32> %x, <i32 1, i32 1> 896 %B = ashr exact <2 x i32> %A, <i32 3, i32 3> 897 ret <2 x i32> %B 898} 899 900; (X <<nuw C1) >>u C2 --> X >>u (C2-C1) 901 902define i32 @test51(i32 %x) { 903; CHECK-LABEL: @test51( 904; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 2 905; CHECK-NEXT: ret i32 [[B]] 906; 907 %A = shl nuw i32 %x, 1 908 %B = lshr i32 %A, 3 909 ret i32 %B 910} 911 912; (X <<nuw C1) >>u C2 --> X >>u (C2-C1) with splats 913; Also, check that exact is propagated. 914 915define <2 x i32> @test51_splat_vec(<2 x i32> %x) { 916; CHECK-LABEL: @test51_splat_vec( 917; CHECK-NEXT: [[B:%.*]] = lshr exact <2 x i32> [[X:%.*]], splat (i32 2) 918; CHECK-NEXT: ret <2 x i32> [[B]] 919; 920 %A = shl nuw <2 x i32> %x, <i32 1, i32 1> 921 %B = lshr exact <2 x i32> %A, <i32 3, i32 3> 922 ret <2 x i32> %B 923} 924 925; (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2) 926; Also, check that exact is propagated. 927 928define i32 @test51_no_nuw(i32 %x) { 929; CHECK-LABEL: @test51_no_nuw( 930; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2 931; CHECK-NEXT: [[B:%.*]] = and i32 [[TMP1]], 536870911 932; CHECK-NEXT: ret i32 [[B]] 933; 934 %A = shl i32 %x, 1 935 %B = lshr exact i32 %A, 3 936 ret i32 %B 937} 938 939; (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2) 940 941define <2 x i32> @test51_no_nuw_splat_vec(<2 x i32> %x) { 942; CHECK-LABEL: @test51_no_nuw_splat_vec( 943; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 2) 944; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[TMP1]], splat (i32 536870911) 945; CHECK-NEXT: ret <2 x i32> [[B]] 946; 947 %A = shl <2 x i32> %x, <i32 1, i32 1> 948 %B = lshr <2 x i32> %A, <i32 3, i32 3> 949 ret <2 x i32> %B 950} 951 952; (X <<nsw C1) >>s C2 --> X <<nsw (C1 - C2) 953 954define i32 @test52(i32 %x) { 955; CHECK-LABEL: @test52( 956; CHECK-NEXT: [[B:%.*]] = shl nsw i32 [[X:%.*]], 2 957; CHECK-NEXT: ret i32 [[B]] 958; 959 %A = shl nsw i32 %x, 3 960 %B = ashr i32 %A, 1 961 ret i32 %B 962} 963 964; (X <<nsw C1) >>s C2 --> X <<nsw (C1 - C2) 965 966define <2 x i32> @test52_splat_vec(<2 x i32> %x) { 967; CHECK-LABEL: @test52_splat_vec( 968; CHECK-NEXT: [[B:%.*]] = shl nsw <2 x i32> [[X:%.*]], splat (i32 2) 969; CHECK-NEXT: ret <2 x i32> [[B]] 970; 971 %A = shl nsw <2 x i32> %x, <i32 3, i32 3> 972 %B = ashr <2 x i32> %A, <i32 1, i32 1> 973 ret <2 x i32> %B 974} 975 976; (X <<nuw C1) >>u C2 --> X <<nuw/nsw (C1 - C2) 977 978define i32 @test53(i32 %x) { 979; CHECK-LABEL: @test53( 980; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 [[X:%.*]], 2 981; CHECK-NEXT: ret i32 [[B]] 982; 983 %A = shl nuw i32 %x, 3 984 %B = lshr i32 %A, 1 985 ret i32 %B 986} 987 988; (X <<nuw C1) >>u C2 --> X <<nuw/nsw (C1 - C2) 989 990define <2 x i32> @test53_splat_vec(<2 x i32> %x) { 991; CHECK-LABEL: @test53_splat_vec( 992; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> [[X:%.*]], splat (i32 2) 993; CHECK-NEXT: ret <2 x i32> [[B]] 994; 995 %A = shl nuw <2 x i32> %x, <i32 3, i32 3> 996 %B = lshr <2 x i32> %A, <i32 1, i32 1> 997 ret <2 x i32> %B 998} 999 1000; (X << C1) >>u C2 --> X << (C1 - C2) & (-1 >> C2) 1001 1002define i8 @test53_no_nuw(i8 %x) { 1003; CHECK-LABEL: @test53_no_nuw( 1004; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 2 1005; CHECK-NEXT: [[B:%.*]] = and i8 [[TMP1]], 124 1006; CHECK-NEXT: ret i8 [[B]] 1007; 1008 %A = shl i8 %x, 3 1009 %B = lshr i8 %A, 1 1010 ret i8 %B 1011} 1012 1013; (X << C1) >>u C2 --> X << (C1 - C2) & (-1 >> C2) 1014 1015define <2 x i8> @test53_no_nuw_splat_vec(<2 x i8> %x) { 1016; CHECK-LABEL: @test53_no_nuw_splat_vec( 1017; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 2) 1018; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[TMP1]], splat (i8 124) 1019; CHECK-NEXT: ret <2 x i8> [[B]] 1020; 1021 %A = shl <2 x i8> %x, <i8 3, i8 3> 1022 %B = lshr <2 x i8> %A, <i8 1, i8 1> 1023 ret <2 x i8> %B 1024} 1025 1026define i32 @test54(i32 %x) { 1027; CHECK-LABEL: @test54( 1028; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3 1029; CHECK-NEXT: [[AND:%.*]] = and i32 [[TMP1]], 16 1030; CHECK-NEXT: ret i32 [[AND]] 1031; 1032 %shr2 = lshr i32 %x, 1 1033 %shl = shl i32 %shr2, 4 1034 %and = and i32 %shl, 16 1035 ret i32 %and 1036} 1037 1038define <2 x i32> @test54_splat_vec(<2 x i32> %x) { 1039; CHECK-LABEL: @test54_splat_vec( 1040; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 3) 1041; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1]], splat (i32 16) 1042; CHECK-NEXT: ret <2 x i32> [[AND]] 1043; 1044 %shr2 = lshr <2 x i32> %x, <i32 1, i32 1> 1045 %shl = shl <2 x i32> %shr2, <i32 4, i32 4> 1046 %and = and <2 x i32> %shl, <i32 16, i32 16> 1047 ret <2 x i32> %and 1048} 1049 1050define i32 @test55(i32 %x) { 1051; CHECK-LABEL: @test55( 1052; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3 1053; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], 8 1054; CHECK-NEXT: ret i32 [[OR]] 1055; 1056 %shr2 = lshr i32 %x, 1 1057 %shl = shl i32 %shr2, 4 1058 %or = or i32 %shl, 8 1059 ret i32 %or 1060} 1061 1062define i32 @test56(i32 %x) { 1063; CHECK-LABEL: @test56( 1064; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3 1065; CHECK-NEXT: [[SHL:%.*]] = and i32 [[TMP1]], -16 1066; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[SHL]], 7 1067; CHECK-NEXT: ret i32 [[OR]] 1068; 1069 %shr2 = lshr i32 %x, 1 1070 %shl = shl i32 %shr2, 4 1071 %or = or i32 %shl, 7 1072 ret i32 %or 1073} 1074 1075define i32 @test57(i32 %x) { 1076; CHECK-LABEL: @test57( 1077; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3 1078; CHECK-NEXT: [[SHL:%.*]] = and i32 [[TMP1]], -16 1079; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[SHL]], 7 1080; CHECK-NEXT: ret i32 [[OR]] 1081; 1082 %shr = ashr i32 %x, 1 1083 %shl = shl i32 %shr, 4 1084 %or = or i32 %shl, 7 1085 ret i32 %or 1086} 1087 1088define i32 @test58(i32 %x) { 1089; CHECK-LABEL: @test58( 1090; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 3 1091; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], 1 1092; CHECK-NEXT: ret i32 [[OR]] 1093; 1094 %shr = ashr i32 %x, 4 1095 %shl = shl i32 %shr, 1 1096 %or = or i32 %shl, 1 1097 ret i32 %or 1098} 1099 1100define <2 x i32> @test58_splat_vec(<2 x i32> %x) { 1101; CHECK-LABEL: @test58_splat_vec( 1102; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 3) 1103; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[TMP1]], splat (i32 1) 1104; CHECK-NEXT: ret <2 x i32> [[OR]] 1105; 1106 %shr = ashr <2 x i32> %x, <i32 4, i32 4> 1107 %shl = shl <2 x i32> %shr, <i32 1, i32 1> 1108 %or = or <2 x i32> %shl, <i32 1, i32 1> 1109 ret <2 x i32> %or 1110} 1111 1112define i32 @test59(i32 %x) { 1113; CHECK-LABEL: @test59( 1114; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 3 1115; CHECK-NEXT: [[SHL:%.*]] = and i32 [[TMP1]], -4 1116; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[SHL]], 2 1117; CHECK-NEXT: ret i32 [[OR]] 1118; 1119 %shr = ashr i32 %x, 4 1120 %shl = shl i32 %shr, 1 1121 %or = or i32 %shl, 2 1122 ret i32 %or 1123} 1124 1125; propagate "exact" trait 1126define i32 @test60(i32 %x) { 1127; CHECK-LABEL: @test60( 1128; CHECK-NEXT: [[SHL:%.*]] = ashr exact i32 [[X:%.*]], 3 1129; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], 1 1130; CHECK-NEXT: ret i32 [[OR]] 1131; 1132 %shr = ashr exact i32 %x, 4 1133 %shl = shl i32 %shr, 1 1134 %or = or i32 %shl, 1 1135 ret i32 %or 1136} 1137 1138; PR17026 1139define void @test61(i128 %arg, i1 %c1, i1 %c2, i1 %c3, i1 %c4) { 1140; CHECK-LABEL: @test61( 1141; CHECK-NEXT: bb: 1142; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB12:%.*]] 1143; CHECK: bb1: 1144; CHECK-NEXT: br label [[BB2:%.*]] 1145; CHECK: bb2: 1146; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB7:%.*]] 1147; CHECK: bb3: 1148; CHECK-NEXT: br label [[BB8:%.*]] 1149; CHECK: bb7: 1150; CHECK-NEXT: br i1 [[C3:%.*]], label [[BB8]], label [[BB2]] 1151; CHECK: bb8: 1152; CHECK-NEXT: br i1 poison, label [[BB11:%.*]], label [[BB12]] 1153; CHECK: bb11: 1154; CHECK-NEXT: br i1 [[C4:%.*]], label [[BB1]], label [[BB12]] 1155; CHECK: bb12: 1156; CHECK-NEXT: ret void 1157; 1158bb: 1159 br i1 %c1, label %bb1, label %bb12 1160 1161bb1: ; preds = %bb11, %bb 1162 br label %bb2 1163 1164bb2: ; preds = %bb7, %bb1 1165 br i1 %c2, label %bb3, label %bb7 1166 1167bb3: ; preds = %bb2 1168 %i = lshr i128 %arg, 36893488147419103232 1169 %i4 = shl i128 %i, 0 1170 %i5 = or i128 %i4, 0 1171 %i6 = trunc i128 %i5 to i16 1172 br label %bb8 1173 1174bb7: ; preds = %bb2 1175 br i1 %c3, label %bb8, label %bb2 1176 1177bb8: ; preds = %bb7, %bb3 1178 %i9 = phi i16 [ %i6, %bb3 ], [ poison, %bb7 ] 1179 %i10 = icmp eq i16 %i9, 0 1180 br i1 %i10, label %bb11, label %bb12 1181 1182bb11: ; preds = %bb8 1183 br i1 %c4, label %bb1, label %bb12 1184 1185bb12: ; preds = %bb11, %bb8, %bb 1186 ret void 1187} 1188 1189define i32 @test62(i32 %a) { 1190; CHECK-LABEL: @test62( 1191; CHECK-NEXT: ret i32 poison 1192; 1193 %b = ashr i32 %a, 32 ; shift all bits out 1194 ret i32 %b 1195} 1196 1197define <4 x i32> @test62_splat_vector(<4 x i32> %a) { 1198; CHECK-LABEL: @test62_splat_vector( 1199; CHECK-NEXT: ret <4 x i32> poison 1200; 1201 %b = ashr <4 x i32> %a, <i32 32, i32 32, i32 32, i32 32> ; shift all bits out 1202 ret <4 x i32> %b 1203} 1204 1205define <4 x i32> @test62_non_splat_vector(<4 x i32> %a) { 1206; CHECK-LABEL: @test62_non_splat_vector( 1207; CHECK-NEXT: [[B:%.*]] = ashr <4 x i32> [[A:%.*]], <i32 32, i32 0, i32 1, i32 2> 1208; CHECK-NEXT: ret <4 x i32> [[B]] 1209; 1210 %b = ashr <4 x i32> %a, <i32 32, i32 0, i32 1, i32 2> ; shift all bits out 1211 ret <4 x i32> %b 1212} 1213 1214define <2 x i65> @test_63(<2 x i64> %t) { 1215; CHECK-LABEL: @test_63( 1216; CHECK-NEXT: [[A:%.*]] = zext <2 x i64> [[T:%.*]] to <2 x i65> 1217; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i65> [[A]], splat (i65 33) 1218; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i65> [[SEXT]], splat (i65 33) 1219; CHECK-NEXT: ret <2 x i65> [[B]] 1220; 1221 %a = zext <2 x i64> %t to <2 x i65> 1222 %sext = shl <2 x i65> %a, <i65 33, i65 33> 1223 %b = ashr <2 x i65> %sext, <i65 33, i65 33> 1224 ret <2 x i65> %b 1225} 1226 1227define i32 @test_shl_zext_bool(i1 %t) { 1228; CHECK-LABEL: @test_shl_zext_bool( 1229; CHECK-NEXT: [[SHL:%.*]] = select i1 [[T:%.*]], i32 4, i32 0 1230; CHECK-NEXT: ret i32 [[SHL]] 1231; 1232 %ext = zext i1 %t to i32 1233 %shl = shl i32 %ext, 2 1234 ret i32 %shl 1235} 1236 1237define <2 x i32> @test_shl_zext_bool_splat(<2 x i1> %t) { 1238; CHECK-LABEL: @test_shl_zext_bool_splat( 1239; CHECK-NEXT: [[SHL:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> splat (i32 8), <2 x i32> zeroinitializer 1240; CHECK-NEXT: ret <2 x i32> [[SHL]] 1241; 1242 %ext = zext <2 x i1> %t to <2 x i32> 1243 %shl = shl <2 x i32> %ext, <i32 3, i32 3> 1244 ret <2 x i32> %shl 1245} 1246 1247define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) { 1248; CHECK-LABEL: @test_shl_zext_bool_vec( 1249; CHECK-NEXT: [[SHL:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer 1250; CHECK-NEXT: ret <2 x i32> [[SHL]] 1251; 1252 %ext = zext <2 x i1> %t to <2 x i32> 1253 %shl = shl <2 x i32> %ext, <i32 2, i32 3> 1254 ret <2 x i32> %shl 1255} 1256 1257define i32 @test_shl_zext_bool_not_constant(i1 %cmp, i32 %shamt) { 1258; CHECK-LABEL: @test_shl_zext_bool_not_constant( 1259; CHECK-NEXT: [[CONV3:%.*]] = zext i1 [[CMP:%.*]] to i32 1260; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 [[CONV3]], [[SHAMT:%.*]] 1261; CHECK-NEXT: ret i32 [[SHL]] 1262; 1263 %conv3 = zext i1 %cmp to i32 1264 %shl = shl i32 %conv3, %shamt 1265 ret i32 %shl 1266} 1267 1268define i64 @shl_zext(i32 %t) { 1269; CHECK-LABEL: @shl_zext( 1270; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[T:%.*]], 8 1271; CHECK-NEXT: [[SHL:%.*]] = zext i32 [[TMP1]] to i64 1272; CHECK-NEXT: ret i64 [[SHL]] 1273; 1274 %and = and i32 %t, 16777215 1275 %ext = zext i32 %and to i64 1276 %shl = shl i64 %ext, 8 1277 ret i64 %shl 1278} 1279 1280define i64 @shl_zext_extra_use(i32 %t) { 1281; CHECK-LABEL: @shl_zext_extra_use( 1282; CHECK-NEXT: [[AND:%.*]] = and i32 [[T:%.*]], 16777215 1283; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[AND]] to i64 1284; CHECK-NEXT: call void @use(i64 [[EXT]]) 1285; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[EXT]], 8 1286; CHECK-NEXT: ret i64 [[SHL]] 1287; 1288 %and = and i32 %t, 16777215 1289 %ext = zext i32 %and to i64 1290 call void @use(i64 %ext) 1291 %shl = shl i64 %ext, 8 1292 ret i64 %shl 1293} 1294 1295define <2 x i64> @shl_zext_splat_vec(<2 x i32> %t) { 1296; CHECK-LABEL: @shl_zext_splat_vec( 1297; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[T:%.*]], splat (i32 8) 1298; CHECK-NEXT: [[SHL:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64> 1299; CHECK-NEXT: ret <2 x i64> [[SHL]] 1300; 1301 %and = and <2 x i32> %t, <i32 16777215, i32 16777215> 1302 %ext = zext <2 x i32> %and to <2 x i64> 1303 %shl = shl <2 x i64> %ext, <i64 8, i64 8> 1304 ret <2 x i64> %shl 1305} 1306 1307define i64 @shl_zext_mul(i32 %t) { 1308; CHECK-LABEL: @shl_zext_mul( 1309; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 16777215 1310; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i64 1311; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[EXT]], 32 1312; CHECK-NEXT: ret i64 [[SHL]] 1313; 1314 %mul = mul i32 %t, 16777215 1315 %ext = zext i32 %mul to i64 1316 %shl = shl i64 %ext, 32 1317 ret i64 %shl 1318} 1319 1320define <3 x i17> @shl_zext_mul_splat(<3 x i5> %t) { 1321; CHECK-LABEL: @shl_zext_mul_splat( 1322; CHECK-NEXT: [[MUL:%.*]] = mul <3 x i5> [[T:%.*]], splat (i5 13) 1323; CHECK-NEXT: [[EXT:%.*]] = zext <3 x i5> [[MUL]] to <3 x i17> 1324; CHECK-NEXT: [[SHL:%.*]] = shl nuw <3 x i17> [[EXT]], splat (i17 12) 1325; CHECK-NEXT: ret <3 x i17> [[SHL]] 1326; 1327 %mul = mul <3 x i5> %t, <i5 13, i5 13, i5 13> 1328 %ext = zext <3 x i5> %mul to <3 x i17> 1329 %shl = shl <3 x i17> %ext, <i17 12, i17 12, i17 12> 1330 ret <3 x i17> %shl 1331} 1332 1333define i64 @shl_zext_mul_low_shift_amount(i32 %t) { 1334; CHECK-LABEL: @shl_zext_mul_low_shift_amount( 1335; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 16777215 1336; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i64 1337; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[EXT]], 31 1338; CHECK-NEXT: ret i64 [[SHL]] 1339; 1340 %mul = mul i32 %t, 16777215 1341 %ext = zext i32 %mul to i64 1342 %shl = shl i64 %ext, 31 1343 ret i64 %shl 1344} 1345 1346define i64 @shl_zext_mul_extra_use1(i32 %t) { 1347; CHECK-LABEL: @shl_zext_mul_extra_use1( 1348; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 16777215 1349; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i64 1350; CHECK-NEXT: call void @use(i64 [[EXT]]) 1351; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[EXT]], 32 1352; CHECK-NEXT: ret i64 [[SHL]] 1353; 1354 %mul = mul i32 %t, 16777215 1355 %ext = zext i32 %mul to i64 1356 call void @use(i64 %ext) 1357 %shl = shl i64 %ext, 32 1358 ret i64 %shl 1359} 1360 1361define i64 @shl_zext_mul_extra_use2(i32 %t) { 1362; CHECK-LABEL: @shl_zext_mul_extra_use2( 1363; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[T:%.*]], 16777215 1364; CHECK-NEXT: call void @use_i32(i32 [[MUL]]) 1365; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[MUL]] to i64 1366; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[EXT]], 32 1367; CHECK-NEXT: ret i64 [[SHL]] 1368; 1369 %mul = mul i32 %t, 16777215 1370 call void @use_i32(i32 %mul) 1371 %ext = zext i32 %mul to i64 1372 %shl = shl i64 %ext, 32 1373 ret i64 %shl 1374} 1375 1376define <2 x i8> @ashr_demanded_bits_splat(<2 x i8> %x) { 1377; CHECK-LABEL: @ashr_demanded_bits_splat( 1378; CHECK-NEXT: [[SHR:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7) 1379; CHECK-NEXT: ret <2 x i8> [[SHR]] 1380; 1381 %and = and <2 x i8> %x, <i8 128, i8 128> 1382 %shr = ashr <2 x i8> %and, <i8 7, i8 7> 1383 ret <2 x i8> %shr 1384} 1385 1386define <vscale x 8 x i8> @ashr_demanded_bits_splat2(<vscale x 8 x i8> %x) { 1387; CHECK-LABEL: @ashr_demanded_bits_splat2( 1388; CHECK-NEXT: [[SHR:%.*]] = ashr <vscale x 8 x i8> [[X:%.*]], splat (i8 7) 1389; CHECK-NEXT: ret <vscale x 8 x i8> [[SHR]] 1390; 1391 %and = and <vscale x 8 x i8> %x, splat (i8 128) 1392 %shr = ashr <vscale x 8 x i8> %and, splat (i8 7) 1393 ret <vscale x 8 x i8> %shr 1394} 1395 1396define <2 x i8> @lshr_demanded_bits_splat(<2 x i8> %x) { 1397; CHECK-LABEL: @lshr_demanded_bits_splat( 1398; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i8> [[X:%.*]], splat (i8 7) 1399; CHECK-NEXT: ret <2 x i8> [[SHR]] 1400; 1401 %and = and <2 x i8> %x, <i8 128, i8 128> 1402 %shr = lshr <2 x i8> %and, <i8 7, i8 7> 1403 ret <2 x i8> %shr 1404} 1405 1406define <vscale x 8 x i8> @lshr_demanded_bits_splat2(<vscale x 8 x i8> %x) { 1407; CHECK-LABEL: @lshr_demanded_bits_splat2( 1408; CHECK-NEXT: [[SHR:%.*]] = lshr <vscale x 8 x i8> [[X:%.*]], splat (i8 7) 1409; CHECK-NEXT: ret <vscale x 8 x i8> [[SHR]] 1410; 1411 %and = and <vscale x 8 x i8> %x, splat (i8 128) 1412 %shr = lshr <vscale x 8 x i8> %and, splat (i8 7) 1413 ret <vscale x 8 x i8> %shr 1414} 1415 1416; Make sure known bits works correctly with non power of 2 bit widths. 1417define i7 @test65(i7 %a, i7 %b) { 1418; CHECK-LABEL: @test65( 1419; CHECK-NEXT: ret i7 0 1420; 1421 %shiftamt = and i7 %b, 6 ; this ensures the shift amount is even and less than the bit width. 1422 %x = lshr i7 42, %shiftamt ; 42 has a zero in every even numbered bit and a one in every odd bit. 1423 %y = and i7 %x, 1 ; this extracts the lsb which should be 0 because we shifted an even number of bits and all even bits of the shift input are 0. 1424 ret i7 %y 1425} 1426 1427define i32 @shl_select_add_true(i32 %x, i1 %cond) { 1428; CHECK-LABEL: @shl_select_add_true( 1429; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1430; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 14 1431; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1432; CHECK-NEXT: ret i32 [[TMP3]] 1433; 1434 %1 = add i32 %x, 7 1435 %2 = select i1 %cond, i32 %1, i32 %x 1436 %3 = shl i32 %2, 1 1437 ret i32 %3 1438} 1439 1440define i32 @shl_select_add_false(i32 %x, i1 %cond) { 1441; CHECK-LABEL: @shl_select_add_false( 1442; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1443; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 14 1444; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1445; CHECK-NEXT: ret i32 [[TMP3]] 1446; 1447 %1 = add i32 %x, 7 1448 %2 = select i1 %cond, i32 %x, i32 %1 1449 %3 = shl i32 %2, 1 1450 ret i32 %3 1451} 1452 1453define i32 @shl_select_and_true(i32 %x, i1 %cond) { 1454; CHECK-LABEL: @shl_select_and_true( 1455; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1456; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 14 1457; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1458; CHECK-NEXT: ret i32 [[TMP3]] 1459; 1460 %1 = and i32 %x, 7 1461 %2 = select i1 %cond, i32 %1, i32 %x 1462 %3 = shl i32 %2, 1 1463 ret i32 %3 1464} 1465 1466define i32 @shl_select_and_false(i32 %x, i1 %cond) { 1467; CHECK-LABEL: @shl_select_and_false( 1468; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1469; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 14 1470; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1471; CHECK-NEXT: ret i32 [[TMP3]] 1472; 1473 %1 = and i32 %x, 7 1474 %2 = select i1 %cond, i32 %x, i32 %1 1475 %3 = shl i32 %2, 1 1476 ret i32 %3 1477} 1478 1479define i32 @lshr_select_and_true(i32 %x, i1 %cond) { 1480; CHECK-LABEL: @lshr_select_and_true( 1481; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1 1482; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 3 1483; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1484; CHECK-NEXT: ret i32 [[TMP3]] 1485; 1486 %1 = and i32 %x, 7 1487 %2 = select i1 %cond, i32 %1, i32 %x 1488 %3 = lshr i32 %2, 1 1489 ret i32 %3 1490} 1491 1492define i32 @lshr_select_and_false(i32 %x, i1 %cond) { 1493; CHECK-LABEL: @lshr_select_and_false( 1494; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1 1495; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 3 1496; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1497; CHECK-NEXT: ret i32 [[TMP3]] 1498; 1499 %1 = and i32 %x, 7 1500 %2 = select i1 %cond, i32 %x, i32 %1 1501 %3 = lshr i32 %2, 1 1502 ret i32 %3 1503} 1504 1505define i32 @ashr_select_and_true(i32 %x, i1 %cond) { 1506; CHECK-LABEL: @ashr_select_and_true( 1507; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1 1508; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -1073741821 1509; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1510; CHECK-NEXT: ret i32 [[TMP3]] 1511; 1512 %1 = and i32 %x, 2147483655 1513 %2 = select i1 %cond, i32 %1, i32 %x 1514 %3 = ashr i32 %2, 1 1515 ret i32 %3 1516} 1517 1518define i32 @ashr_select_and_false(i32 %x, i1 %cond) { 1519; CHECK-LABEL: @ashr_select_and_false( 1520; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1 1521; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -1073741821 1522; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1523; CHECK-NEXT: ret i32 [[TMP3]] 1524; 1525 %1 = and i32 %x, 2147483655 1526 %2 = select i1 %cond, i32 %x, i32 %1 1527 %3 = ashr i32 %2, 1 1528 ret i32 %3 1529} 1530 1531define i32 @shl_select_or_true(i32 %x, i1 %cond) { 1532; CHECK-LABEL: @shl_select_or_true( 1533; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1534; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 14 1535; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1536; CHECK-NEXT: ret i32 [[TMP3]] 1537; 1538 %1 = or i32 %x, 7 1539 %2 = select i1 %cond, i32 %1, i32 %x 1540 %3 = shl i32 %2, 1 1541 ret i32 %3 1542} 1543 1544define i32 @shl_select_or_false(i32 %x, i1 %cond) { 1545; CHECK-LABEL: @shl_select_or_false( 1546; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1547; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 14 1548; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1549; CHECK-NEXT: ret i32 [[TMP3]] 1550; 1551 %1 = or i32 %x, 7 1552 %2 = select i1 %cond, i32 %x, i32 %1 1553 %3 = shl i32 %2, 1 1554 ret i32 %3 1555} 1556 1557define i32 @lshr_select_or_true(i32 %x, i1 %cond) { 1558; CHECK-LABEL: @lshr_select_or_true( 1559; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1 1560; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3 1561; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1562; CHECK-NEXT: ret i32 [[TMP3]] 1563; 1564 %1 = or i32 %x, 7 1565 %2 = select i1 %cond, i32 %1, i32 %x 1566 %3 = lshr i32 %2, 1 1567 ret i32 %3 1568} 1569 1570define i32 @lshr_select_or_false(i32 %x, i1 %cond) { 1571; CHECK-LABEL: @lshr_select_or_false( 1572; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1 1573; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3 1574; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1575; CHECK-NEXT: ret i32 [[TMP3]] 1576; 1577 %1 = or i32 %x, 7 1578 %2 = select i1 %cond, i32 %x, i32 %1 1579 %3 = lshr i32 %2, 1 1580 ret i32 %3 1581} 1582 1583define i32 @ashr_select_or_true(i32 %x, i1 %cond) { 1584; CHECK-LABEL: @ashr_select_or_true( 1585; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1 1586; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3 1587; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1588; CHECK-NEXT: ret i32 [[TMP3]] 1589; 1590 %1 = or i32 %x, 7 1591 %2 = select i1 %cond, i32 %1, i32 %x 1592 %3 = ashr i32 %2, 1 1593 ret i32 %3 1594} 1595 1596define i32 @ashr_select_or_false(i32 %x, i1 %cond) { 1597; CHECK-LABEL: @ashr_select_or_false( 1598; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1 1599; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3 1600; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1601; CHECK-NEXT: ret i32 [[TMP3]] 1602; 1603 %1 = or i32 %x, 7 1604 %2 = select i1 %cond, i32 %x, i32 %1 1605 %3 = ashr i32 %2, 1 1606 ret i32 %3 1607} 1608 1609define i32 @shl_select_xor_true(i32 %x, i1 %cond) { 1610; CHECK-LABEL: @shl_select_xor_true( 1611; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1612; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 14 1613; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1614; CHECK-NEXT: ret i32 [[TMP3]] 1615; 1616 %1 = xor i32 %x, 7 1617 %2 = select i1 %cond, i32 %1, i32 %x 1618 %3 = shl i32 %2, 1 1619 ret i32 %3 1620} 1621 1622define i32 @shl_select_xor_false(i32 %x, i1 %cond) { 1623; CHECK-LABEL: @shl_select_xor_false( 1624; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1 1625; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 14 1626; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1627; CHECK-NEXT: ret i32 [[TMP3]] 1628; 1629 %1 = xor i32 %x, 7 1630 %2 = select i1 %cond, i32 %x, i32 %1 1631 %3 = shl i32 %2, 1 1632 ret i32 %3 1633} 1634 1635define i32 @lshr_select_xor_true(i32 %x, i1 %cond) { 1636; CHECK-LABEL: @lshr_select_xor_true( 1637; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1 1638; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3 1639; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1640; CHECK-NEXT: ret i32 [[TMP3]] 1641; 1642 %1 = xor i32 %x, 7 1643 %2 = select i1 %cond, i32 %1, i32 %x 1644 %3 = lshr i32 %2, 1 1645 ret i32 %3 1646} 1647 1648define i32 @lshr_select_xor_false(i32 %x, i1 %cond) { 1649; CHECK-LABEL: @lshr_select_xor_false( 1650; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1 1651; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3 1652; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1653; CHECK-NEXT: ret i32 [[TMP3]] 1654; 1655 %1 = xor i32 %x, 7 1656 %2 = select i1 %cond, i32 %x, i32 %1 1657 %3 = lshr i32 %2, 1 1658 ret i32 %3 1659} 1660 1661define i32 @ashr_select_xor_true(i32 %x, i1 %cond) { 1662; CHECK-LABEL: @ashr_select_xor_true( 1663; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1 1664; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3 1665; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP2]], i32 [[TMP1]] 1666; CHECK-NEXT: ret i32 [[TMP3]] 1667; 1668 %1 = xor i32 %x, 7 1669 %2 = select i1 %cond, i32 %1, i32 %x 1670 %3 = ashr i32 %2, 1 1671 ret i32 %3 1672} 1673 1674define i32 @ashr_select_xor_false(i32 %x, i1 %cond) { 1675; CHECK-LABEL: @ashr_select_xor_false( 1676; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1 1677; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3 1678; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[TMP2]] 1679; CHECK-NEXT: ret i32 [[TMP3]] 1680; 1681 %1 = xor i32 %x, 7 1682 %2 = select i1 %cond, i32 %x, i32 %1 1683 %3 = ashr i32 %2, 1 1684 ret i32 %3 1685} 1686 1687; OSS Fuzz #4871 1688; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4871 1689define i177 @lshr_out_of_range(i177 %Y, ptr %A2, ptr %ptr) { 1690; CHECK-LABEL: @lshr_out_of_range( 1691; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i177 [[Y:%.*]], -1 1692; CHECK-NEXT: [[B4:%.*]] = sext i1 [[TMP1]] to i177 1693; CHECK-NEXT: [[C8:%.*]] = icmp ugt i177 [[Y]], [[B4]] 1694; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[C8]] to i64 1695; CHECK-NEXT: [[G18:%.*]] = getelementptr ptr, ptr [[A2:%.*]], i64 [[TMP2]] 1696; CHECK-NEXT: store ptr [[G18]], ptr [[PTR:%.*]], align 8 1697; CHECK-NEXT: ret i177 0 1698; 1699 %B5 = udiv i177 %Y, -1 1700 %B4 = add i177 %B5, -1 1701 %B2 = add i177 %B4, -1 1702 %B6 = mul i177 %B5, %B2 1703 %B3 = add i177 %B2, %B2 1704 %B10 = sub i177 %B5, %B3 1705 %B12 = lshr i177 %Y, %B6 1706 %C8 = icmp ugt i177 %B12, %B4 1707 %G18 = getelementptr ptr, ptr %A2, i1 %C8 1708 store ptr %G18, ptr %ptr 1709 %B1 = udiv i177 %B10, %B6 1710 ret i177 %B1 1711} 1712 1713; OSS Fuzz #26716 1714; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26716 1715define i177 @lshr_out_of_range2(i177 %Y, ptr %A2, ptr %ptr) { 1716; CHECK-LABEL: @lshr_out_of_range2( 1717; CHECK-NEXT: [[C8:%.*]] = icmp ne i177 [[Y:%.*]], 0 1718; CHECK-NEXT: [[TMP1:%.*]] = sext i1 [[C8]] to i64 1719; CHECK-NEXT: [[G18:%.*]] = getelementptr ptr, ptr [[A2:%.*]], i64 [[TMP1]] 1720; CHECK-NEXT: store ptr [[G18]], ptr [[PTR:%.*]], align 8 1721; CHECK-NEXT: ret i177 0 1722; 1723 %B5 = udiv i177 %Y, -1 1724 %B = sdiv i177 %B5, -1 1725 %B4 = add i177 %B5, %B 1726 %B2 = add i177 %B4, -1 1727 %B6 = mul i177 %B5, %B2 1728 %B12 = lshr i177 %Y, %B6 1729 %C8 = icmp ugt i177 %B12, %B4 1730 %G18 = getelementptr ptr, ptr %A2, i1 %C8 1731 store ptr %G18, ptr %ptr, align 8 1732 %B1 = udiv i177 %B5, %B6 1733 ret i177 %B1 1734} 1735 1736; The fuzzer-generated @ashr_out_of_range test case does not reach a fixpoint, 1737; because a logical and it not relaxed to a bitwise and in one iteration. 1738 1739; OSS Fuzz #5032 1740; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5032 1741define void @ashr_out_of_range(ptr %A) "instcombine-no-verify-fixpoint" { 1742; CHECK-LABEL: @ashr_out_of_range( 1743; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 4 1744; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L]], -1 1745; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 -1, i64 -2 1746; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP2]] 1747; CHECK-NEXT: [[L7:%.*]] = load i177, ptr [[G11]], align 4 1748; CHECK-NEXT: [[L7_FROZEN:%.*]] = freeze i177 [[L7]] 1749; CHECK-NEXT: [[C171:%.*]] = icmp slt i177 [[L7_FROZEN]], 0 1750; CHECK-NEXT: [[C17:%.*]] = select i1 [[TMP1]], i1 [[C171]], i1 false 1751; CHECK-NEXT: [[TMP3:%.*]] = sext i1 [[C17]] to i64 1752; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP3]] 1753; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i177 [[L7_FROZEN]], -1 1754; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP4]], i177 0, i177 [[L7_FROZEN]] 1755; CHECK-NEXT: store i177 [[B28]], ptr [[G62]], align 4 1756; CHECK-NEXT: ret void 1757; 1758 %L = load i177, ptr %A 1759 %B5 = udiv i177 %L, -1 1760 %B4 = add i177 %B5, -1 1761 %B2 = add i177 %B4, -1 1762 %G11 = getelementptr i177, ptr %A, i177 %B2 1763 %L7 = load i177, ptr %G11 1764 %B6 = mul i177 %B5, %B2 1765 %B24 = ashr i177 %L7, %B6 1766 %B36 = and i177 %L7, %B4 1767 %C17 = icmp sgt i177 %B36, %B24 1768 %G62 = getelementptr i177, ptr %G11, i1 %C17 1769 %B28 = urem i177 %B24, %B6 1770 store i177 %B28, ptr %G62 1771 ret void 1772} 1773 1774; OSS Fuzz #26135 1775; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26135 1776define void @ashr_out_of_range_1(ptr %A) { 1777; CHECK-LABEL: @ashr_out_of_range_1( 1778; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 4 1779; CHECK-NEXT: [[L_FROZEN:%.*]] = freeze i177 [[L]] 1780; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L_FROZEN]], -1 1781; CHECK-NEXT: [[TMP2:%.*]] = trunc i177 [[L_FROZEN]] to i64 1782; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]] 1783; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP3]] 1784; CHECK-NEXT: [[G11:%.*]] = getelementptr i8, ptr [[TMP4]], i64 -24 1785; CHECK-NEXT: [[TMP5:%.*]] = sext i1 [[TMP1]] to i64 1786; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP5]] 1787; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i177 [[L_FROZEN]], -1 1788; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP6]], i177 0, i177 [[L_FROZEN]] 1789; CHECK-NEXT: store i177 [[B28]], ptr [[G62]], align 4 1790; CHECK-NEXT: ret void 1791; 1792 %L = load i177, ptr %A, align 4 1793 %B5 = udiv i177 %L, -1 1794 %B4 = add i177 %B5, -1 1795 %B = and i177 %B4, %L 1796 %B2 = add i177 %B, -1 1797 %G11 = getelementptr i177, ptr %A, i177 %B2 1798 %B6 = mul i177 %B5, %B2 1799 %B24 = ashr i177 %L, %B6 1800 %C17 = icmp sgt i177 %B, %B24 1801 %G62 = getelementptr i177, ptr %G11, i1 %C17 1802 %B28 = urem i177 %B24, %B6 1803 store i177 %B28, ptr %G62, align 4 1804 ret void 1805} 1806 1807; OSS Fuzz #38078 1808; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=38078 1809define void @ossfuzz_38078(i32 %arg, i32 %arg1, ptr %ptr, ptr %ptr2, ptr %ptr3, ptr %ptr4, ptr %ptr5, ptr %ptr6, ptr %ptr7) { 1810; CHECK-LABEL: @ossfuzz_38078( 1811; CHECK-NEXT: bb: 1812; CHECK-NEXT: [[G1:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 -4 1813; CHECK-NEXT: [[I2:%.*]] = sub i32 0, [[ARG1:%.*]] 1814; CHECK-NEXT: [[I5:%.*]] = icmp eq i32 [[ARG:%.*]], [[I2]] 1815; CHECK-NEXT: call void @llvm.assume(i1 [[I5]]) 1816; CHECK-NEXT: store volatile i32 2147483647, ptr [[G1]], align 4 1817; CHECK-NEXT: br label [[BB:%.*]] 1818; CHECK: BB: 1819; CHECK-NEXT: unreachable 1820; 1821bb: 1822 %i = or i32 0, -1 1823 %B24 = urem i32 %i, -2147483648 1824 %B21 = or i32 %i, %i 1825 %i2 = add nsw i32 %arg, %arg1 1826 %B7 = or i32 %i, %i2 1827 %B8 = and i32 %i, %i2 1828 %B12 = sdiv i32 %i2, %B7 1829 %B3 = add i32 %i2, %B24 1830 %B5 = and i32 %i, %B3 1831 %B18 = and i32 %i, %B8 1832 %i3 = xor i32 %i2, %B3 1833 %C1 = icmp ne i32 %B8, %B5 1834 %i4 = lshr i32 %B5, %i3 1835 %B29 = shl nuw i32 %B8, %i3 1836 %B2 = lshr i32 %B12, %i2 1837 %B16 = add i32 %B2, %i3 1838 %B = sdiv i32 %B29, %B5 1839 %B15 = sub i32 %i2, %B5 1840 %B22 = or i32 %B21, %B29 1841 %B23 = mul i32 %B15, %B 1842 %C2 = icmp sge i1 %C1, false 1843 %C7 = icmp sle i32 %i3, %B16 1844 %B20 = xor i32 %B21, %B22 1845 %G1 = getelementptr i32, ptr %ptr, i32 %B22 1846 %B1 = sub i32 %B, 0 1847 %B26 = ashr i32 %B29, 0 1848 %B4 = add i32 0, %B5 1849 %B27 = srem i32 %B12, %B21 1850 %i5 = icmp eq i32 %B20, %B18 1851 %C11 = icmp ugt i32 %i4, %B4 1852 call void @llvm.assume(i1 %i5) 1853 store volatile i32 %B4, ptr %G1, align 4 1854 %B11 = or i32 0, %B23 1855 br label %BB 1856 1857BB: 1858 store i1 %C7, ptr %ptr2, align 1 1859 store i32 %B11, ptr %ptr3, align 4 1860 store i1 %C11, ptr %ptr4, align 1 1861 store i32 %B1, ptr %ptr5, align 4 1862 store i32 %B27, ptr %ptr6, align 4 1863 %C = icmp ne i32 %B26, 0 1864 %B17 = or i1 %C, %C2 1865 store i1 %B17, ptr %ptr7, align 1 1866 unreachable 1867} 1868declare void @llvm.assume(i1 noundef) 1869 1870define i8 @lshr_mask_demand(i8 %x) { 1871; CHECK-LABEL: @lshr_mask_demand( 1872; CHECK-NEXT: [[S:%.*]] = lshr i8 63, [[X:%.*]] 1873; CHECK-NEXT: [[R:%.*]] = and i8 [[S]], 32 1874; CHECK-NEXT: ret i8 [[R]] 1875; 1876 %s = lshr i8 63, %x ; 0b00111111 1877 %r = and i8 %s, 224 ; 0b11100000 1878 ret i8 %r 1879} 1880 1881define i8 @shl_mask_demand(i8 %x) { 1882; CHECK-LABEL: @shl_mask_demand( 1883; CHECK-NEXT: [[S:%.*]] = shl i8 12, [[X:%.*]] 1884; CHECK-NEXT: [[R:%.*]] = and i8 [[S]], 4 1885; CHECK-NEXT: ret i8 [[R]] 1886; 1887 %s = shl i8 12, %x ; 0b00001100 1888 %r = and i8 %s, 7 ; 0b00000111 1889 ret i8 %r 1890} 1891 1892define i64 @lshr_mul_negpow2(i64 %x) { 1893; CHECK-LABEL: @lshr_mul_negpow2( 1894; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[X:%.*]] 1895; CHECK-NEXT: [[A:%.*]] = and i64 [[TMP1]], 4294967295 1896; CHECK-NEXT: ret i64 [[A]] 1897; 1898 %a = mul i64 %x, -4294967296 1899 %b = lshr i64 %a, 32 1900 ret i64 %b 1901} 1902 1903define i64 @lshr_mul_negpow2_2(i64 %x) { 1904; CHECK-LABEL: @lshr_mul_negpow2_2( 1905; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[X:%.*]] 1906; CHECK-NEXT: [[A:%.*]] = and i64 [[TMP1]], 281474976710655 1907; CHECK-NEXT: ret i64 [[A]] 1908; 1909 %a = mul i64 %x, -65536 1910 %b = lshr i64 %a, 16 1911 ret i64 %b 1912} 1913 1914define <2 x i32> @lshr_mul_negpow2_3(<2 x i32> %x) { 1915; CHECK-LABEL: @lshr_mul_negpow2_3( 1916; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]] 1917; CHECK-NEXT: [[A:%.*]] = and <2 x i32> [[TMP1]], splat (i32 255) 1918; CHECK-NEXT: ret <2 x i32> [[A]] 1919; 1920 %a = mul <2 x i32> %x, <i32 -16777216, i32 -16777216> 1921 %b = lshr <2 x i32> %a, <i32 24, i32 24> 1922 ret <2 x i32> %b 1923} 1924 1925define i32 @lshr_mul_negpow2_4(i32 %x) { 1926; CHECK-LABEL: @lshr_mul_negpow2_4( 1927; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[X:%.*]] 1928; CHECK-NEXT: [[A:%.*]] = and i32 [[TMP1]], 65535 1929; CHECK-NEXT: [[B:%.*]] = xor i32 [[A]], 1 1930; CHECK-NEXT: ret i32 [[B]] 1931; 1932 %a = mul i32 %x, -65536 1933 %b = xor i32 %a, 65536 1934 %c = lshr i32 %b, 16 1935 ret i32 %c 1936} 1937 1938define <2 x i32> @lshr_mul_negpow2_5(<2 x i32> %x) { 1939; CHECK-LABEL: @lshr_mul_negpow2_5( 1940; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]] 1941; CHECK-NEXT: [[A:%.*]] = and <2 x i32> [[TMP1]], splat (i32 65527) 1942; CHECK-NEXT: [[B:%.*]] = or disjoint <2 x i32> [[A]], splat (i32 8) 1943; CHECK-NEXT: ret <2 x i32> [[B]] 1944; 1945 %a = mul <2 x i32> %x, <i32 -65536, i32 -65536> 1946 %b = or <2 x i32> %a, <i32 524288, i32 524288> 1947 %c = lshr <2 x i32> %b, <i32 16, i32 16> 1948 ret <2 x i32> %c 1949} 1950 1951define i64 @lshr_mul_negpow2_extra_use(i64 %x) { 1952; CHECK-LABEL: @lshr_mul_negpow2_extra_use( 1953; CHECK-NEXT: [[A:%.*]] = mul i64 [[X:%.*]], -4294967296 1954; CHECK-NEXT: [[B:%.*]] = lshr exact i64 [[A]], 32 1955; CHECK-NEXT: call void @use(i64 [[A]]) 1956; CHECK-NEXT: ret i64 [[B]] 1957; 1958 %a = mul i64 %x, -4294967296 1959 %b = lshr i64 %a, 32 1960 call void @use(i64 %a) 1961 ret i64 %b 1962} 1963 1964define i8 @ashr_sdiv_pos(i8 %x) { 1965; CHECK-LABEL: @ashr_sdiv_pos( 1966; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], -41 1967; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i8 1968; CHECK-NEXT: ret i8 [[R]] 1969; 1970 %d = sdiv i8 %x, 42 1971 %r = ashr i8 %d, 7 1972 ret i8 %r 1973} 1974 1975define <2 x i8> @ashr_sdiv_neg_splat_vec(<2 x i8> %x) { 1976; CHECK-LABEL: @ashr_sdiv_neg_splat_vec( 1977; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 41) 1978; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 1979; CHECK-NEXT: ret <2 x i8> [[R]] 1980; 1981 %d = sdiv <2 x i8> %x, <i8 -42, i8 -42> 1982 %r = ashr <2 x i8> %d, <i8 7, i8 7> 1983 ret <2 x i8> %r 1984} 1985 1986define <2 x i8> @ashr_sdiv_neg_splat_vec_poison(<2 x i8> %x) { 1987; CHECK-LABEL: @ashr_sdiv_neg_splat_vec_poison( 1988; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 127) 1989; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 1990; CHECK-NEXT: ret <2 x i8> [[R]] 1991; 1992 %d = sdiv <2 x i8> %x, <i8 -127, i8 -127> 1993 %r = ashr <2 x i8> %d, <i8 7, i8 poison> 1994 ret <2 x i8> %r 1995} 1996 1997define i8 @lshr_sdiv_pos(i8 %x) { 1998; CHECK-LABEL: @lshr_sdiv_pos( 1999; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], -11 2000; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i8 2001; CHECK-NEXT: ret i8 [[R]] 2002; 2003 %d = sdiv i8 %x, 12 2004 %r = lshr i8 %d, 7 2005 ret i8 %r 2006} 2007 2008define i18 @lshr_sdiv_neg(i18 %x) { 2009; CHECK-LABEL: @lshr_sdiv_neg( 2010; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i18 [[X:%.*]], 11 2011; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i18 2012; CHECK-NEXT: ret i18 [[R]] 2013; 2014 %d = sdiv i18 %x, -12 2015 %r = lshr i18 %d, 17 2016 ret i18 %r 2017} 2018 2019; negative test 2020 2021define i8 @ashr_sdiv_not_full_shift(i8 %x) { 2022; CHECK-LABEL: @ashr_sdiv_not_full_shift( 2023; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], 42 2024; CHECK-NEXT: [[R:%.*]] = ashr i8 [[D]], 6 2025; CHECK-NEXT: ret i8 [[R]] 2026; 2027 %d = sdiv i8 %x, 42 2028 %r = ashr i8 %d, 6 2029 ret i8 %r 2030} 2031 2032; negative test 2033 2034define i32 @ashr_sdiv_extra_use(i32 %x) { 2035; CHECK-LABEL: @ashr_sdiv_extra_use( 2036; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 42 2037; CHECK-NEXT: call void @use_i32(i32 [[D]]) 2038; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], -41 2039; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i32 2040; CHECK-NEXT: ret i32 [[R]] 2041; 2042 %d = sdiv i32 %x, 42 2043 call void @use_i32(i32 %d) 2044 %r = ashr i32 %d, 31 2045 ret i32 %r 2046} 2047 2048define i32 @shl1_cttz(i32 %x) { 2049; CHECK-LABEL: @shl1_cttz( 2050; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]] 2051; CHECK-NEXT: [[SHL:%.*]] = and i32 [[X]], [[NEG]] 2052; CHECK-NEXT: ret i32 [[SHL]] 2053; 2054 %tz = call i32 @llvm.cttz.i32(i32 %x, i1 true) 2055 %shl = shl i32 1, %tz 2056 ret i32 %shl 2057} 2058 2059define <2 x i8> @shl1_cttz_vec(<2 x i8> %x) { 2060; CHECK-LABEL: @shl1_cttz_vec( 2061; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]] 2062; CHECK-NEXT: [[SHL:%.*]] = and <2 x i8> [[X]], [[NEG]] 2063; CHECK-NEXT: ret <2 x i8> [[SHL]] 2064; 2065 %tz = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 false) 2066 %shl = shl <2 x i8> <i8 1, i8 1>, %tz 2067 ret <2 x i8> %shl 2068} 2069 2070define <2 x i8> @shl1_cttz_vec_poison(<2 x i8> %x) { 2071; CHECK-LABEL: @shl1_cttz_vec_poison( 2072; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]] 2073; CHECK-NEXT: [[SHL:%.*]] = and <2 x i8> [[X]], [[NEG]] 2074; CHECK-NEXT: ret <2 x i8> [[SHL]] 2075; 2076 %tz = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 false) 2077 %shl = shl <2 x i8> <i8 1, i8 poison>, %tz 2078 ret <2 x i8> %shl 2079} 2080 2081; negative test - extra use 2082 2083define i32 @shl1_cttz_extra_use(i32 %x) { 2084; CHECK-LABEL: @shl1_cttz_extra_use( 2085; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false) 2086; CHECK-NEXT: call void @use_i32(i32 [[TZ]]) 2087; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[TZ]] 2088; CHECK-NEXT: ret i32 [[SHL]] 2089; 2090 %tz = call i32 @llvm.cttz.i32(i32 %x, i1 false) 2091 call void @use_i32(i32 %tz) 2092 %shl = shl i32 1, %tz 2093 ret i32 %shl 2094} 2095 2096; negative test - must be shift-left of 1 2097 2098define i32 @shl2_cttz(i32 %x) { 2099; CHECK-LABEL: @shl2_cttz( 2100; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true) 2101; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, [[TZ]] 2102; CHECK-NEXT: ret i32 [[SHL]] 2103; 2104 %tz = call i32 @llvm.cttz.i32(i32 %x, i1 true) 2105 %shl = shl i32 2, %tz 2106 ret i32 %shl 2107} 2108 2109; shift (X, amt | bitwidth - 1) -> shift (X, bitwidth - 1) 2110define i6 @shl_or7_eq_shl7(i6 %x, i6 %c) { 2111; CHECK-LABEL: @shl_or7_eq_shl7( 2112; CHECK-NEXT: [[Y:%.*]] = shl nsw i6 [[X:%.*]], 5 2113; CHECK-NEXT: ret i6 [[Y]] 2114; 2115 %amt = or i6 %c, 5 2116 ;; nsw not needed for transform, just check that we propagate. 2117 %y = shl nsw i6 %x, %amt 2118 ret i6 %y 2119} 2120 2121define <2 x i8> @lshr_vec_or7_eq_shl7(<2 x i8> %x, <2 x i8> %c) { 2122; CHECK-LABEL: @lshr_vec_or7_eq_shl7( 2123; CHECK-NEXT: [[Y:%.*]] = lshr exact <2 x i8> [[X:%.*]], splat (i8 7) 2124; CHECK-NEXT: ret <2 x i8> [[Y]] 2125; 2126 %amt = or <2 x i8> %c, <i8 7, i8 7> 2127 ;; exact not needed for transform, just check that we propagate. 2128 %y = lshr exact <2 x i8> %x, %amt 2129 ret <2 x i8> %y 2130} 2131 2132define <2 x i8> @ashr_vec_or7_eq_ashr7(<2 x i8> %x, <2 x i8> %c) { 2133; CHECK-LABEL: @ashr_vec_or7_eq_ashr7( 2134; CHECK-NEXT: [[Y:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7) 2135; CHECK-NEXT: ret <2 x i8> [[Y]] 2136; 2137 %amt = or <2 x i8> %c, <i8 7, i8 7> 2138 %y = ashr <2 x i8> %x, %amt 2139 ret <2 x i8> %y 2140} 2141 2142; Negative test not bitwidth - 1 2143define <2 x i8> @ashr_vec_or6_fail(<2 x i8> %x, <2 x i8> %c) { 2144; CHECK-LABEL: @ashr_vec_or6_fail( 2145; CHECK-NEXT: [[AMT:%.*]] = or <2 x i8> [[C:%.*]], splat (i8 6) 2146; CHECK-NEXT: [[Y:%.*]] = ashr <2 x i8> [[X:%.*]], [[AMT]] 2147; CHECK-NEXT: ret <2 x i8> [[Y]] 2148; 2149 %amt = or <2 x i8> %c, <i8 6, i8 6> 2150 %y = ashr <2 x i8> %x, %amt 2151 ret <2 x i8> %y 2152} 2153 2154define i16 @lshr_and_not_demanded(i8 %x) { 2155; CHECK-LABEL: @lshr_and_not_demanded( 2156; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[X:%.*]] to i16 2157; CHECK-NEXT: [[SHR:%.*]] = lshr i16 [[Y_EXT]], 1 2158; CHECK-NEXT: ret i16 [[SHR]] 2159; 2160 %y = and i8 %x, -2 2161 %y.ext = sext i8 %y to i16 2162 %shr = lshr i16 %y.ext, 1 2163 ret i16 %shr 2164} 2165 2166define i16 @lshr_exact_and_not_demanded(i8 %x) { 2167; CHECK-LABEL: @lshr_exact_and_not_demanded( 2168; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[X:%.*]] to i16 2169; CHECK-NEXT: [[SHR:%.*]] = lshr i16 [[Y_EXT]], 1 2170; CHECK-NEXT: ret i16 [[SHR]] 2171; 2172 %y = and i8 %x, -2 2173 %y.ext = sext i8 %y to i16 2174 %shr = lshr exact i16 %y.ext, 1 2175 ret i16 %shr 2176} 2177 2178define i16 @lshr_and_demanded(i8 %x) { 2179; CHECK-LABEL: @lshr_and_demanded( 2180; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -4 2181; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[Y]] to i16 2182; CHECK-NEXT: [[SHR:%.*]] = lshr exact i16 [[Y_EXT]], 1 2183; CHECK-NEXT: ret i16 [[SHR]] 2184; 2185 %y = and i8 %x, -4 2186 %y.ext = sext i8 %y to i16 2187 %shr = lshr i16 %y.ext, 1 2188 ret i16 %shr 2189} 2190 2191define i16 @ashr_umax_not_demanded(i16 %x) { 2192; CHECK-LABEL: @ashr_umax_not_demanded( 2193; CHECK-NEXT: [[SHR:%.*]] = ashr i16 [[X:%.*]], 1 2194; CHECK-NEXT: ret i16 [[SHR]] 2195; 2196 %y = call i16 @llvm.umax.i16(i16 %x, i16 1) 2197 %shr = ashr i16 %y, 1 2198 ret i16 %shr 2199} 2200 2201define i16 @ashr_exact_umax_not_demanded(i16 %x) { 2202; CHECK-LABEL: @ashr_exact_umax_not_demanded( 2203; CHECK-NEXT: [[SHR:%.*]] = ashr i16 [[X:%.*]], 1 2204; CHECK-NEXT: ret i16 [[SHR]] 2205; 2206 %y = call i16 @llvm.umax.i16(i16 %x, i16 1) 2207 %shr = ashr exact i16 %y, 1 2208 ret i16 %shr 2209} 2210 2211define i16 @ashr_umax_demanded(i16 %x) { 2212; CHECK-LABEL: @ashr_umax_demanded( 2213; CHECK-NEXT: [[Y:%.*]] = call i16 @llvm.umax.i16(i16 [[X:%.*]], i16 2) 2214; CHECK-NEXT: [[SHR:%.*]] = ashr i16 [[Y]], 1 2215; CHECK-NEXT: ret i16 [[SHR]] 2216; 2217 %y = call i16 @llvm.umax.i16(i16 %x, i16 2) 2218 %shr = ashr i16 %y, 1 2219 ret i16 %shr 2220} 2221 2222define i128 @shift_zext_nneg(i8 %arg) { 2223; CHECK-LABEL: @shift_zext_nneg( 2224; CHECK-NEXT: [[EXT:%.*]] = zext nneg i8 [[ARG:%.*]] to i128 2225; CHECK-NEXT: [[SHL:%.*]] = shl nuw i128 1, [[EXT]] 2226; CHECK-NEXT: ret i128 [[SHL]] 2227; 2228 %ext = zext i8 %arg to i128 2229 %shl = shl i128 1, %ext 2230 ret i128 %shl 2231} 2232 2233define i129 @shift_zext_not_nneg(i8 %arg) { 2234; CHECK-LABEL: @shift_zext_not_nneg( 2235; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[ARG:%.*]] to i129 2236; CHECK-NEXT: [[SHL:%.*]] = shl nuw i129 1, [[EXT]] 2237; CHECK-NEXT: ret i129 [[SHL]] 2238; 2239 %ext = zext i8 %arg to i129 2240 %shl = shl i129 1, %ext 2241 ret i129 %shl 2242} 2243 2244define i8 @src_shl_nsw(i8 %x) { 2245; CHECK-LABEL: @src_shl_nsw( 2246; CHECK-NEXT: [[R:%.*]] = shl nsw i8 32, [[X:%.*]] 2247; CHECK-NEXT: ret i8 [[R]] 2248; 2249 %sh = shl nsw i8 1, %x 2250 %r = shl nsw i8 %sh, 5 2251 ret i8 %r 2252} 2253 2254define i8 @src_shl_nsw_fail(i8 %x) { 2255; CHECK-LABEL: @src_shl_nsw_fail( 2256; CHECK-NEXT: [[R:%.*]] = shl i8 32, [[X:%.*]] 2257; CHECK-NEXT: ret i8 [[R]] 2258; 2259 %sh = shl nsw i8 1, %x 2260 %r = shl i8 %sh, 5 2261 ret i8 %r 2262} 2263 2264define i8 @src_shl_nuw(i8 %x) { 2265; CHECK-LABEL: @src_shl_nuw( 2266; CHECK-NEXT: [[R:%.*]] = shl nuw i8 12, [[X:%.*]] 2267; CHECK-NEXT: ret i8 [[R]] 2268; 2269 %sh = shl nuw i8 3, %x 2270 %r = shl nuw i8 %sh, 2 2271 ret i8 %r 2272} 2273 2274define i8 @src_shl_nuw_fail(i8 %x) { 2275; CHECK-LABEL: @src_shl_nuw_fail( 2276; CHECK-NEXT: [[R:%.*]] = shl i8 12, [[X:%.*]] 2277; CHECK-NEXT: ret i8 [[R]] 2278; 2279 %sh = shl i8 3, %x 2280 %r = shl nuw i8 %sh, 2 2281 ret i8 %r 2282} 2283 2284define i8 @src_lshr_exact(i8 %x) { 2285; CHECK-LABEL: @src_lshr_exact( 2286; CHECK-NEXT: [[R:%.*]] = lshr exact i8 48, [[X:%.*]] 2287; CHECK-NEXT: ret i8 [[R]] 2288; 2289 %sh = lshr exact i8 96, %x 2290 %r = lshr exact i8 %sh, 1 2291 ret i8 %r 2292} 2293 2294define i8 @src_lshr_exact_fail(i8 %x) { 2295; CHECK-LABEL: @src_lshr_exact_fail( 2296; CHECK-NEXT: [[R:%.*]] = lshr i8 48, [[X:%.*]] 2297; CHECK-NEXT: ret i8 [[R]] 2298; 2299 %sh = lshr exact i8 96, %x 2300 %r = lshr i8 %sh, 1 2301 ret i8 %r 2302} 2303 2304define i8 @src_ashr_exact(i8 %x) { 2305; CHECK-LABEL: @src_ashr_exact( 2306; CHECK-NEXT: [[R:%.*]] = ashr exact i8 -8, [[X:%.*]] 2307; CHECK-NEXT: ret i8 [[R]] 2308; 2309 %sh = ashr exact i8 -32, %x 2310 %r = ashr exact i8 %sh, 2 2311 ret i8 %r 2312} 2313 2314define i8 @src_ashr_exact_fail(i8 %x) { 2315; CHECK-LABEL: @src_ashr_exact_fail( 2316; CHECK-NEXT: [[R:%.*]] = ashr i8 -8, [[X:%.*]] 2317; CHECK-NEXT: ret i8 [[R]] 2318; 2319 %sh = ashr i8 -32, %x 2320 %r = ashr exact i8 %sh, 2 2321 ret i8 %r 2322} 2323 2324declare i16 @llvm.umax.i16(i16, i16) 2325