2385 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Tests to make sure elimination of casts is working correctly3; RUN: opt < %s -passes=instcombine -S -data-layout="E-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" | FileCheck %s --check-prefixes=ALL,BE4; RUN: opt < %s -passes=instcombine -S -data-layout="e-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" | FileCheck %s --check-prefixes=ALL,LE5; RUN: opt < %s -passes=instcombine -S -data-layout="E-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ALL,BE6; RUN: opt < %s -passes=instcombine -S -data-layout="e-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ALL,LE7 8declare void @use_i8(i8)9declare void @use_i32(i32)10declare void @use_v2i32(<2 x i32>)11 12@inbuf = external global [32832 x i8]13 14define i32 @test1(i32 %A) {15; ALL-LABEL: @test1(16; ALL-NEXT: ret i32 [[A:%.*]]17;18 %c1 = bitcast i32 %A to i3219 %c2 = bitcast i32 %c1 to i3220 ret i32 %c221}22 23define i64 @test2(i8 %A) {24; ALL-LABEL: @test2(25; ALL-NEXT: [[RET:%.*]] = zext i8 [[A:%.*]] to i6426; ALL-NEXT: ret i64 [[RET]]27;28 %c1 = zext i8 %A to i1629 %c2 = zext i16 %c1 to i3230 %Ret = zext i32 %c2 to i6431 ret i64 %Ret32}33 34define i64 @test3(i64 %A) {35; ALL-LABEL: @test3(36; ALL-NEXT: [[C2:%.*]] = and i64 [[A:%.*]], 25537; ALL-NEXT: ret i64 [[C2]]38;39 %c1 = trunc i64 %A to i840 %c2 = zext i8 %c1 to i6441 ret i64 %c242}43 44define i32 @test4(i32 %A, i32 %B) {45; ALL-LABEL: @test4(46; ALL-NEXT: [[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]47; ALL-NEXT: [[RESULT:%.*]] = zext i1 [[COND]] to i3248; ALL-NEXT: ret i32 [[RESULT]]49;50 %COND = icmp slt i32 %A, %B51 %c = zext i1 %COND to i852 %result = zext i8 %c to i3253 ret i32 %result54}55 56define i32 @test5(i1 %B) {57; ALL-LABEL: @test5(58; ALL-NEXT: [[RESULT:%.*]] = zext i1 [[B:%.*]] to i3259; ALL-NEXT: ret i32 [[RESULT]]60;61 %c = zext i1 %B to i862 %result = zext i8 %c to i3263 ret i32 %result64}65 66define i32 @test6(i64 %A) {67; ALL-LABEL: @test6(68; ALL-NEXT: [[C1:%.*]] = trunc i64 [[A:%.*]] to i3269; ALL-NEXT: ret i32 [[C1]]70;71 %c1 = trunc i64 %A to i3272 %res = bitcast i32 %c1 to i3273 ret i32 %res74}75 76define i64 @test7(i1 %A) {77; ALL-LABEL: @test7(78; ALL-NEXT: [[RES:%.*]] = zext i1 [[A:%.*]] to i6479; ALL-NEXT: ret i64 [[RES]]80;81 %c1 = zext i1 %A to i3282 %res = sext i32 %c1 to i6483 ret i64 %res84}85 86define i64 @test8(i8 %A) {87; ALL-LABEL: @test8(88; ALL-NEXT: [[C1:%.*]] = sext i8 [[A:%.*]] to i6489; ALL-NEXT: ret i64 [[C1]]90;91 %c1 = sext i8 %A to i6492 %res = bitcast i64 %c1 to i6493 ret i64 %res94}95 96define i16 @test9(i16 %A) {97; ALL-LABEL: @test9(98; ALL-NEXT: ret i16 [[A:%.*]]99;100 %c1 = sext i16 %A to i32101 %c2 = trunc i32 %c1 to i16102 ret i16 %c2103}104 105define i16 @test10(i16 %A) {106; ALL-LABEL: @test10(107; ALL-NEXT: ret i16 [[A:%.*]]108;109 %c1 = sext i16 %A to i32110 %c2 = trunc i32 %c1 to i16111 ret i16 %c2112}113 114declare void @varargs(i32, ...)115 116define void @test11(ptr %P) {117; ALL-LABEL: @test11(118; ALL-NEXT: call void (i32, ...) @varargs(i32 5, ptr [[P:%.*]])119; ALL-NEXT: ret void120;121 call void (i32, ...) @varargs( i32 5, ptr %P )122 ret void123}124 125declare i32 @__gxx_personality_v0(...)126define void @test_invoke_vararg_cast(ptr %a, ptr %b) personality ptr @__gxx_personality_v0 {127; ALL-LABEL: @test_invoke_vararg_cast(128; ALL-NEXT: entry:129; ALL-NEXT: invoke void (i32, ...) @varargs(i32 1, ptr [[B:%.*]], ptr [[A:%.*]])130; ALL-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]131; ALL: invoke.cont:132; ALL-NEXT: ret void133; ALL: lpad:134; ALL-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 }135; ALL-NEXT: cleanup136; ALL-NEXT: ret void137;138entry:139 invoke void (i32, ...) @varargs(i32 1, ptr %b, ptr %a)140 to label %invoke.cont unwind label %lpad141 142invoke.cont:143 ret void144 145lpad:146 %0 = landingpad { ptr, i32 }147 cleanup148 ret void149}150 151define ptr @test13(i64 %A) {152; ALL-LABEL: @test13(153; ALL-NEXT: [[C:%.*]] = getelementptr i8, ptr @inbuf, i64 [[A:%.*]]154; ALL-NEXT: ret ptr [[C]]155;156 %c = getelementptr [0 x i8], ptr @inbuf, i64 0, i64 %A157 ret ptr %c158}159 160define i1 @test14(i8 %A) {161; ALL-LABEL: @test14(162; ALL-NEXT: [[X:%.*]] = icmp sgt i8 [[A:%.*]], -1163; ALL-NEXT: ret i1 [[X]]164;165 %c = bitcast i8 %A to i8166 %X = icmp ult i8 %c, -128167 ret i1 %X168}169 170 171; This just won't occur when there's no difference between ubyte and sbyte172;bool %test15(ubyte %A) {173; %c = cast ubyte %A to sbyte174; %X = setlt sbyte %c, 0 ; setgt %A, 127175; ret bool %X176;}177 178define i1 @test16(ptr %P) {179; ALL-LABEL: @test16(180; ALL-NEXT: [[C:%.*]] = icmp ne ptr [[P:%.*]], null181; ALL-NEXT: ret i1 [[C]]182;183 %c = icmp ne ptr %P, null184 ret i1 %c185}186 187define i16 @test17(i1 %x) {188; ALL-LABEL: @test17(189; ALL-NEXT: [[T86:%.*]] = zext i1 [[X:%.*]] to i16190; ALL-NEXT: ret i16 [[T86]]191;192 %c = zext i1 %x to i32193 %t86 = trunc i32 %c to i16194 ret i16 %t86195}196 197define i16 @test18(i8 %x) {198; ALL-LABEL: @test18(199; ALL-NEXT: [[T86:%.*]] = sext i8 [[X:%.*]] to i16200; ALL-NEXT: ret i16 [[T86]]201;202 %c = sext i8 %x to i32203 %t86 = trunc i32 %c to i16204 ret i16 %t86205}206 207define i1 @test19(i32 %X) {208; ALL-LABEL: @test19(209; ALL-NEXT: [[Z:%.*]] = icmp slt i32 [[X:%.*]], 12345210; ALL-NEXT: ret i1 [[Z]]211;212 %c = sext i32 %X to i64213 %Z = icmp slt i64 %c, 12345214 ret i1 %Z215}216 217define <2 x i1> @test19vec(<2 x i32> %X) {218; ALL-LABEL: @test19vec(219; ALL-NEXT: [[Z:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 12345, i32 2147483647>220; ALL-NEXT: ret <2 x i1> [[Z]]221;222 %c = sext <2 x i32> %X to <2 x i64>223 %Z = icmp slt <2 x i64> %c, <i64 12345, i64 2147483647>224 ret <2 x i1> %Z225}226 227define <3 x i1> @test19vec2(<3 x i1> %X) {228; ALL-LABEL: @test19vec2(229; ALL-NEXT: [[CMPEQ:%.*]] = xor <3 x i1> [[X:%.*]], splat (i1 true)230; ALL-NEXT: ret <3 x i1> [[CMPEQ]]231;232 %sext = sext <3 x i1> %X to <3 x i32>233 %cmpeq = icmp eq <3 x i32> %sext, zeroinitializer234 ret <3 x i1> %cmpeq235}236 237define i1 @test20(i1 %B) {238; ALL-LABEL: @test20(239; ALL-NEXT: ret i1 false240;241 %c = zext i1 %B to i32242 %D = icmp slt i32 %c, -1243 ret i1 %D244}245 246define i32 @test21(i32 %X) {247; ALL-LABEL: @test21(248; ALL-NEXT: [[SEXT:%.*]] = and i32 [[X:%.*]], 255249; ALL-NEXT: ret i32 [[SEXT]]250;251 %c1 = trunc i32 %X to i8252 %c2 = sext i8 %c1 to i32253 %RV = and i32 %c2, 255254 ret i32 %RV255}256 257define i32 @test22(i32 %X) {258; ALL-LABEL: @test22(259; ALL-NEXT: [[SEXT:%.*]] = shl i32 [[X:%.*]], 24260; ALL-NEXT: ret i32 [[SEXT]]261;262 %c1 = trunc i32 %X to i8263 %c2 = sext i8 %c1 to i32264 %RV = shl i32 %c2, 24265 ret i32 %RV266}267 268define i32 @test23(i32 %X) {269; ALL-LABEL: @test23(270; ALL-NEXT: [[C2:%.*]] = and i32 [[X:%.*]], 65535271; ALL-NEXT: ret i32 [[C2]]272;273 %c1 = trunc i32 %X to i16274 %c2 = zext i16 %c1 to i32275 ret i32 %c2276}277 278define i1 @test24(i1 %C) {279; ALL-LABEL: @test24(280; ALL-NEXT: ret i1 true281;282 %X = select i1 %C, i32 14, i32 1234283 %c = icmp ne i32 %X, 0284 ret i1 %c285}286 287define i32 @test26(float %F) {288; ALL-LABEL: @test26(289; ALL-NEXT: [[D:%.*]] = fptosi float [[F:%.*]] to i32290; ALL-NEXT: ret i32 [[D]]291;292 %c = fpext float %F to double293 %D = fptosi double %c to i32294 ret i32 %D295}296 297define ptr @test27(ptr %A) {298; ALL-LABEL: @test27(299; ALL-NEXT: ret ptr [[A:%.*]]300;301 ret ptr %A302}303 304define ptr @test28(ptr %A) {305; ALL-LABEL: @test28(306; ALL-NEXT: ret ptr [[A:%.*]]307;308 ret ptr %A309}310 311define i32 @test29(i32 %c1, i32 %c2) {312; ALL-LABEL: @test29(313; ALL-NEXT: [[T21:%.*]] = or i32 [[C2:%.*]], [[C1:%.*]]314; ALL-NEXT: [[T10:%.*]] = and i32 [[T21]], 255315; ALL-NEXT: ret i32 [[T10]]316;317 %t1 = trunc i32 %c1 to i8318 %tmask = trunc i32 %c2 to i8319 %t2 = or i8 %tmask, %t1320 %t10 = zext i8 %t2 to i32321 ret i32 %t10322}323 324define i32 @test30(i32 %c1) {325; ALL-LABEL: @test30(326; ALL-NEXT: [[C3:%.*]] = and i32 [[C1:%.*]], 255327; ALL-NEXT: [[C4:%.*]] = xor i32 [[C3]], 1328; ALL-NEXT: ret i32 [[C4]]329;330 %c2 = trunc i32 %c1 to i8331 %c3 = xor i8 %c2, 1332 %c4 = zext i8 %c3 to i32333 ret i32 %c4334}335 336define i1 @test31(i64 %A) {337; ALL-LABEL: @test31(338; ALL-NEXT: [[C1:%.*]] = and i64 [[A:%.*]], 42339; ALL-NEXT: [[D:%.*]] = icmp eq i64 [[C1]], 10340; ALL-NEXT: ret i1 [[D]]341;342 %B = trunc i64 %A to i32343 %C = and i32 %B, 42344 %D = icmp eq i32 %C, 10345 ret i1 %D346}347 348; FIXME: Vectors should fold too...or not?349; Does this depend on the whether the source/dest types of the trunc are legal in the data layout?350define <2 x i1> @test31vec(<2 x i64> %A) {351; ALL-LABEL: @test31vec(352; ALL-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>353; ALL-NEXT: [[C:%.*]] = and <2 x i32> [[B]], splat (i32 42)354; ALL-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[C]], splat (i32 10)355; ALL-NEXT: ret <2 x i1> [[D]]356;357 %B = trunc <2 x i64> %A to <2 x i32>358 %C = and <2 x i32> %B, <i32 42, i32 42>359 %D = icmp eq <2 x i32> %C, <i32 10, i32 10>360 ret <2 x i1> %D361}362 363; Verify that the 'and' was narrowed, the zext was eliminated, and the compare was narrowed364; even for vectors. Earlier folds should ensure that the icmp(and(zext)) pattern never occurs.365 366define <2 x i1> @test32vec(<2 x i8> %A) {367; ALL-LABEL: @test32vec(368; ALL-NEXT: [[TMP1:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 42)369; ALL-NEXT: [[D:%.*]] = icmp eq <2 x i8> [[TMP1]], splat (i8 10)370; ALL-NEXT: ret <2 x i1> [[D]]371;372 %B = zext <2 x i8> %A to <2 x i16>373 %C = and <2 x i16> %B, <i16 42, i16 42>374 %D = icmp eq <2 x i16> %C, <i16 10, i16 10>375 ret <2 x i1> %D376}377 378define i32 @test33(i32 %c1) {379; ALL-LABEL: @test33(380; ALL-NEXT: ret i32 [[C1:%.*]]381;382 %x = bitcast i32 %c1 to float383 %y = bitcast float %x to i32384 ret i32 %y385}386 387define i16 @test34(i16 %a) {388; ALL-LABEL: @test34(389; ALL-NEXT: [[TMP1:%.*]] = lshr i16 [[A:%.*]], 8390; ALL-NEXT: ret i16 [[TMP1]]391;392 %c1 = zext i16 %a to i32393 %t21 = lshr i32 %c1, 8394 %c2 = trunc i32 %t21 to i16395 ret i16 %c2396}397 398define i16 @test35(i16 %a) {399; ALL-LABEL: @test35(400; ALL-NEXT: [[T2:%.*]] = lshr i16 [[A:%.*]], 8401; ALL-NEXT: ret i16 [[T2]]402;403 %c1 = bitcast i16 %a to i16404 %t2 = lshr i16 %c1, 8405 %c2 = bitcast i16 %t2 to i16406 ret i16 %c2407}408 409; rdar://6480391410define i1 @test36(i32 %a) {411; ALL-LABEL: @test36(412; ALL-NEXT: [[D:%.*]] = icmp sgt i32 [[A:%.*]], -1413; ALL-NEXT: ret i1 [[D]]414;415 %b = lshr i32 %a, 31416 %c = trunc i32 %b to i8417 %d = icmp eq i8 %c, 0418 ret i1 %d419}420 421define <2 x i1> @test36vec(<2 x i32> %a) {422; ALL-LABEL: @test36vec(423; ALL-NEXT: [[D:%.*]] = icmp sgt <2 x i32> [[A:%.*]], splat (i32 -1)424; ALL-NEXT: ret <2 x i1> [[D]]425;426 %b = lshr <2 x i32> %a, <i32 31, i32 31>427 %c = trunc <2 x i32> %b to <2 x i8>428 %d = icmp eq <2 x i8> %c, zeroinitializer429 ret <2 x i1> %d430}431 432define i1 @test37(i32 %a) {433; ALL-LABEL: @test37(434; ALL-NEXT: ret i1 false435;436 %b = lshr i32 %a, 31437 %c = or i32 %b, 512438 %d = trunc i32 %c to i8439 %e = icmp eq i8 %d, 11440 ret i1 %e441}442 443define i64 @test38(i32 %a) {444; ALL-LABEL: @test38(445; ALL-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], -2446; ALL-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i64447; ALL-NEXT: ret i64 [[TMP2]]448;449 %1 = icmp eq i32 %a, -2450 %2 = zext i1 %1 to i8451 %3 = xor i8 %2, 1452 %4 = zext i8 %3 to i64453 ret i64 %4454}455 456define i16 @test39(i16 %a) {457; ALL-LABEL: @test39(458; ALL-NEXT: [[T32:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])459; ALL-NEXT: ret i16 [[T32]]460;461 %t = zext i16 %a to i32462 %t21 = lshr i32 %t, 8463 %t5 = shl i32 %t, 8464 %t32 = or i32 %t21, %t5465 %r = trunc i32 %t32 to i16466 ret i16 %r467}468 469define i16 @test40(i16 %a) {470; ALL-LABEL: @test40(471; ALL-NEXT: [[T21:%.*]] = lshr i16 [[A:%.*]], 9472; ALL-NEXT: [[T5:%.*]] = shl i16 [[A]], 8473; ALL-NEXT: [[T32:%.*]] = or disjoint i16 [[T21]], [[T5]]474; ALL-NEXT: ret i16 [[T32]]475;476 %t = zext i16 %a to i32477 %t21 = lshr i32 %t, 9478 %t5 = shl i32 %t, 8479 %t32 = or i32 %t21, %t5480 %r = trunc i32 %t32 to i16481 ret i16 %r482}483 484define <2 x i16> @test40vec(<2 x i16> %a) {485; ALL-LABEL: @test40vec(486; ALL-NEXT: [[T21:%.*]] = lshr <2 x i16> [[A:%.*]], splat (i16 9)487; ALL-NEXT: [[T5:%.*]] = shl <2 x i16> [[A]], splat (i16 8)488; ALL-NEXT: [[T32:%.*]] = or disjoint <2 x i16> [[T21]], [[T5]]489; ALL-NEXT: ret <2 x i16> [[T32]]490;491 %t = zext <2 x i16> %a to <2 x i32>492 %t21 = lshr <2 x i32> %t, <i32 9, i32 9>493 %t5 = shl <2 x i32> %t, <i32 8, i32 8>494 %t32 = or <2 x i32> %t21, %t5495 %r = trunc <2 x i32> %t32 to <2 x i16>496 ret <2 x i16> %r497}498 499define <2 x i16> @test40vec_nonuniform(<2 x i16> %a) {500; ALL-LABEL: @test40vec_nonuniform(501; ALL-NEXT: [[T21:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 9, i16 10>502; ALL-NEXT: [[T5:%.*]] = shl <2 x i16> [[A]], <i16 8, i16 9>503; ALL-NEXT: [[T32:%.*]] = or disjoint <2 x i16> [[T21]], [[T5]]504; ALL-NEXT: ret <2 x i16> [[T32]]505;506 %t = zext <2 x i16> %a to <2 x i32>507 %t21 = lshr <2 x i32> %t, <i32 9, i32 10>508 %t5 = shl <2 x i32> %t, <i32 8, i32 9>509 %t32 = or <2 x i32> %t21, %t5510 %r = trunc <2 x i32> %t32 to <2 x i16>511 ret <2 x i16> %r512}513 514define <2 x i16> @test40vec_poison(<2 x i16> %a) {515; ALL-LABEL: @test40vec_poison(516; ALL-NEXT: [[T21:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 9, i16 poison>517; ALL-NEXT: [[T5:%.*]] = shl <2 x i16> [[A]], <i16 8, i16 poison>518; ALL-NEXT: [[T32:%.*]] = or disjoint <2 x i16> [[T21]], [[T5]]519; ALL-NEXT: ret <2 x i16> [[T32]]520;521 %t = zext <2 x i16> %a to <2 x i32>522 %t21 = lshr <2 x i32> %t, <i32 9, i32 poison>523 %t5 = shl <2 x i32> %t, <i32 8, i32 poison>524 %t32 = or <2 x i32> %t21, %t5525 %r = trunc <2 x i32> %t32 to <2 x i16>526 ret <2 x i16> %r527}528 529; PR1263530define ptr @test41(ptr %t1) {531; ALL-LABEL: @test41(532; ALL-NEXT: ret ptr [[T1:%.*]]533;534 ret ptr %t1535}536 537define ptr addrspace(1) @test41_addrspacecast_smaller(ptr %t1) {538; ALL-LABEL: @test41_addrspacecast_smaller(539; ALL-NEXT: [[T64:%.*]] = addrspacecast ptr [[T1:%.*]] to ptr addrspace(1)540; ALL-NEXT: ret ptr addrspace(1) [[T64]]541;542 %t64 = addrspacecast ptr %t1 to ptr addrspace(1)543 ret ptr addrspace(1) %t64544}545 546define ptr @test41_addrspacecast_larger(ptr addrspace(1) %t1) {547; ALL-LABEL: @test41_addrspacecast_larger(548; ALL-NEXT: [[T64:%.*]] = addrspacecast ptr addrspace(1) [[T1:%.*]] to ptr549; ALL-NEXT: ret ptr [[T64]]550;551 %t64 = addrspacecast ptr addrspace(1) %t1 to ptr552 ret ptr %t64553}554 555define i32 @test42(i32 %X) {556; ALL-LABEL: @test42(557; ALL-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255558; ALL-NEXT: ret i32 [[Z]]559;560 %Y = trunc i32 %X to i8561 %Z = zext i8 %Y to i32562 ret i32 %Z563}564 565; rdar://6598839566define zeroext i64 @test43(i8 zeroext %on_off) {567; ALL-LABEL: @test43(568; ALL-NEXT: [[A:%.*]] = zext i8 [[ON_OFF:%.*]] to i64569; ALL-NEXT: [[B:%.*]] = add nsw i64 [[A]], -1570; ALL-NEXT: ret i64 [[B]]571;572 %A = zext i8 %on_off to i32573 %B = add i32 %A, -1574 %C = sext i32 %B to i64575 ret i64 %C ;; Should be (add (zext i8 -> i64), -1)576}577 578define i64 @test44(i8 %T) {579; ALL-LABEL: @test44(580; ALL-NEXT: [[A:%.*]] = zext i8 [[T:%.*]] to i64581; ALL-NEXT: [[B:%.*]] = or i64 [[A]], 1234582; ALL-NEXT: ret i64 [[B]]583;584 %A = zext i8 %T to i16585 %B = or i16 %A, 1234586 %C = zext i16 %B to i64587 ret i64 %C588}589 590define i64 @test45(i8 %A, i64 %Q) {591; ALL-LABEL: @test45(592; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i64593; ALL-NEXT: [[C:%.*]] = or i64 [[Q:%.*]], [[B]]594; ALL-NEXT: [[E:%.*]] = and i64 [[C]], 4294967295595; ALL-NEXT: ret i64 [[E]]596;597 %D = trunc i64 %Q to i32 ;; should be removed598 %B = sext i8 %A to i32599 %C = or i32 %B, %D600 %E = zext i32 %C to i64601 ret i64 %E602}603 604 605define i64 @test46(i64 %A) {606; ALL-LABEL: @test46(607; ALL-NEXT: [[C:%.*]] = shl i64 [[A:%.*]], 8608; ALL-NEXT: [[D:%.*]] = and i64 [[C]], 10752609; ALL-NEXT: ret i64 [[D]]610;611 %B = trunc i64 %A to i32612 %C = and i32 %B, 42613 %D = shl i32 %C, 8614 %E = zext i32 %D to i64615 ret i64 %E616}617 618define <2 x i64> @test46vec(<2 x i64> %A) {619; ALL-LABEL: @test46vec(620; ALL-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>621; ALL-NEXT: [[C:%.*]] = shl <2 x i32> [[B]], splat (i32 8)622; ALL-NEXT: [[D:%.*]] = and <2 x i32> [[C]], splat (i32 10752)623; ALL-NEXT: [[E:%.*]] = zext nneg <2 x i32> [[D]] to <2 x i64>624; ALL-NEXT: ret <2 x i64> [[E]]625;626 %B = trunc <2 x i64> %A to <2 x i32>627 %C = and <2 x i32> %B, <i32 42, i32 42>628 %D = shl <2 x i32> %C, <i32 8, i32 8>629 %E = zext <2 x i32> %D to <2 x i64>630 ret <2 x i64> %E631}632 633define i64 @test47(i8 %A) {634; ALL-LABEL: @test47(635; ALL-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], 42636; ALL-NEXT: [[C:%.*]] = sext i8 [[TMP1]] to i64637; ALL-NEXT: [[E:%.*]] = and i64 [[C]], 4294967295638; ALL-NEXT: ret i64 [[E]]639;640 %B = sext i8 %A to i32641 %C = or i32 %B, 42642 %E = zext i32 %C to i64643 ret i64 %E644}645 646define i64 @test48(i8 %A1, i8 %a2) {647; ALL-LABEL: @test48(648; ALL-NEXT: [[Z2:%.*]] = zext i8 [[A1:%.*]] to i32649; ALL-NEXT: [[C:%.*]] = shl nuw nsw i32 [[Z2]], 8650; ALL-NEXT: [[D:%.*]] = or disjoint i32 [[C]], [[Z2]]651; ALL-NEXT: [[E:%.*]] = zext nneg i32 [[D]] to i64652; ALL-NEXT: ret i64 [[E]]653;654 %Z1 = zext i8 %a2 to i32655 %Z2 = zext i8 %A1 to i32656 %C = shl i32 %Z2, 8657 %D = or i32 %C, %Z2658 %E = zext i32 %D to i64659 ret i64 %E660}661 662define i64 @test49(i64 %A) {663; ALL-LABEL: @test49(664; ALL-NEXT: [[C:%.*]] = shl i64 [[A:%.*]], 32665; ALL-NEXT: [[SEXT:%.*]] = ashr exact i64 [[C]], 32666; ALL-NEXT: [[D:%.*]] = or i64 [[SEXT]], 1667; ALL-NEXT: ret i64 [[D]]668;669 %B = trunc i64 %A to i32670 %C = or i32 %B, 1671 %D = sext i32 %C to i64672 ret i64 %D673}674 675define i64 @test50(i64 %x) {676; ALL-LABEL: @test50(677; ALL-NEXT: [[TMP1:%.*]] = shl i64 [[X:%.*]], 30678; ALL-NEXT: [[SEXT:%.*]] = add i64 [[TMP1]], -4294967296679; ALL-NEXT: [[E:%.*]] = ashr i64 [[SEXT]], 32680; ALL-NEXT: ret i64 [[E]]681;682 %a = lshr i64 %x, 2683 %B = trunc i64 %a to i32684 %D = add i32 %B, -1685 %E = sext i32 %D to i64686 ret i64 %E687}688 689define i64 @test51(i64 %A, i1 %cond) {690; ALL-LABEL: @test51(691; ALL-NEXT: [[C:%.*]] = and i64 [[A:%.*]], 4294967294692; ALL-NEXT: [[NOT_COND:%.*]] = xor i1 [[COND:%.*]], true693; ALL-NEXT: [[MASKSEL:%.*]] = zext i1 [[NOT_COND]] to i64694; ALL-NEXT: [[E:%.*]] = or disjoint i64 [[C]], [[MASKSEL]]695; ALL-NEXT: [[SEXT:%.*]] = shl nuw i64 [[E]], 32696; ALL-NEXT: [[F:%.*]] = ashr exact i64 [[SEXT]], 32697; ALL-NEXT: ret i64 [[F]]698;699 %B = trunc i64 %A to i32700 %C = and i32 %B, -2701 %D = or i32 %B, 1702 %E = select i1 %cond, i32 %C, i32 %D703 %F = sext i32 %E to i64704 ret i64 %F705}706 707define i32 @test52(i64 %A) {708; ALL-LABEL: @test52(709; ALL-NEXT: [[B:%.*]] = trunc i64 [[A:%.*]] to i32710; ALL-NEXT: [[C:%.*]] = and i32 [[B]], 7224711; ALL-NEXT: [[D:%.*]] = or disjoint i32 [[C]], 32962712; ALL-NEXT: ret i32 [[D]]713;714 %B = trunc i64 %A to i16715 %C = or i16 %B, -32574716 %D = and i16 %C, -25350717 %E = zext i16 %D to i32718 ret i32 %E719}720 721define i64 @test53(i32 %A) {722; ALL-LABEL: @test53(723; ALL-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 7224724; ALL-NEXT: [[TMP2:%.*]] = or disjoint i32 [[TMP1]], 32962725; ALL-NEXT: [[D:%.*]] = zext nneg i32 [[TMP2]] to i64726; ALL-NEXT: ret i64 [[D]]727;728 %B = trunc i32 %A to i16729 %C = or i16 %B, -32574730 %D = and i16 %C, -25350731 %E = zext i16 %D to i64732 ret i64 %E733}734 735define i32 @test54(i64 %A) {736; ALL-LABEL: @test54(737; ALL-NEXT: [[B:%.*]] = trunc i64 [[A:%.*]] to i32738; ALL-NEXT: [[C:%.*]] = and i32 [[B]], 7224739; ALL-NEXT: [[D:%.*]] = or disjoint i32 [[C]], -32574740; ALL-NEXT: ret i32 [[D]]741;742 %B = trunc i64 %A to i16743 %C = or i16 %B, -32574744 %D = and i16 %C, -25350745 %E = sext i16 %D to i32746 ret i32 %E747}748 749define i64 @test55(i32 %A) {750; ALL-LABEL: @test55(751; ALL-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 7224752; ALL-NEXT: [[TMP2:%.*]] = or disjoint i32 [[TMP1]], -32574753; ALL-NEXT: [[D:%.*]] = sext i32 [[TMP2]] to i64754; ALL-NEXT: ret i64 [[D]]755;756 %B = trunc i32 %A to i16757 %C = or i16 %B, -32574758 %D = and i16 %C, -25350759 %E = sext i16 %D to i64760 ret i64 %E761}762 763define i64 @test56(i16 %A) {764; ALL-LABEL: @test56(765; ALL-NEXT: [[P353:%.*]] = sext i16 [[A:%.*]] to i64766; ALL-NEXT: [[P354:%.*]] = lshr i64 [[P353]], 5767; ALL-NEXT: [[P355:%.*]] = and i64 [[P354]], 134217727768; ALL-NEXT: ret i64 [[P355]]769;770 %p353 = sext i16 %A to i32771 %p354 = lshr i32 %p353, 5772 %p355 = zext i32 %p354 to i64773 ret i64 %p355774}775 776define <2 x i64> @test56vec(<2 x i16> %A) {777; ALL-LABEL: @test56vec(778; ALL-NEXT: [[P353:%.*]] = sext <2 x i16> [[A:%.*]] to <2 x i32>779; ALL-NEXT: [[P354:%.*]] = lshr <2 x i32> [[P353]], splat (i32 5)780; ALL-NEXT: [[P355:%.*]] = zext nneg <2 x i32> [[P354]] to <2 x i64>781; ALL-NEXT: ret <2 x i64> [[P355]]782;783 %p353 = sext <2 x i16> %A to <2 x i32>784 %p354 = lshr <2 x i32> %p353, <i32 5, i32 5>785 %p355 = zext <2 x i32> %p354 to <2 x i64>786 ret <2 x i64> %p355787}788 789define i64 @test57(i64 %A) {790; ALL-LABEL: @test57(791; ALL-NEXT: [[C:%.*]] = lshr i64 [[A:%.*]], 8792; ALL-NEXT: [[E:%.*]] = and i64 [[C]], 16777215793; ALL-NEXT: ret i64 [[E]]794;795 %B = trunc i64 %A to i32796 %C = lshr i32 %B, 8797 %E = zext i32 %C to i64798 ret i64 %E799}800 801define <2 x i64> @test57vec(<2 x i64> %A) {802; ALL-LABEL: @test57vec(803; ALL-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>804; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 8)805; ALL-NEXT: [[E:%.*]] = zext nneg <2 x i32> [[C]] to <2 x i64>806; ALL-NEXT: ret <2 x i64> [[E]]807;808 %B = trunc <2 x i64> %A to <2 x i32>809 %C = lshr <2 x i32> %B, <i32 8, i32 8>810 %E = zext <2 x i32> %C to <2 x i64>811 ret <2 x i64> %E812}813 814define i64 @test58(i64 %A) {815; ALL-LABEL: @test58(816; ALL-NEXT: [[C:%.*]] = lshr i64 [[A:%.*]], 8817; ALL-NEXT: [[D:%.*]] = and i64 [[C]], 16777087818; ALL-NEXT: [[E:%.*]] = or disjoint i64 [[D]], 128819; ALL-NEXT: ret i64 [[E]]820;821 %B = trunc i64 %A to i32822 %C = lshr i32 %B, 8823 %D = or i32 %C, 128824 %E = zext i32 %D to i64825 ret i64 %E826 827}828 829define i64 @test59(i8 %A, i8 %B) {830; ALL-LABEL: @test59(831; ALL-NEXT: [[C:%.*]] = zext i8 [[A:%.*]] to i64832; ALL-NEXT: [[D:%.*]] = shl nuw nsw i64 [[C]], 4833; ALL-NEXT: [[E:%.*]] = and i64 [[D]], 48834; ALL-NEXT: [[TMP1:%.*]] = lshr i8 [[B:%.*]], 4835; ALL-NEXT: [[G:%.*]] = zext nneg i8 [[TMP1]] to i64836; ALL-NEXT: [[H:%.*]] = or disjoint i64 [[E]], [[G]]837; ALL-NEXT: ret i64 [[H]]838;839 %C = zext i8 %A to i32840 %D = shl i32 %C, 4841 %E = and i32 %D, 48842 %F = zext i8 %B to i32843 %G = lshr i32 %F, 4844 %H = or i32 %G, %E845 %I = zext i32 %H to i64846 ret i64 %I847}848 849define <3 x i32> @test60(<4 x i32> %call4) {850; BE-LABEL: @test60(851; BE-NEXT: [[P10:%.*]] = shufflevector <4 x i32> [[CALL4:%.*]], <4 x i32> poison, <3 x i32> <i32 1, i32 2, i32 3>852; BE-NEXT: ret <3 x i32> [[P10]]853;854; LE-LABEL: @test60(855; LE-NEXT: [[P10:%.*]] = shufflevector <4 x i32> [[CALL4:%.*]], <4 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2>856; LE-NEXT: ret <3 x i32> [[P10]]857;858 %p11 = bitcast <4 x i32> %call4 to i128859 %p9 = trunc i128 %p11 to i96860 %p10 = bitcast i96 %p9 to <3 x i32>861 ret <3 x i32> %p10862 863}864 865define <4 x i32> @test61(<3 x i32> %call4) {866; BE-LABEL: @test61(867; BE-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[CALL4:%.*]], <3 x i32> <i32 0, i32 poison, i32 poison>, <4 x i32> <i32 3, i32 0, i32 1, i32 2>868; BE-NEXT: ret <4 x i32> [[P10]]869;870; LE-LABEL: @test61(871; LE-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[CALL4:%.*]], <3 x i32> <i32 0, i32 poison, i32 poison>, <4 x i32> <i32 0, i32 1, i32 2, i32 3>872; LE-NEXT: ret <4 x i32> [[P10]]873;874 %p11 = bitcast <3 x i32> %call4 to i96875 %p9 = zext i96 %p11 to i128876 %p10 = bitcast i128 %p9 to <4 x i32>877 ret <4 x i32> %p10878}879 880define <4 x i32> @test62(<3 x float> %call4) {881; BE-LABEL: @test62(882; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x float> [[CALL4:%.*]] to <3 x i32>883; BE-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[TMP1]], <3 x i32> <i32 0, i32 poison, i32 poison>, <4 x i32> <i32 3, i32 0, i32 1, i32 2>884; BE-NEXT: ret <4 x i32> [[P10]]885;886; LE-LABEL: @test62(887; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x float> [[CALL4:%.*]] to <3 x i32>888; LE-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[TMP1]], <3 x i32> <i32 0, i32 poison, i32 poison>, <4 x i32> <i32 0, i32 1, i32 2, i32 3>889; LE-NEXT: ret <4 x i32> [[P10]]890;891 %p11 = bitcast <3 x float> %call4 to i96892 %p9 = zext i96 %p11 to i128893 %p10 = bitcast i128 %p9 to <4 x i32>894 ret <4 x i32> %p10895}896 897; PR7311 - Don't create invalid IR on scalar->vector cast.898define <2 x float> @test63(i64 %t8) {899; ALL-LABEL: @test63(900; ALL-NEXT: [[A:%.*]] = bitcast i64 [[T8:%.*]] to <2 x i32>901; ALL-NEXT: [[VCVT_I:%.*]] = uitofp <2 x i32> [[A]] to <2 x float>902; ALL-NEXT: ret <2 x float> [[VCVT_I]]903;904 %a = bitcast i64 %t8 to <2 x i32>905 %vcvt.i = uitofp <2 x i32> %a to <2 x float>906 ret <2 x float> %vcvt.i907}908 909define <4 x float> @test64(<4 x float> %c) {910; ALL-LABEL: @test64(911; ALL-NEXT: ret <4 x float> [[C:%.*]]912;913 %t0 = bitcast <4 x float> %c to <4 x i32>914 %t1 = bitcast <4 x i32> %t0 to <4 x float>915 ret <4 x float> %t1916}917 918define <4 x float> @test65(<4 x float> %c) {919; ALL-LABEL: @test65(920; ALL-NEXT: ret <4 x float> [[C:%.*]]921;922 %t0 = bitcast <4 x float> %c to <2 x double>923 %t1 = bitcast <2 x double> %t0 to <4 x float>924 ret <4 x float> %t1925}926 927define <2 x float> @test66(<2 x float> %c) {928; ALL-LABEL: @test66(929; ALL-NEXT: ret <2 x float> [[C:%.*]]930;931 %t0 = bitcast <2 x float> %c to double932 %t1 = bitcast double %t0 to <2 x float>933 ret <2 x float> %t1934}935 936define float @test2c() {937; ALL-LABEL: @test2c(938; ALL-NEXT: ret float -1.000000e+00939;940 ret float extractelement (<2 x float> bitcast (double bitcast (<2 x float> <float -1.000000e+00, float -1.000000e+00> to double) to <2 x float>), i32 0)941}942 943; PR12514944define i1 @test67(i1 %a, i32 %b) {945; ALL-LABEL: @test67(946; ALL-NEXT: ret i1 false947;948 %t2 = zext i1 %a to i32949 %conv6 = xor i32 %t2, 1950 %and = and i32 %b, %conv6951 %sext = shl nuw nsw i32 %and, 24952 %neg.i = xor i32 %sext, -16777216953 %conv.i.i = ashr exact i32 %neg.i, 24954 %trunc = trunc i32 %conv.i.i to i8955 %tobool.i = icmp eq i8 %trunc, 0956 ret i1 %tobool.i957}958 959%s = type { i32, i32, i16 }960 961define %s @test68(ptr %p, i64 %i) {962; ALL-LABEL: @test68(963; ALL-NEXT: [[O:%.*]] = mul i64 [[I:%.*]], 12964; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]965; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 4966; ALL-NEXT: ret [[S]] [[L]]967;968 %o = mul i64 %i, 12969 %pp = getelementptr inbounds i8, ptr %p, i64 %o970 %l = load %s, ptr %pp971 ret %s %l972}973 974; addrspacecasts should be eliminated.975define %s @test68_addrspacecast(ptr %p, i64 %i) {976; ALL-LABEL: @test68_addrspacecast(977; ALL-NEXT: [[O:%.*]] = mul i64 [[I:%.*]], 12978; ALL-NEXT: [[Q:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(2)979; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr addrspace(2) [[Q]], i64 [[O]]980; ALL-NEXT: [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr981; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr [[R]], align 4982; ALL-NEXT: ret [[S]] [[L]]983;984 %o = mul i64 %i, 12985 %q = addrspacecast ptr %p to ptr addrspace(2)986 %pp = getelementptr inbounds i8, ptr addrspace(2) %q, i64 %o987 %r = addrspacecast ptr addrspace(2) %pp to ptr988 %l = load %s, ptr %r989 ret %s %l990}991 992define %s @test68_addrspacecast_2(ptr %p, i64 %i) {993; ALL-LABEL: @test68_addrspacecast_2(994; ALL-NEXT: [[O:%.*]] = mul i64 [[I:%.*]], 12995; ALL-NEXT: [[Q:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(2)996; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr addrspace(2) [[Q]], i64 [[O]]997; ALL-NEXT: [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr addrspace(1)998; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr addrspace(1) [[R]], align 4999; ALL-NEXT: ret [[S]] [[L]]1000;1001 %o = mul i64 %i, 121002 %q = addrspacecast ptr %p to ptr addrspace(2)1003 %pp = getelementptr inbounds i8, ptr addrspace(2) %q, i64 %o1004 %r = addrspacecast ptr addrspace(2) %pp to ptr addrspace(1)1005 %l = load %s, ptr addrspace(1) %r1006 ret %s %l1007}1008 1009define %s @test68_as1(ptr addrspace(1) %p, i32 %i) {1010; ALL-LABEL: @test68_as1(1011; ALL-NEXT: [[O:%.*]] = mul i32 [[I:%.*]], 121012; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[P:%.*]], i32 [[O]]1013; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr addrspace(1) [[PP]], align 41014; ALL-NEXT: ret [[S]] [[L]]1015;1016 %o = mul i32 %i, 121017 %pp = getelementptr inbounds i8, ptr addrspace(1) %p, i32 %o1018 %l = load %s, ptr addrspace(1) %pp1019 ret %s %l1020}1021 1022define double @test69(ptr %p, i64 %i) {1023; ALL-LABEL: @test69(1024; ALL-NEXT: [[O:%.*]] = shl nsw i64 [[I:%.*]], 31025; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]1026; ALL-NEXT: [[L:%.*]] = load double, ptr [[PP]], align 81027; ALL-NEXT: ret double [[L]]1028;1029 %o = shl nsw i64 %i, 31030 %pp = getelementptr inbounds i8, ptr %p, i64 %o1031 %l = load double, ptr %pp1032 ret double %l1033}1034 1035define %s @test70(ptr %p, i64 %i) {1036; ALL-LABEL: @test70(1037; ALL-NEXT: [[O:%.*]] = mul nsw i64 [[I:%.*]], 361038; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]1039; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 41040; ALL-NEXT: ret [[S]] [[L]]1041;1042 %o = mul nsw i64 %i, 361043 %pp = getelementptr inbounds i8, ptr %p, i64 %o1044 %l = load %s, ptr %pp1045 ret %s %l1046}1047 1048define double @test71(ptr %p, i64 %i) {1049; ALL-LABEL: @test71(1050; ALL-NEXT: [[O:%.*]] = shl i64 [[I:%.*]], 51051; ALL-NEXT: [[PP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[O]]1052; ALL-NEXT: [[L:%.*]] = load double, ptr [[PP]], align 81053; ALL-NEXT: ret double [[L]]1054;1055 %o = shl i64 %i, 51056 %pp = getelementptr i8, ptr %p, i64 %o1057 %l = load double, ptr %pp1058 ret double %l1059}1060 1061define double @test72(ptr %p, i32 %i) {1062; ALL-LABEL: @test72(1063; ALL-NEXT: [[SO:%.*]] = shl nsw i32 [[I:%.*]], 31064; ALL-NEXT: [[O:%.*]] = sext i32 [[SO]] to i641065; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]1066; ALL-NEXT: [[L:%.*]] = load double, ptr [[PP]], align 81067; ALL-NEXT: ret double [[L]]1068;1069 %so = shl nsw i32 %i, 31070 %o = sext i32 %so to i641071 %pp = getelementptr inbounds i8, ptr %p, i64 %o1072 %l = load double, ptr %pp1073 ret double %l1074}1075 1076define double @test73(ptr %p, i128 %i) {1077; ALL-LABEL: @test73(1078; ALL-NEXT: [[I_TR:%.*]] = trunc i128 [[I:%.*]] to i641079; ALL-NEXT: [[O:%.*]] = shl i64 [[I_TR]], 31080; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]1081; ALL-NEXT: [[L:%.*]] = load double, ptr [[PP]], align 81082; ALL-NEXT: ret double [[L]]1083;1084 %lo = shl nsw i128 %i, 31085 %o = trunc i128 %lo to i641086 %pp = getelementptr inbounds i8, ptr %p, i64 %o1087 %l = load double, ptr %pp1088 ret double %l1089}1090 1091define double @test74(ptr %p, i64 %i) {1092; ALL-LABEL: @test74(1093; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 [[I:%.*]]1094; ALL-NEXT: [[L:%.*]] = load double, ptr [[PP]], align 81095; ALL-NEXT: ret double [[L]]1096;1097 %pp = getelementptr inbounds i64, ptr %p, i64 %i1098 %l = load double, ptr %pp1099 ret double %l1100}1101 1102define ptr @test75(ptr %p, i32 %x) {1103; ALL-LABEL: @test75(1104; ALL-NEXT: [[Y:%.*]] = shl i32 [[X:%.*]], 31105; ALL-NEXT: [[Z:%.*]] = sext i32 [[Y]] to i641106; ALL-NEXT: [[R:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Z]]1107; ALL-NEXT: ret ptr [[R]]1108;1109 %y = shl i32 %x, 31110 %z = sext i32 %y to i641111 %r = getelementptr i8, ptr %p, i64 %z1112 ret ptr %r1113}1114 1115define %s @test76(ptr %p, i64 %i, i64 %j) {1116; ALL-LABEL: @test76(1117; ALL-NEXT: [[O:%.*]] = mul i64 [[I:%.*]], 121118; ALL-NEXT: [[O2:%.*]] = mul nsw i64 [[O]], [[J:%.*]]1119; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O2]]1120; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 41121; ALL-NEXT: ret [[S]] [[L]]1122;1123 %o = mul i64 %i, 121124 %o2 = mul nsw i64 %o, %j1125 %pp = getelementptr inbounds i8, ptr %p, i64 %o21126 %l = load %s, ptr %pp1127 ret %s %l1128}1129 1130define %s @test77(ptr %p, i64 %i, i64 %j) {1131; ALL-LABEL: @test77(1132; ALL-NEXT: [[O:%.*]] = mul nsw i64 [[I:%.*]], 361133; ALL-NEXT: [[O2:%.*]] = mul nsw i64 [[O]], [[J:%.*]]1134; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O2]]1135; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 41136; ALL-NEXT: ret [[S]] [[L]]1137;1138 %o = mul nsw i64 %i, 361139 %o2 = mul nsw i64 %o, %j1140 %pp = getelementptr inbounds i8, ptr %p, i64 %o21141 %l = load %s, ptr %pp1142 ret %s %l1143}1144 1145define %s @test78(ptr %p, i64 %i, i64 %j, i32 %k, i32 %l, i128 %m, i128 %n) {1146; ALL-LABEL: @test78(1147; ALL-NEXT: [[A:%.*]] = mul nsw i32 [[K:%.*]], 361148; ALL-NEXT: [[B:%.*]] = mul nsw i32 [[A]], [[L:%.*]]1149; ALL-NEXT: [[C:%.*]] = sext i32 [[B]] to i1281150; ALL-NEXT: [[D:%.*]] = mul nsw i128 [[M:%.*]], [[C]]1151; ALL-NEXT: [[E:%.*]] = mul i128 [[D]], [[N:%.*]]1152; ALL-NEXT: [[F:%.*]] = trunc i128 [[E]] to i641153; ALL-NEXT: [[G:%.*]] = mul nsw i64 [[I:%.*]], [[F]]1154; ALL-NEXT: [[H:%.*]] = mul nsw i64 [[G]], [[J:%.*]]1155; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[H]]1156; ALL-NEXT: [[LOAD:%.*]] = load [[S:%.*]], ptr [[PP]], align 41157; ALL-NEXT: ret [[S]] [[LOAD]]1158;1159 %a = mul nsw i32 %k, 361160 %b = mul nsw i32 %a, %l1161 %c = sext i32 %b to i1281162 %d = mul nsw i128 %c, %m1163 %e = mul i128 %d, %n1164 %f = trunc i128 %e to i641165 %g = mul nsw i64 %f, %i1166 %h = mul nsw i64 %g, %j1167 %pp = getelementptr inbounds i8, ptr %p, i64 %h1168 %load = load %s, ptr %pp1169 ret %s %load1170}1171 1172define %s @test79(ptr %p, i64 %i, i32 %j) {1173; ALL-LABEL: @test79(1174; ALL-NEXT: [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i321175; ALL-NEXT: [[B:%.*]] = mul i32 [[TMP1]], 361176; ALL-NEXT: [[C:%.*]] = mul i32 [[B]], [[J:%.*]]1177; ALL-NEXT: [[TMP2:%.*]] = sext i32 [[C]] to i641178; ALL-NEXT: [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[TMP2]]1179; ALL-NEXT: [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 41180; ALL-NEXT: ret [[S]] [[L]]1181;1182 %a = mul nsw i64 %i, 361183 %b = trunc i64 %a to i321184 %c = mul i32 %b, %j1185 %pp = getelementptr inbounds i8, ptr %p, i32 %c1186 %l = load %s, ptr %pp1187 ret %s %l1188}1189 1190define double @test80(ptr %p, i32 %i) {1191; ALL-LABEL: @test80(1192; ALL-NEXT: [[T:%.*]] = shl nsw i32 [[I:%.*]], 31193; ALL-NEXT: [[TMP1:%.*]] = sext i32 [[T]] to i641194; ALL-NEXT: [[PP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]1195; ALL-NEXT: [[L:%.*]] = load double, ptr [[PP]], align 81196; ALL-NEXT: ret double [[L]]1197;1198 %t = shl nsw i32 %i, 31199 %pp = getelementptr i8, ptr %p, i32 %t1200 %l = load double, ptr %pp1201 ret double %l1202}1203 1204define double @test80_addrspacecast(ptr addrspace(1) %p, i32 %i) {1205; ALL-LABEL: @test80_addrspacecast(1206; ALL-NEXT: [[T:%.*]] = shl nsw i32 [[I:%.*]], 31207; ALL-NEXT: [[Q:%.*]] = addrspacecast ptr addrspace(1) [[P:%.*]] to ptr addrspace(2)1208; ALL-NEXT: [[TMP1:%.*]] = sext i32 [[T]] to i641209; ALL-NEXT: [[PP:%.*]] = getelementptr i8, ptr addrspace(2) [[Q]], i64 [[TMP1]]1210; ALL-NEXT: [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr addrspace(1)1211; ALL-NEXT: [[L:%.*]] = load double, ptr addrspace(1) [[R]], align 81212; ALL-NEXT: ret double [[L]]1213;1214 %t = shl nsw i32 %i, 31215 %q = addrspacecast ptr addrspace(1) %p to ptr addrspace(2)1216 %pp = getelementptr i8, ptr addrspace(2) %q, i32 %t1217 %r = addrspacecast ptr addrspace(2) %pp to ptr addrspace(1)1218 %l = load double, ptr addrspace(1) %r1219 ret double %l1220}1221 1222define double @test80_addrspacecast_2(ptr addrspace(1) %p, i32 %i) {1223; ALL-LABEL: @test80_addrspacecast_2(1224; ALL-NEXT: [[T:%.*]] = shl nsw i32 [[I:%.*]], 31225; ALL-NEXT: [[Q:%.*]] = addrspacecast ptr addrspace(1) [[P:%.*]] to ptr addrspace(2)1226; ALL-NEXT: [[TMP1:%.*]] = sext i32 [[T]] to i641227; ALL-NEXT: [[PP:%.*]] = getelementptr i8, ptr addrspace(2) [[Q]], i64 [[TMP1]]1228; ALL-NEXT: [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr addrspace(3)1229; ALL-NEXT: [[L:%.*]] = load double, ptr addrspace(3) [[R]], align 81230; ALL-NEXT: ret double [[L]]1231;1232 %t = shl nsw i32 %i, 31233 %q = addrspacecast ptr addrspace(1) %p to ptr addrspace(2)1234 %pp = getelementptr i8, ptr addrspace(2) %q, i32 %t1235 %r = addrspacecast ptr addrspace(2) %pp to ptr addrspace(3)1236 %l = load double, ptr addrspace(3) %r1237 ret double %l1238}1239 1240define double @test80_as1(ptr addrspace(1) %p, i16 %i) {1241; ALL-LABEL: @test80_as1(1242; ALL-NEXT: [[T:%.*]] = shl nsw i16 [[I:%.*]], 31243; ALL-NEXT: [[TMP1:%.*]] = sext i16 [[T]] to i321244; ALL-NEXT: [[PP:%.*]] = getelementptr i8, ptr addrspace(1) [[P:%.*]], i32 [[TMP1]]1245; ALL-NEXT: [[L:%.*]] = load double, ptr addrspace(1) [[PP]], align 81246; ALL-NEXT: ret double [[L]]1247;1248 %t = shl nsw i16 %i, 31249 %pp = getelementptr i8, ptr addrspace(1) %p, i16 %t1250 %l = load double, ptr addrspace(1) %pp1251 ret double %l1252}1253 1254define double @test81(ptr %p, float %f) {1255; ALL-LABEL: @test81(1256; ALL-NEXT: [[I:%.*]] = fptosi float [[F:%.*]] to i641257; ALL-NEXT: [[PP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[I]]1258; ALL-NEXT: [[L:%.*]] = load double, ptr [[PP]], align 81259; ALL-NEXT: ret double [[L]]1260;1261 %i = fptosi float %f to i641262 %pp = getelementptr i8, ptr %p, i64 %i1263 %l = load double, ptr %pp1264 ret double %l1265}1266 1267define i64 @test82(i64 %A) {1268; ALL-LABEL: @test82(1269; ALL-NEXT: [[TMP1:%.*]] = shl i64 [[A:%.*]], 11270; ALL-NEXT: [[D:%.*]] = and i64 [[TMP1]], 42949667841271; ALL-NEXT: ret i64 [[D]]1272;1273 %B = trunc i64 %A to i321274 %C = lshr i32 %B, 81275 %D = shl i32 %C, 91276 %E = zext i32 %D to i641277 ret i64 %E1278}1279 1280; PR159591281define i64 @test83(i16 %a, i64 %k) {1282; ALL-LABEL: @test83(1283; ALL-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i321284; ALL-NEXT: [[TMP1:%.*]] = trunc i64 [[K:%.*]] to i321285; ALL-NEXT: [[SH_PROM:%.*]] = add i32 [[TMP1]], -11286; ALL-NEXT: [[SHL:%.*]] = shl i32 [[CONV]], [[SH_PROM]]1287; ALL-NEXT: [[SH_PROM1:%.*]] = zext i32 [[SHL]] to i641288; ALL-NEXT: ret i64 [[SH_PROM1]]1289;1290 %conv = sext i16 %a to i321291 %sub = add nsw i64 %k, -11292 %sh_prom = trunc i64 %sub to i321293 %shl = shl i32 %conv, %sh_prom1294 %sh_prom1 = zext i32 %shl to i641295 ret i64 %sh_prom11296}1297 1298define i8 @test84(i32 %a) {1299; ALL-LABEL: @test84(1300; ALL-NEXT: [[ADD:%.*]] = add i32 [[A:%.*]], 21307064321301; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], 231302; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i81303; ALL-NEXT: ret i8 [[TRUNC]]1304;1305 %add = add nsw i32 %a, -167772161306 %shr = lshr exact i32 %add, 231307 %trunc = trunc i32 %shr to i81308 ret i8 %trunc1309}1310 1311define i8 @test85(i32 %a) {1312; ALL-LABEL: @test85(1313; ALL-NEXT: [[ADD:%.*]] = add i32 [[A:%.*]], 21307064321314; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], 231315; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i81316; ALL-NEXT: ret i8 [[TRUNC]]1317;1318 %add = add nuw i32 %a, -167772161319 %shr = lshr exact i32 %add, 231320 %trunc = trunc i32 %shr to i81321 ret i8 %trunc1322}1323 1324define i16 @test86(i16 %v) {1325; ALL-LABEL: @test86(1326; ALL-NEXT: [[TMP1:%.*]] = ashr i16 [[V:%.*]], 41327; ALL-NEXT: ret i16 [[TMP1]]1328;1329 %a = sext i16 %v to i321330 %s = ashr i32 %a, 41331 %t = trunc i32 %s to i161332 ret i16 %t1333}1334 1335define i16 @test87(i16 %v) {1336; ALL-LABEL: @test87(1337; ALL-NEXT: [[TMP1:%.*]] = ashr i16 [[V:%.*]], 121338; ALL-NEXT: ret i16 [[TMP1]]1339;1340 %c = sext i16 %v to i321341 %m = mul nsw i32 %c, 161342 %a = ashr i32 %m, 161343 %t = trunc i32 %a to i161344 ret i16 %t1345}1346 1347define i16 @test88(i16 %v) {1348; ALL-LABEL: @test88(1349; ALL-NEXT: [[TMP1:%.*]] = ashr i16 [[V:%.*]], 151350; ALL-NEXT: ret i16 [[TMP1]]1351;1352 %a = sext i16 %v to i321353 %s = ashr i32 %a, 181354 %t = trunc i32 %s to i161355 ret i16 %t1356}1357 1358define i32 @PR21388(ptr %v) {1359; ALL-LABEL: @PR21388(1360; ALL-NEXT: [[ICMP:%.*]] = icmp slt ptr [[V:%.*]], null1361; ALL-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i321362; ALL-NEXT: ret i32 [[SEXT]]1363;1364 %icmp = icmp slt ptr %v, null1365 %sext = sext i1 %icmp to i321366 ret i32 %sext1367}1368 1369define float @sitofp_zext(i16 %a) {1370; ALL-LABEL: @sitofp_zext(1371; ALL-NEXT: [[SITOFP:%.*]] = uitofp i16 [[A:%.*]] to float1372; ALL-NEXT: ret float [[SITOFP]]1373;1374 %zext = zext i16 %a to i321375 %sitofp = sitofp i32 %zext to float1376 ret float %sitofp1377}1378 1379define i1 @PR23309(i32 %A, i32 %B) {1380; ALL-LABEL: @PR23309(1381; ALL-NEXT: [[SUB:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]1382; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SUB]] to i11383; ALL-NEXT: ret i1 [[TRUNC]]1384;1385 %add = add i32 %A, -41386 %sub = sub nsw i32 %add, %B1387 %trunc = trunc i32 %sub to i11388 ret i1 %trunc1389}1390 1391define i1 @PR23309v2(i32 %A, i32 %B) {1392; ALL-LABEL: @PR23309v2(1393; ALL-NEXT: [[SUB:%.*]] = add i32 [[A:%.*]], [[B:%.*]]1394; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SUB]] to i11395; ALL-NEXT: ret i1 [[TRUNC]]1396;1397 %add = add i32 %A, -41398 %sub = add nuw i32 %add, %B1399 %trunc = trunc i32 %sub to i11400 ret i1 %trunc1401}1402 1403define i16 @PR24763(i8 %V) {1404; ALL-LABEL: @PR24763(1405; ALL-NEXT: [[TMP1:%.*]] = ashr i8 [[V:%.*]], 11406; ALL-NEXT: [[T:%.*]] = sext i8 [[TMP1]] to i161407; ALL-NEXT: ret i16 [[T]]1408;1409 %conv = sext i8 %V to i321410 %l = lshr i32 %conv, 11411 %t = trunc i32 %l to i161412 ret i16 %t1413}1414 1415define i64 @PR28745() {1416; BE-LABEL: @PR28745(1417; BE-NEXT: ret i64 11418;1419; LE-LABEL: @PR28745(1420; LE-NEXT: ret i64 01421;1422 %c = icmp eq i16 extractelement (<2 x i16> bitcast (<1 x i32> <i32 1> to <2 x i16>), i32 0), 01423 %s = select i1 %c, { i32 } { i32 1 }, { i32 } zeroinitializer1424 %e = extractvalue { i32 } %s, 01425 %b = zext i32 %e to i641426 ret i64 %b1427}1428 1429define i32 @test89() {1430; BE-LABEL: @test89(1431; BE-NEXT: ret i32 3932161432;1433; LE-LABEL: @test89(1434; LE-NEXT: ret i32 61435;1436 ret i32 bitcast (<2 x i16> <i16 6, i16 poison> to i32)1437}1438 1439define <2 x i32> @test90() {1440; BE-LABEL: @test90(1441; BE-NEXT: ret <2 x i32> <i32 0, i32 15360>1442;1443; LE-LABEL: @test90(1444; LE-NEXT: ret <2 x i32> <i32 0, i32 1006632960>1445;1446 %t6 = bitcast <4 x half> <half poison, half poison, half poison, half 0xH3C00> to <2 x i32>1447 ret <2 x i32> %t61448}1449 1450; Do not optimize to ashr i64 (shift by 48 > 96 - 64)1451define i64 @test91(i64 %A) {1452; ALL-LABEL: @test91(1453; ALL-NEXT: [[B:%.*]] = sext i64 [[A:%.*]] to i961454; ALL-NEXT: [[C:%.*]] = lshr i96 [[B]], 481455; ALL-NEXT: [[D:%.*]] = trunc nuw nsw i96 [[C]] to i641456; ALL-NEXT: ret i64 [[D]]1457;1458 %B = sext i64 %A to i961459 %C = lshr i96 %B, 481460 %D = trunc i96 %C to i641461 ret i64 %D1462}1463 1464; Do optimize to ashr i64 (shift by 32 <= 96 - 64)1465define i64 @test92(i64 %A) {1466; ALL-LABEL: @test92(1467; ALL-NEXT: [[TMP1:%.*]] = ashr i64 [[A:%.*]], 321468; ALL-NEXT: ret i64 [[TMP1]]1469;1470 %B = sext i64 %A to i961471 %C = lshr i96 %B, 321472 %D = trunc i96 %C to i641473 ret i64 %D1474}1475 1476; When optimizing to ashr i32, don't shift by more than 31.1477define i32 @test93(i32 %A) {1478; ALL-LABEL: @test93(1479; ALL-NEXT: [[TMP1:%.*]] = ashr i32 [[A:%.*]], 311480; ALL-NEXT: ret i32 [[TMP1]]1481;1482 %B = sext i32 %A to i961483 %C = lshr i96 %B, 641484 %D = trunc i96 %C to i321485 ret i32 %D1486}1487 1488define i8 @trunc_lshr_sext(i8 %A) {1489; ALL-LABEL: @trunc_lshr_sext(1490; ALL-NEXT: [[D:%.*]] = ashr i8 [[A:%.*]], 61491; ALL-NEXT: ret i8 [[D]]1492;1493 %B = sext i8 %A to i321494 %C = lshr i32 %B, 61495 %D = trunc i32 %C to i81496 ret i8 %D1497}1498 1499define i8 @trunc_lshr_sext_exact(i8 %A) {1500; ALL-LABEL: @trunc_lshr_sext_exact(1501; ALL-NEXT: [[D:%.*]] = ashr exact i8 [[A:%.*]], 61502; ALL-NEXT: ret i8 [[D]]1503;1504 %B = sext i8 %A to i321505 %C = lshr exact i32 %B, 61506 %D = trunc i32 %C to i81507 ret i8 %D1508}1509 1510define <2 x i8> @trunc_lshr_sext_uniform(<2 x i8> %A) {1511; ALL-LABEL: @trunc_lshr_sext_uniform(1512; ALL-NEXT: [[D:%.*]] = ashr <2 x i8> [[A:%.*]], splat (i8 6)1513; ALL-NEXT: ret <2 x i8> [[D]]1514;1515 %B = sext <2 x i8> %A to <2 x i32>1516 %C = lshr <2 x i32> %B, <i32 6, i32 6>1517 %D = trunc <2 x i32> %C to <2 x i8>1518 ret <2 x i8> %D1519}1520 1521define <2 x i8> @trunc_lshr_sext_uniform_poison(<2 x i8> %A) {1522; ALL-LABEL: @trunc_lshr_sext_uniform_poison(1523; ALL-NEXT: [[D:%.*]] = ashr <2 x i8> [[A:%.*]], <i8 6, i8 poison>1524; ALL-NEXT: ret <2 x i8> [[D]]1525;1526 %B = sext <2 x i8> %A to <2 x i32>1527 %C = lshr <2 x i32> %B, <i32 6, i32 poison>1528 %D = trunc <2 x i32> %C to <2 x i8>1529 ret <2 x i8> %D1530}1531 1532define <2 x i8> @trunc_lshr_sext_nonuniform(<2 x i8> %A) {1533; ALL-LABEL: @trunc_lshr_sext_nonuniform(1534; ALL-NEXT: [[D:%.*]] = ashr <2 x i8> [[A:%.*]], <i8 6, i8 2>1535; ALL-NEXT: ret <2 x i8> [[D]]1536;1537 %B = sext <2 x i8> %A to <2 x i32>1538 %C = lshr <2 x i32> %B, <i32 6, i32 2>1539 %D = trunc <2 x i32> %C to <2 x i8>1540 ret <2 x i8> %D1541}1542 1543define <3 x i8> @trunc_lshr_sext_nonuniform_poison(<3 x i8> %A) {1544; ALL-LABEL: @trunc_lshr_sext_nonuniform_poison(1545; ALL-NEXT: [[D:%.*]] = ashr <3 x i8> [[A:%.*]], <i8 6, i8 2, i8 poison>1546; ALL-NEXT: ret <3 x i8> [[D]]1547;1548 %B = sext <3 x i8> %A to <3 x i32>1549 %C = lshr <3 x i32> %B, <i32 6, i32 2, i32 poison>1550 %D = trunc <3 x i32> %C to <3 x i8>1551 ret <3 x i8> %D1552}1553 1554define <2 x i8> @trunc_lshr_sext_uses1(<2 x i8> %A) {1555; ALL-LABEL: @trunc_lshr_sext_uses1(1556; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1557; ALL-NEXT: call void @use_v2i32(<2 x i32> [[B]])1558; ALL-NEXT: [[D:%.*]] = ashr <2 x i8> [[A]], splat (i8 6)1559; ALL-NEXT: ret <2 x i8> [[D]]1560;1561 %B = sext <2 x i8> %A to <2 x i32>1562 call void @use_v2i32(<2 x i32> %B)1563 %C = lshr <2 x i32> %B, <i32 6, i32 6>1564 %D = trunc <2 x i32> %C to <2 x i8>1565 ret <2 x i8> %D1566}1567 1568define i8 @trunc_lshr_sext_uses2(i8 %A) {1569; ALL-LABEL: @trunc_lshr_sext_uses2(1570; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321571; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 61572; ALL-NEXT: call void @use_i32(i32 [[C]])1573; ALL-NEXT: [[D:%.*]] = ashr i8 [[A]], 61574; ALL-NEXT: ret i8 [[D]]1575;1576 %B = sext i8 %A to i321577 %C = lshr i32 %B, 61578 call void @use_i32(i32 %C)1579 %D = trunc i32 %C to i81580 ret i8 %D1581}1582 1583define <2 x i8> @trunc_lshr_sext_uses3(<2 x i8> %A) {1584; ALL-LABEL: @trunc_lshr_sext_uses3(1585; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1586; ALL-NEXT: call void @use_v2i32(<2 x i32> [[B]])1587; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 6)1588; ALL-NEXT: call void @use_v2i32(<2 x i32> [[C]])1589; ALL-NEXT: [[D:%.*]] = ashr <2 x i8> [[A]], splat (i8 6)1590; ALL-NEXT: ret <2 x i8> [[D]]1591;1592 %B = sext <2 x i8 >%A to <2 x i32>1593 call void @use_v2i32(<2 x i32> %B)1594 %C = lshr <2 x i32> %B, <i32 6, i32 6>1595 call void @use_v2i32(<2 x i32> %C)1596 %D = trunc <2 x i32 >%C to <2 x i8>1597 ret <2 x i8> %D1598}1599 1600define <2 x i8> @trunc_lshr_overshift_sext(<2 x i8> %A) {1601; ALL-LABEL: @trunc_lshr_overshift_sext(1602; ALL-NEXT: [[D:%.*]] = ashr <2 x i8> [[A:%.*]], splat (i8 7)1603; ALL-NEXT: ret <2 x i8> [[D]]1604;1605 %B = sext <2 x i8> %A to <2 x i32>1606 %C = lshr <2 x i32> %B, <i32 8, i32 8>1607 %D = trunc <2 x i32> %C to <2 x i8>1608 ret <2 x i8> %D1609}1610 1611define i8 @trunc_lshr_overshift_sext_uses1(i8 %A) {1612; ALL-LABEL: @trunc_lshr_overshift_sext_uses1(1613; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321614; ALL-NEXT: call void @use_i32(i32 [[B]])1615; ALL-NEXT: [[D:%.*]] = ashr i8 [[A]], 71616; ALL-NEXT: ret i8 [[D]]1617;1618 %B = sext i8 %A to i321619 call void @use_i32(i32 %B)1620 %C = lshr i32 %B, 81621 %D = trunc i32 %C to i81622 ret i8 %D1623}1624 1625define <2 x i8> @trunc_lshr_overshift_sext_uses2(<2 x i8> %A) {1626; ALL-LABEL: @trunc_lshr_overshift_sext_uses2(1627; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1628; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 8)1629; ALL-NEXT: call void @use_v2i32(<2 x i32> [[C]])1630; ALL-NEXT: [[D:%.*]] = ashr <2 x i8> [[A]], splat (i8 7)1631; ALL-NEXT: ret <2 x i8> [[D]]1632;1633 %B = sext <2 x i8> %A to <2 x i32>1634 %C = lshr <2 x i32> %B, <i32 8, i32 8>1635 call void @use_v2i32(<2 x i32> %C)1636 %D = trunc <2 x i32> %C to <2 x i8>1637 ret <2 x i8> %D1638}1639 1640define i8 @trunc_lshr_overshift_sext_uses3(i8 %A) {1641; ALL-LABEL: @trunc_lshr_overshift_sext_uses3(1642; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321643; ALL-NEXT: call void @use_i32(i32 [[B]])1644; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 81645; ALL-NEXT: call void @use_i32(i32 [[C]])1646; ALL-NEXT: [[D:%.*]] = ashr i8 [[A]], 71647; ALL-NEXT: ret i8 [[D]]1648;1649 %B = sext i8 %A to i321650 call void @use_i32(i32 %B)1651 %C = lshr i32 %B, 81652 call void @use_i32(i32 %C)1653 %D = trunc i32 %C to i81654 ret i8 %D1655}1656 1657define i8 @trunc_lshr_sext_wide_input(i16 %A) {1658; ALL-LABEL: @trunc_lshr_sext_wide_input(1659; ALL-NEXT: [[TMP1:%.*]] = ashr i16 [[A:%.*]], 91660; ALL-NEXT: [[D:%.*]] = trunc nsw i16 [[TMP1]] to i81661; ALL-NEXT: ret i8 [[D]]1662;1663 %B = sext i16 %A to i321664 %C = lshr i32 %B, 91665 %D = trunc i32 %C to i81666 ret i8 %D1667}1668 1669define i8 @trunc_lshr_sext_wide_input_exact(i16 %A) {1670; ALL-LABEL: @trunc_lshr_sext_wide_input_exact(1671; ALL-NEXT: [[TMP1:%.*]] = ashr exact i16 [[A:%.*]], 91672; ALL-NEXT: [[D:%.*]] = trunc nsw i16 [[TMP1]] to i81673; ALL-NEXT: ret i8 [[D]]1674;1675 %B = sext i16 %A to i321676 %C = lshr exact i32 %B, 91677 %D = trunc i32 %C to i81678 ret i8 %D1679}1680 1681define <2 x i8> @trunc_lshr_sext_wide_input_uses1(<2 x i16> %A) {1682; ALL-LABEL: @trunc_lshr_sext_wide_input_uses1(1683; ALL-NEXT: [[B:%.*]] = sext <2 x i16> [[A:%.*]] to <2 x i32>1684; ALL-NEXT: call void @use_v2i32(<2 x i32> [[B]])1685; ALL-NEXT: [[TMP1:%.*]] = ashr <2 x i16> [[A]], splat (i16 9)1686; ALL-NEXT: [[D:%.*]] = trunc nsw <2 x i16> [[TMP1]] to <2 x i8>1687; ALL-NEXT: ret <2 x i8> [[D]]1688;1689 %B = sext <2 x i16> %A to <2 x i32>1690 call void @use_v2i32(<2 x i32> %B)1691 %C = lshr <2 x i32> %B, <i32 9, i32 9>1692 %D = trunc <2 x i32> %C to <2 x i8>1693 ret <2 x i8> %D1694}1695 1696define i8 @trunc_lshr_sext_wide_input_uses2(i16 %A) {1697; ALL-LABEL: @trunc_lshr_sext_wide_input_uses2(1698; ALL-NEXT: [[B:%.*]] = sext i16 [[A:%.*]] to i321699; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 91700; ALL-NEXT: call void @use_i32(i32 [[C]])1701; ALL-NEXT: [[D:%.*]] = trunc i32 [[C]] to i81702; ALL-NEXT: ret i8 [[D]]1703;1704 %B = sext i16 %A to i321705 %C = lshr i32 %B, 91706 call void @use_i32(i32 %C)1707 %D = trunc i32 %C to i81708 ret i8 %D1709}1710 1711define <2 x i8> @trunc_lshr_sext_wide_input_uses3(<2 x i16> %A) {1712; ALL-LABEL: @trunc_lshr_sext_wide_input_uses3(1713; ALL-NEXT: [[B:%.*]] = sext <2 x i16> [[A:%.*]] to <2 x i32>1714; ALL-NEXT: call void @use_v2i32(<2 x i32> [[B]])1715; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 9)1716; ALL-NEXT: call void @use_v2i32(<2 x i32> [[C]])1717; ALL-NEXT: [[D:%.*]] = trunc <2 x i32> [[C]] to <2 x i8>1718; ALL-NEXT: ret <2 x i8> [[D]]1719;1720 %B = sext <2 x i16 >%A to <2 x i32>1721 call void @use_v2i32(<2 x i32> %B)1722 %C = lshr <2 x i32> %B, <i32 9, i32 9>1723 call void @use_v2i32(<2 x i32> %C)1724 %D = trunc <2 x i32 >%C to <2 x i8>1725 ret <2 x i8> %D1726}1727 1728define <2 x i8> @trunc_lshr_overshift_wide_input_sext(<2 x i16> %A) {1729; ALL-LABEL: @trunc_lshr_overshift_wide_input_sext(1730; ALL-NEXT: [[TMP1:%.*]] = ashr <2 x i16> [[A:%.*]], splat (i16 15)1731; ALL-NEXT: [[D:%.*]] = trunc nsw <2 x i16> [[TMP1]] to <2 x i8>1732; ALL-NEXT: ret <2 x i8> [[D]]1733;1734 %B = sext <2 x i16> %A to <2 x i32>1735 %C = lshr <2 x i32> %B, <i32 16, i32 16>1736 %D = trunc <2 x i32> %C to <2 x i8>1737 ret <2 x i8> %D1738}1739 1740define i8 @trunc_lshr_overshift_sext_wide_input_uses1(i16 %A) {1741; ALL-LABEL: @trunc_lshr_overshift_sext_wide_input_uses1(1742; ALL-NEXT: [[B:%.*]] = sext i16 [[A:%.*]] to i321743; ALL-NEXT: call void @use_i32(i32 [[B]])1744; ALL-NEXT: [[TMP1:%.*]] = ashr i16 [[A]], 151745; ALL-NEXT: [[D:%.*]] = trunc nsw i16 [[TMP1]] to i81746; ALL-NEXT: ret i8 [[D]]1747;1748 %B = sext i16 %A to i321749 call void @use_i32(i32 %B)1750 %C = lshr i32 %B, 161751 %D = trunc i32 %C to i81752 ret i8 %D1753}1754 1755define <2 x i8> @trunc_lshr_overshift_sext_wide_input_uses2(<2 x i16> %A) {1756; ALL-LABEL: @trunc_lshr_overshift_sext_wide_input_uses2(1757; ALL-NEXT: [[TMP1:%.*]] = ashr <2 x i16> [[A:%.*]], splat (i16 15)1758; ALL-NEXT: [[C:%.*]] = zext <2 x i16> [[TMP1]] to <2 x i32>1759; ALL-NEXT: call void @use_v2i32(<2 x i32> [[C]])1760; ALL-NEXT: [[D:%.*]] = trunc nsw <2 x i16> [[TMP1]] to <2 x i8>1761; ALL-NEXT: ret <2 x i8> [[D]]1762;1763 %B = sext <2 x i16> %A to <2 x i32>1764 %C = lshr <2 x i32> %B, <i32 16, i32 16>1765 call void @use_v2i32(<2 x i32> %C)1766 %D = trunc <2 x i32> %C to <2 x i8>1767 ret <2 x i8> %D1768}1769 1770define i8 @trunc_lshr_overshift_sext_wide_input_uses3(i16 %A) {1771; ALL-LABEL: @trunc_lshr_overshift_sext_wide_input_uses3(1772; ALL-NEXT: [[B:%.*]] = sext i16 [[A:%.*]] to i321773; ALL-NEXT: call void @use_i32(i32 [[B]])1774; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 161775; ALL-NEXT: call void @use_i32(i32 [[C]])1776; ALL-NEXT: [[D:%.*]] = trunc i32 [[C]] to i81777; ALL-NEXT: ret i8 [[D]]1778;1779 %B = sext i16 %A to i321780 call void @use_i32(i32 %B)1781 %C = lshr i32 %B, 161782 call void @use_i32(i32 %C)1783 %D = trunc i32 %C to i81784 ret i8 %D1785}1786 1787define i16 @trunc_lshr_sext_narrow_input(i8 %A) {1788; ALL-LABEL: @trunc_lshr_sext_narrow_input(1789; ALL-NEXT: [[TMP1:%.*]] = ashr i8 [[A:%.*]], 61790; ALL-NEXT: [[D:%.*]] = sext i8 [[TMP1]] to i161791; ALL-NEXT: ret i16 [[D]]1792;1793 %B = sext i8 %A to i321794 %C = lshr i32 %B, 61795 %D = trunc i32 %C to i161796 ret i16 %D1797}1798 1799define <2 x i16> @trunc_lshr_sext_narrow_input_uses1(<2 x i8> %A) {1800; ALL-LABEL: @trunc_lshr_sext_narrow_input_uses1(1801; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1802; ALL-NEXT: call void @use_v2i32(<2 x i32> [[B]])1803; ALL-NEXT: [[TMP1:%.*]] = ashr <2 x i8> [[A]], splat (i8 6)1804; ALL-NEXT: [[D:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i16>1805; ALL-NEXT: ret <2 x i16> [[D]]1806;1807 %B = sext <2 x i8> %A to <2 x i32>1808 call void @use_v2i32(<2 x i32> %B)1809 %C = lshr <2 x i32> %B, <i32 6, i32 6>1810 %D = trunc <2 x i32> %C to <2 x i16>1811 ret <2 x i16> %D1812}1813 1814define i16 @trunc_lshr_sext_narrow_input_uses2(i8 %A) {1815; ALL-LABEL: @trunc_lshr_sext_narrow_input_uses2(1816; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321817; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 61818; ALL-NEXT: call void @use_i32(i32 [[C]])1819; ALL-NEXT: [[D:%.*]] = trunc i32 [[C]] to i161820; ALL-NEXT: ret i16 [[D]]1821;1822 %B = sext i8 %A to i321823 %C = lshr i32 %B, 61824 call void @use_i32(i32 %C)1825 %D = trunc i32 %C to i161826 ret i16 %D1827}1828 1829define <2 x i16> @trunc_lshr_sext_narrow_input_uses3(<2 x i8> %A) {1830; ALL-LABEL: @trunc_lshr_sext_narrow_input_uses3(1831; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1832; ALL-NEXT: call void @use_v2i32(<2 x i32> [[B]])1833; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 6)1834; ALL-NEXT: call void @use_v2i32(<2 x i32> [[C]])1835; ALL-NEXT: [[D:%.*]] = trunc <2 x i32> [[C]] to <2 x i16>1836; ALL-NEXT: ret <2 x i16> [[D]]1837;1838 %B = sext <2 x i8 >%A to <2 x i32>1839 call void @use_v2i32(<2 x i32> %B)1840 %C = lshr <2 x i32> %B, <i32 6, i32 6>1841 call void @use_v2i32(<2 x i32> %C)1842 %D = trunc <2 x i32 >%C to <2 x i16>1843 ret <2 x i16> %D1844}1845 1846define <2 x i16> @trunc_lshr_overshift_narrow_input_sext(<2 x i8> %A) {1847; ALL-LABEL: @trunc_lshr_overshift_narrow_input_sext(1848; ALL-NEXT: [[TMP1:%.*]] = ashr <2 x i8> [[A:%.*]], splat (i8 7)1849; ALL-NEXT: [[D:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i16>1850; ALL-NEXT: ret <2 x i16> [[D]]1851;1852 %B = sext <2 x i8> %A to <2 x i32>1853 %C = lshr <2 x i32> %B, <i32 8, i32 8>1854 %D = trunc <2 x i32> %C to <2 x i16>1855 ret <2 x i16> %D1856}1857 1858define i16 @trunc_lshr_overshift_sext_narrow_input_uses1(i8 %A) {1859; ALL-LABEL: @trunc_lshr_overshift_sext_narrow_input_uses1(1860; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321861; ALL-NEXT: call void @use_i32(i32 [[B]])1862; ALL-NEXT: [[TMP1:%.*]] = ashr i8 [[A]], 71863; ALL-NEXT: [[D:%.*]] = sext i8 [[TMP1]] to i161864; ALL-NEXT: ret i16 [[D]]1865;1866 %B = sext i8 %A to i321867 call void @use_i32(i32 %B)1868 %C = lshr i32 %B, 81869 %D = trunc i32 %C to i161870 ret i16 %D1871}1872 1873define <2 x i16> @trunc_lshr_overshift_sext_narrow_input_uses2(<2 x i8> %A) {1874; ALL-LABEL: @trunc_lshr_overshift_sext_narrow_input_uses2(1875; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1876; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 8)1877; ALL-NEXT: call void @use_v2i32(<2 x i32> [[C]])1878; ALL-NEXT: [[D:%.*]] = trunc <2 x i32> [[C]] to <2 x i16>1879; ALL-NEXT: ret <2 x i16> [[D]]1880;1881 %B = sext <2 x i8> %A to <2 x i32>1882 %C = lshr <2 x i32> %B, <i32 8, i32 8>1883 call void @use_v2i32(<2 x i32> %C)1884 %D = trunc <2 x i32> %C to <2 x i16>1885 ret <2 x i16> %D1886}1887 1888define i16 @trunc_lshr_overshift_sext_narrow_input_uses3(i8 %A) {1889; ALL-LABEL: @trunc_lshr_overshift_sext_narrow_input_uses3(1890; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321891; ALL-NEXT: call void @use_i32(i32 [[B]])1892; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 81893; ALL-NEXT: call void @use_i32(i32 [[C]])1894; ALL-NEXT: [[D:%.*]] = trunc i32 [[C]] to i161895; ALL-NEXT: ret i16 [[D]]1896;1897 %B = sext i8 %A to i321898 call void @use_i32(i32 %B)1899 %C = lshr i32 %B, 81900 call void @use_i32(i32 %C)1901 %D = trunc i32 %C to i161902 ret i16 %D1903}1904 1905define <2 x i8> @trunc_lshr_overshift2_sext(<2 x i8> %A) {1906; ALL-LABEL: @trunc_lshr_overshift2_sext(1907; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1908; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 25)1909; ALL-NEXT: [[D:%.*]] = trunc nuw nsw <2 x i32> [[C]] to <2 x i8>1910; ALL-NEXT: ret <2 x i8> [[D]]1911;1912 %B = sext <2 x i8> %A to <2 x i32>1913 %C = lshr <2 x i32> %B, <i32 25, i32 25>1914 %D = trunc <2 x i32> %C to <2 x i8>1915 ret <2 x i8> %D1916}1917 1918define i8 @trunc_lshr_overshift2_sext_uses1(i8 %A) {1919; ALL-LABEL: @trunc_lshr_overshift2_sext_uses1(1920; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321921; ALL-NEXT: call void @use_i32(i32 [[B]])1922; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 251923; ALL-NEXT: [[D:%.*]] = trunc nuw nsw i32 [[C]] to i81924; ALL-NEXT: ret i8 [[D]]1925;1926 %B = sext i8 %A to i321927 call void @use_i32(i32 %B)1928 %C = lshr i32 %B, 251929 %D = trunc i32 %C to i81930 ret i8 %D1931}1932 1933define <2 x i8> @trunc_lshr_overshift2_sext_uses2(<2 x i8> %A) {1934; ALL-LABEL: @trunc_lshr_overshift2_sext_uses2(1935; ALL-NEXT: [[B:%.*]] = sext <2 x i8> [[A:%.*]] to <2 x i32>1936; ALL-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], splat (i32 25)1937; ALL-NEXT: call void @use_v2i32(<2 x i32> [[C]])1938; ALL-NEXT: [[D:%.*]] = trunc nuw nsw <2 x i32> [[C]] to <2 x i8>1939; ALL-NEXT: ret <2 x i8> [[D]]1940;1941 %B = sext <2 x i8> %A to <2 x i32>1942 %C = lshr <2 x i32> %B, <i32 25, i32 25>1943 call void @use_v2i32(<2 x i32> %C)1944 %D = trunc <2 x i32> %C to <2 x i8>1945 ret <2 x i8> %D1946}1947 1948define i8 @trunc_lshr_overshift2_sext_uses3(i8 %A) {1949; ALL-LABEL: @trunc_lshr_overshift2_sext_uses3(1950; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i321951; ALL-NEXT: call void @use_i32(i32 [[B]])1952; ALL-NEXT: [[C:%.*]] = lshr i32 [[B]], 251953; ALL-NEXT: call void @use_i32(i32 [[C]])1954; ALL-NEXT: [[D:%.*]] = trunc nuw nsw i32 [[C]] to i81955; ALL-NEXT: ret i8 [[D]]1956;1957 %B = sext i8 %A to i321958 call void @use_i32(i32 %B)1959 %C = lshr i32 %B, 251960 call void @use_i32(i32 %C)1961 %D = trunc i32 %C to i81962 ret i8 %D1963}1964 1965define i8 @trunc_lshr_zext(i8 %A) {1966; ALL-LABEL: @trunc_lshr_zext(1967; ALL-NEXT: [[TMP1:%.*]] = lshr i8 [[A:%.*]], 61968; ALL-NEXT: ret i8 [[TMP1]]1969;1970 %B = zext i8 %A to i321971 %C = lshr i32 %B, 61972 %D = trunc i32 %C to i81973 ret i8 %D1974}1975 1976define i8 @trunc_lshr_zext_exact(i8 %A) {1977; ALL-LABEL: @trunc_lshr_zext_exact(1978; ALL-NEXT: [[TMP1:%.*]] = lshr i8 [[A:%.*]], 61979; ALL-NEXT: ret i8 [[TMP1]]1980;1981 %B = zext i8 %A to i321982 %C = lshr exact i32 %B, 61983 %D = trunc i32 %C to i81984 ret i8 %D1985}1986 1987define <2 x i8> @trunc_lshr_zext_uniform(<2 x i8> %A) {1988; ALL-LABEL: @trunc_lshr_zext_uniform(1989; ALL-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[A:%.*]], splat (i8 6)1990; ALL-NEXT: ret <2 x i8> [[TMP1]]1991;1992 %B = zext <2 x i8> %A to <2 x i32>1993 %C = lshr <2 x i32> %B, <i32 6, i32 6>1994 %D = trunc <2 x i32> %C to <2 x i8>1995 ret <2 x i8> %D1996}1997 1998define <2 x i8> @trunc_lshr_zext_uniform_poison(<2 x i8> %A) {1999; ALL-LABEL: @trunc_lshr_zext_uniform_poison(2000; ALL-NEXT: [[C:%.*]] = lshr <2 x i8> [[A:%.*]], <i8 6, i8 poison>2001; ALL-NEXT: ret <2 x i8> [[C]]2002;2003 %B = zext <2 x i8> %A to <2 x i32>2004 %C = lshr <2 x i32> %B, <i32 6, i32 poison>2005 %D = trunc <2 x i32> %C to <2 x i8>2006 ret <2 x i8> %D2007}2008 2009define <2 x i8> @trunc_lshr_zext_nonuniform(<2 x i8> %A) {2010; ALL-LABEL: @trunc_lshr_zext_nonuniform(2011; ALL-NEXT: [[C:%.*]] = lshr <2 x i8> [[A:%.*]], <i8 6, i8 2>2012; ALL-NEXT: ret <2 x i8> [[C]]2013;2014 %B = zext <2 x i8> %A to <2 x i32>2015 %C = lshr <2 x i32> %B, <i32 6, i32 2>2016 %D = trunc <2 x i32> %C to <2 x i8>2017 ret <2 x i8> %D2018}2019 2020define <3 x i8> @trunc_lshr_zext_nonuniform_poison(<3 x i8> %A) {2021; ALL-LABEL: @trunc_lshr_zext_nonuniform_poison(2022; ALL-NEXT: [[C:%.*]] = lshr <3 x i8> [[A:%.*]], <i8 6, i8 2, i8 poison>2023; ALL-NEXT: ret <3 x i8> [[C]]2024;2025 %B = zext <3 x i8> %A to <3 x i32>2026 %C = lshr <3 x i32> %B, <i32 6, i32 2, i32 poison>2027 %D = trunc <3 x i32> %C to <3 x i8>2028 ret <3 x i8> %D2029}2030 2031define <2 x i8> @trunc_lshr_zext_uses1(<2 x i8> %A) {2032; ALL-LABEL: @trunc_lshr_zext_uses1(2033; ALL-NEXT: [[B:%.*]] = zext <2 x i8> [[A:%.*]] to <2 x i32>2034; ALL-NEXT: call void @use_v2i32(<2 x i32> [[B]])2035; ALL-NEXT: [[C:%.*]] = lshr <2 x i8> [[A]], splat (i8 6)2036; ALL-NEXT: ret <2 x i8> [[C]]2037;2038 %B = zext <2 x i8> %A to <2 x i32>2039 call void @use_v2i32(<2 x i32> %B)2040 %C = lshr <2 x i32> %B, <i32 6, i32 6>2041 %D = trunc <2 x i32> %C to <2 x i8>2042 ret <2 x i8> %D2043}2044 2045define i8 @trunc_lshr_ext_halfWidth(i16 %a, i16 %b, i16 range(i16 0, 8) %shiftAmt) {2046; ALL-LABEL: @trunc_lshr_ext_halfWidth(2047; ALL-NEXT: [[ADD:%.*]] = add i16 [[A:%.*]], [[B:%.*]]2048; ALL-NEXT: [[SHR:%.*]] = lshr i16 [[ADD]], [[SHIFTAMT:%.*]]2049; ALL-NEXT: [[TRUNC:%.*]] = trunc i16 [[SHR]] to i82050; ALL-NEXT: ret i8 [[TRUNC]]2051;2052 %zext_a = zext i16 %a to i322053 %zext_b = zext i16 %b to i322054 %zext_shiftAmt = zext i16 %shiftAmt to i322055 %add = add nuw nsw i32 %zext_a, %zext_b2056 %shr = lshr i32 %add, %zext_shiftAmt2057 %trunc = trunc i32 %shr to i82058 ret i8 %trunc2059}2060 2061define i8 @trunc_lshr_ext_halfWidth_rhsOutofRange_neg(i16 %a, i16 %b, i16 range(i16 0, 10) %shiftAmt) {2062; ALL-LABEL: @trunc_lshr_ext_halfWidth_rhsOutofRange_neg(2063; ALL-NEXT: [[ZEXT_A:%.*]] = zext i16 [[A:%.*]] to i322064; ALL-NEXT: [[ZEXT_B:%.*]] = zext i16 [[B:%.*]] to i322065; ALL-NEXT: [[ZEXT_SHIFTAMT:%.*]] = zext nneg i16 [[SHIFTAMT:%.*]] to i322066; ALL-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]2067; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], [[ZEXT_SHIFTAMT]]2068; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i82069; ALL-NEXT: ret i8 [[TRUNC]]2070;2071 %zext_a = zext i16 %a to i322072 %zext_b = zext i16 %b to i322073 %zext_shiftAmt = zext i16 %shiftAmt to i322074 %add = add nuw nsw i32 %zext_a, %zext_b2075 %shr = lshr i32 %add, %zext_shiftAmt2076 %trunc = trunc i32 %shr to i82077 ret i8 %trunc2078}2079 2080define i8 @trunc_lshr_ext_halfWidth_rhsNoRange_neg(i16 %a, i16 %b, i16 %shiftAmt) {2081; ALL-LABEL: @trunc_lshr_ext_halfWidth_rhsNoRange_neg(2082; ALL-NEXT: [[ZEXT_A:%.*]] = zext i16 [[A:%.*]] to i322083; ALL-NEXT: [[ZEXT_B:%.*]] = zext i16 [[B:%.*]] to i322084; ALL-NEXT: [[ZEXT_SHIFTAMT:%.*]] = zext nneg i16 [[SHIFTAMT:%.*]] to i322085; ALL-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]2086; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], [[ZEXT_SHIFTAMT]]2087; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i82088; ALL-NEXT: ret i8 [[TRUNC]]2089;2090 %zext_a = zext i16 %a to i322091 %zext_b = zext i16 %b to i322092 %zext_shiftAmt = zext i16 %shiftAmt to i322093 %add = add nuw nsw i32 %zext_a, %zext_b2094 %shr = lshr i32 %add, %zext_shiftAmt2095 %trunc = trunc i32 %shr to i82096 ret i8 %trunc2097}2098 2099define i8 @trunc_lshr_ext_halfWidth_twouse_neg1(i16 %a, i16 %b, i16 range(i16 0, 8) %shiftAmt) {2100; ALL-LABEL: @trunc_lshr_ext_halfWidth_twouse_neg1(2101; ALL-NEXT: [[ZEXT_A:%.*]] = zext i16 [[A:%.*]] to i322102; ALL-NEXT: [[ZEXT_B:%.*]] = zext i16 [[B:%.*]] to i322103; ALL-NEXT: [[ZEXT_SHIFTAMT:%.*]] = zext nneg i16 [[SHIFTAMT:%.*]] to i322104; ALL-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]2105; ALL-NEXT: call void @use_i32(i32 [[ADD]])2106; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], [[ZEXT_SHIFTAMT]]2107; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i82108; ALL-NEXT: ret i8 [[TRUNC]]2109;2110 %zext_a = zext i16 %a to i322111 %zext_b = zext i16 %b to i322112 %zext_shiftAmt = zext i16 %shiftAmt to i322113 %add = add nuw nsw i32 %zext_a, %zext_b2114 call void @use_i32(i32 %add)2115 %shr = lshr i32 %add, %zext_shiftAmt2116 %trunc = trunc i32 %shr to i82117 ret i8 %trunc2118}2119 2120define i8 @trunc_lshr_ext_halfWidth_twouse_neg2(i16 %a, i16 %b, i16 range(i16 0, 8) %shiftAmt) {2121; ALL-LABEL: @trunc_lshr_ext_halfWidth_twouse_neg2(2122; ALL-NEXT: [[ZEXT_A:%.*]] = zext i16 [[A:%.*]] to i322123; ALL-NEXT: [[ZEXT_B:%.*]] = zext i16 [[B:%.*]] to i322124; ALL-NEXT: [[ZEXT_SHIFTAMT:%.*]] = zext nneg i16 [[SHIFTAMT:%.*]] to i322125; ALL-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]2126; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], [[ZEXT_SHIFTAMT]]2127; ALL-NEXT: call void @use_i32(i32 [[SHR]])2128; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i82129; ALL-NEXT: ret i8 [[TRUNC]]2130;2131 %zext_a = zext i16 %a to i322132 %zext_b = zext i16 %b to i322133 %zext_shiftAmt = zext i16 %shiftAmt to i322134 %add = add nuw nsw i32 %zext_a, %zext_b2135 %shr = lshr i32 %add, %zext_shiftAmt2136 call void @use_i32(i32 %shr)2137 %trunc = trunc i32 %shr to i82138 ret i8 %trunc2139}2140 2141; The narrowing transform only happens for integer types.2142define <2 x i8> @trunc_lshr_ext_halfWidth_vector_neg(<2 x i16> %a, <2 x i16> %b) {2143; ALL-LABEL: @trunc_lshr_ext_halfWidth_vector_neg(2144; ALL-NEXT: [[ZEXT_A:%.*]] = zext <2 x i16> [[A:%.*]] to <2 x i32>2145; ALL-NEXT: [[ZEXT_B:%.*]] = zext <2 x i16> [[B:%.*]] to <2 x i32>2146; ALL-NEXT: [[ADD:%.*]] = add nuw nsw <2 x i32> [[ZEXT_A]], [[ZEXT_B]]2147; ALL-NEXT: [[SHR:%.*]] = lshr <2 x i32> [[ADD]], splat (i32 6)2148; ALL-NEXT: [[TRUNC:%.*]] = trunc <2 x i32> [[SHR]] to <2 x i8>2149; ALL-NEXT: ret <2 x i8> [[TRUNC]]2150;2151 %zext_a = zext <2 x i16> %a to <2 x i32>2152 %zext_b = zext <2 x i16> %b to <2 x i32>2153 %add = add nuw nsw <2 x i32> %zext_a, %zext_b2154 %shr = lshr <2 x i32> %add, <i32 6, i32 6>2155 %trunc = trunc <2 x i32> %shr to <2 x i8>2156 ret <2 x i8> %trunc2157}2158 2159; The following four tests sext + lshr + trunc patterns.2160; PR330782161 2162define i8 @pr33078_1(i8 %A) {2163; ALL-LABEL: @pr33078_1(2164; ALL-NEXT: [[TMP1:%.*]] = ashr i8 [[A:%.*]], 72165; ALL-NEXT: ret i8 [[TMP1]]2166;2167 %B = sext i8 %A to i162168 %C = lshr i16 %B, 82169 %D = trunc i16 %C to i82170 ret i8 %D2171}2172 2173define i12 @pr33078_2(i8 %A) {2174; ALL-LABEL: @pr33078_2(2175; ALL-NEXT: [[TMP1:%.*]] = ashr i8 [[A:%.*]], 42176; ALL-NEXT: [[D:%.*]] = sext i8 [[TMP1]] to i122177; ALL-NEXT: ret i12 [[D]]2178;2179 %B = sext i8 %A to i162180 %C = lshr i16 %B, 42181 %D = trunc i16 %C to i122182 ret i12 %D2183}2184 2185define i4 @pr33078_3(i8 %A) {2186; ALL-LABEL: @pr33078_3(2187; ALL-NEXT: [[B:%.*]] = sext i8 [[A:%.*]] to i162188; ALL-NEXT: [[C:%.*]] = lshr i16 [[B]], 122189; ALL-NEXT: [[D:%.*]] = trunc nuw i16 [[C]] to i42190; ALL-NEXT: ret i4 [[D]]2191;2192 %B = sext i8 %A to i162193 %C = lshr i16 %B, 122194 %D = trunc i16 %C to i42195 ret i4 %D2196}2197 2198define i8 @pr33078_4(i3 %x) {2199; Don't turn this in an `ashr`. This was getting miscompiled2200; ALL-LABEL: @pr33078_4(2201; ALL-NEXT: [[B:%.*]] = sext i3 [[X:%.*]] to i162202; ALL-NEXT: [[C:%.*]] = lshr i16 [[B]], 132203; ALL-NEXT: [[D:%.*]] = trunc nuw nsw i16 [[C]] to i82204; ALL-NEXT: ret i8 [[D]]2205;2206 %B = sext i3 %x to i162207 %C = lshr i16 %B, 132208 %D = trunc i16 %C to i82209 ret i8 %D2210}2211 2212; (sext (xor (cmp), -1)) -> (sext (!cmp))2213define i64 @test94(i32 %a) {2214; ALL-LABEL: @test94(2215; ALL-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], -22216; ALL-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i642217; ALL-NEXT: ret i64 [[TMP2]]2218;2219 %1 = icmp eq i32 %a, -22220 %2 = sext i1 %1 to i82221 %3 = xor i8 %2, -12222 %4 = sext i8 %3 to i642223 ret i64 %42224}2225 2226; We should be able to remove the zext and trunc here.2227define i32 @test95(i32 %x) {2228; ALL-LABEL: @test95(2229; ALL-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 62230; ALL-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 22231; ALL-NEXT: [[TMP3:%.*]] = or disjoint i32 [[TMP2]], 402232; ALL-NEXT: ret i32 [[TMP3]]2233;2234 %1 = trunc i32 %x to i82235 %2 = lshr i8 %1, 62236 %3 = and i8 %2, 22237 %4 = or i8 %3, 402238 %5 = zext i8 %4 to i322239 ret i32 %52240}2241 2242define i16 @test96(i16 %x, i16 %y) {2243; ALL-LABEL: @test96(2244; ALL-NEXT: [[A:%.*]] = add i16 [[X:%.*]], [[Y:%.*]]2245; ALL-NEXT: [[B:%.*]] = add i16 [[A]], 52246; ALL-NEXT: [[C:%.*]] = mul i16 [[A]], 32247; ALL-NEXT: [[T:%.*]] = or i16 [[B]], [[C]]2248; ALL-NEXT: ret i16 [[T]]2249;2250 %zx = zext i16 %x to i322251 %zy = zext i16 %y to i322252 %a = add i32 %zx, %zy2253 %b = add i32 %a, 52254 %c = mul i32 %a, 32255 %d = or i32 %b, %c2256 %t = trunc i32 %d to i162257 ret i16 %t2258}2259 2260define i16 @test97(i16 %x, i16 %y) {2261; ALL-LABEL: @test97(2262; ALL-NEXT: [[ZX:%.*]] = zext i16 [[X:%.*]] to i322263; ALL-NEXT: [[ZY:%.*]] = zext i16 [[Y:%.*]] to i322264; ALL-NEXT: [[A:%.*]] = add nuw nsw i32 [[ZX]], [[ZY]]2265; ALL-NEXT: [[B:%.*]] = add nuw nsw i32 [[A]], 52266; ALL-NEXT: [[C:%.*]] = mul nuw nsw i32 [[A]], 32267; ALL-NEXT: [[D:%.*]] = or i32 [[B]], [[C]]2268; ALL-NEXT: call void @use_i32(i32 [[A]])2269; ALL-NEXT: [[T:%.*]] = trunc i32 [[D]] to i162270; ALL-NEXT: ret i16 [[T]]2271;2272 %zx = zext i16 %x to i322273 %zy = zext i16 %y to i322274 %a = add i32 %zx, %zy2275 %b = add i32 %a, 52276 %c = mul i32 %a, 32277 %d = or i32 %b, %c2278 call void @use_i32(i32 %a)2279 %t = trunc i32 %d to i162280 ret i16 %t2281}2282 2283; expected not to narrow operations to i16 due to a loop in use chains2284define i16 @test98(i16 %x, i16 %n) {2285; ALL-LABEL: @test98(2286; ALL-NEXT: entry:2287; ALL-NEXT: [[Z:%.*]] = zext i16 [[X:%.*]] to i322288; ALL-NEXT: br label [[LOOP:%.*]]2289; ALL: loop:2290; ALL-NEXT: [[P:%.*]] = phi i32 [ [[Z]], [[ENTRY:%.*]] ], [ [[A:%.*]], [[LOOP]] ]2291; ALL-NEXT: [[A]] = add i32 [[P]], 12292; ALL-NEXT: [[T:%.*]] = trunc i32 [[A]] to i162293; ALL-NEXT: [[COND:%.*]] = icmp ugt i16 [[N:%.*]], [[T]]2294; ALL-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]2295; ALL: exit:2296; ALL-NEXT: ret i16 [[T]]2297;2298entry:2299 %z = zext i16 %x to i322300 br label %loop2301 2302loop:2303 %p = phi i32 [ %z, %entry ], [ %a, %loop ]2304 %a = add i32 %p, 12305 %t = trunc i32 %a to i162306 %cond = icmp ult i16 %t, %n2307 br i1 %cond, label %loop, label %exit2308 2309exit:2310 ret i16 %t2311}2312 2313define i32 @test99(i32 %x, i32 %y) {2314; ALL-LABEL: @test99(2315; ALL-NEXT: [[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]2316; ALL-NEXT: [[B:%.*]] = add i32 [[A]], 52317; ALL-NEXT: [[C:%.*]] = mul i32 [[A]], 32318; ALL-NEXT: [[D:%.*]] = or i32 [[B]], [[C]]2319; ALL-NEXT: [[SEXT:%.*]] = shl i32 [[D]], 162320; ALL-NEXT: [[S:%.*]] = ashr exact i32 [[SEXT]], 162321; ALL-NEXT: ret i32 [[S]]2322;2323 %tx = trunc i32 %x to i162324 %ty = trunc i32 %y to i162325 %a = add i16 %tx, %ty2326 %b = add i16 %a, 52327 %c = mul i16 %a, 32328 %d = or i16 %b, %c2329 %t = sext i16 %d to i322330 ret i32 %t2331}2332 2333define i32 @test100(i32 %x, i32 %y) {2334; ALL-LABEL: @test100(2335; ALL-NEXT: [[TX:%.*]] = trunc i32 [[X:%.*]] to i82336; ALL-NEXT: [[TY:%.*]] = trunc i32 [[Y:%.*]] to i82337; ALL-NEXT: [[A:%.*]] = add i8 [[TX]], [[TY]]2338; ALL-NEXT: [[B:%.*]] = add i8 [[A]], 52339; ALL-NEXT: [[C:%.*]] = mul i8 [[A]], 32340; ALL-NEXT: [[D:%.*]] = or i8 [[B]], [[C]]2341; ALL-NEXT: call void @use_i8(i8 [[A]])2342; ALL-NEXT: [[T:%.*]] = sext i8 [[D]] to i322343; ALL-NEXT: ret i32 [[T]]2344;2345 %tx = trunc i32 %x to i82346 %ty = trunc i32 %y to i82347 %a = add i8 %tx, %ty2348 %b = add i8 %a, 52349 %c = mul i8 %a, 32350 %d = or i8 %b, %c2351 call void @use_i8(i8 %a)2352 %t = sext i8 %d to i322353 ret i32 %t2354}2355 2356; expected not to extend operations to i32 due to a loop in use chains2357define i32 @test101(i32 %x, i8 %n) {2358; ALL-LABEL: @test101(2359; ALL-NEXT: entry:2360; ALL-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i82361; ALL-NEXT: br label [[LOOP:%.*]]2362; ALL: loop:2363; ALL-NEXT: [[P:%.*]] = phi i8 [ [[T]], [[ENTRY:%.*]] ], [ [[A:%.*]], [[LOOP]] ]2364; ALL-NEXT: [[A]] = add i8 [[P]], 12365; ALL-NEXT: [[COND:%.*]] = icmp ult i8 [[A]], [[N:%.*]]2366; ALL-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]2367; ALL: exit:2368; ALL-NEXT: [[S:%.*]] = sext i8 [[A]] to i322369; ALL-NEXT: ret i32 [[S]]2370;2371entry:2372 %t = trunc i32 %x to i82373 br label %loop2374 2375loop:2376 %p = phi i8 [ %t, %entry ], [ %a, %loop ]2377 %a = add i8 %p, 12378 %cond = icmp ult i8 %a, %n2379 br i1 %cond, label %loop, label %exit2380 2381exit:2382 %s = sext i8 %a to i322383 ret i32 %s2384}2385