brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.3 KiB · f83352c Raw
1020 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"4 5; Instcombine should be able to eliminate all of these ext casts.6 7declare void @use(i32)8declare void @use_vec(<2 x i32>)9 10define i64 @test1(i64 %a) {11; CHECK-LABEL: @test1(12; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i3213; CHECK-NEXT:    [[C:%.*]] = and i64 [[A]], 1514; CHECK-NEXT:    call void @use(i32 [[B]])15; CHECK-NEXT:    ret i64 [[C]]16;17  %b = trunc i64 %a to i3218  %c = and i32 %b, 1519  %d = zext i32 %c to i6420  call void @use(i32 %b)21  ret i64 %d22}23 24define <2 x i64> @test1_vec(<2 x i64> %a) {25; CHECK-LABEL: @test1_vec(26; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>27; CHECK-NEXT:    [[D:%.*]] = and <2 x i64> [[A]], splat (i64 15)28; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])29; CHECK-NEXT:    ret <2 x i64> [[D]]30;31  %b = trunc <2 x i64> %a to <2 x i32>32  %c = and <2 x i32> %b, <i32 15, i32 15>33  %d = zext <2 x i32> %c to <2 x i64>34  call void @use_vec(<2 x i32> %b)35  ret <2 x i64> %d36}37 38define <2 x i64> @test1_vec_nonuniform(<2 x i64> %a) {39; CHECK-LABEL: @test1_vec_nonuniform(40; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>41; CHECK-NEXT:    [[D:%.*]] = and <2 x i64> [[A]], <i64 15, i64 7>42; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])43; CHECK-NEXT:    ret <2 x i64> [[D]]44;45  %b = trunc <2 x i64> %a to <2 x i32>46  %c = and <2 x i32> %b, <i32 15, i32 7>47  %d = zext <2 x i32> %c to <2 x i64>48  call void @use_vec(<2 x i32> %b)49  ret <2 x i64> %d50}51 52define <2 x i64> @test1_vec_poison(<2 x i64> %a) {53; CHECK-LABEL: @test1_vec_poison(54; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>55; CHECK-NEXT:    [[D:%.*]] = and <2 x i64> [[A]], <i64 15, i64 poison>56; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])57; CHECK-NEXT:    ret <2 x i64> [[D]]58;59  %b = trunc <2 x i64> %a to <2 x i32>60  %c = and <2 x i32> %b, <i32 15, i32 poison>61  %d = zext <2 x i32> %c to <2 x i64>62  call void @use_vec(<2 x i32> %b)63  ret <2 x i64> %d64}65 66define i64 @test2(i64 %a) {67; CHECK-LABEL: @test2(68; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i3269; CHECK-NEXT:    [[D1:%.*]] = shl i64 [[A]], 3670; CHECK-NEXT:    [[D:%.*]] = ashr exact i64 [[D1]], 3671; CHECK-NEXT:    call void @use(i32 [[B]])72; CHECK-NEXT:    ret i64 [[D]]73;74  %b = trunc i64 %a to i3275  %c = shl i32 %b, 476  %q = ashr i32 %c, 477  %d = sext i32 %q to i6478  call void @use(i32 %b)79  ret i64 %d80}81 82define <2 x i64> @test2_vec(<2 x i64> %a) {83; CHECK-LABEL: @test2_vec(84; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>85; CHECK-NEXT:    [[D1:%.*]] = shl <2 x i64> [[A]], splat (i64 36)86; CHECK-NEXT:    [[D:%.*]] = ashr exact <2 x i64> [[D1]], splat (i64 36)87; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])88; CHECK-NEXT:    ret <2 x i64> [[D]]89;90  %b = trunc <2 x i64> %a to <2 x i32>91  %c = shl <2 x i32> %b, <i32 4, i32 4>92  %q = ashr <2 x i32> %c, <i32 4, i32 4>93  %d = sext <2 x i32> %q to <2 x i64>94  call void @use_vec(<2 x i32> %b)95  ret <2 x i64> %d96}97 98define <2 x i64> @test2_vec_nonuniform(<2 x i64> %a) {99; CHECK-LABEL: @test2_vec_nonuniform(100; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>101; CHECK-NEXT:    [[D1:%.*]] = shl <2 x i64> [[A]], <i64 36, i64 37>102; CHECK-NEXT:    [[D:%.*]] = ashr exact <2 x i64> [[D1]], <i64 36, i64 37>103; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])104; CHECK-NEXT:    ret <2 x i64> [[D]]105;106  %b = trunc <2 x i64> %a to <2 x i32>107  %c = shl <2 x i32> %b, <i32 4, i32 5>108  %q = ashr <2 x i32> %c, <i32 4, i32 5>109  %d = sext <2 x i32> %q to <2 x i64>110  call void @use_vec(<2 x i32> %b)111  ret <2 x i64> %d112}113 114define <2 x i64> @test2_vec_poison(<2 x i64> %a) {115; CHECK-LABEL: @test2_vec_poison(116; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>117; CHECK-NEXT:    [[D1:%.*]] = shl <2 x i64> [[A]], <i64 36, i64 poison>118; CHECK-NEXT:    [[D:%.*]] = ashr exact <2 x i64> [[D1]], <i64 36, i64 poison>119; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])120; CHECK-NEXT:    ret <2 x i64> [[D]]121;122  %b = trunc <2 x i64> %a to <2 x i32>123  %c = shl <2 x i32> %b, <i32 4, i32 poison>124  %q = ashr <2 x i32> %c, <i32 4, i32 poison>125  %d = sext <2 x i32> %q to <2 x i64>126  call void @use_vec(<2 x i32> %b)127  ret <2 x i64> %d128}129 130define i64 @test3(i64 %a) {131; CHECK-LABEL: @test3(132; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i32133; CHECK-NEXT:    [[C:%.*]] = and i64 [[A]], 8134; CHECK-NEXT:    call void @use(i32 [[B]])135; CHECK-NEXT:    ret i64 [[C]]136;137  %b = trunc i64 %a to i32138  %c = and i32 %b, 8139  %d = zext i32 %c to i64140  call void @use(i32 %b)141  ret i64 %d142}143 144define i64 @test4(i64 %a) {145; CHECK-LABEL: @test4(146; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i32147; CHECK-NEXT:    [[C:%.*]] = and i64 [[A]], 8148; CHECK-NEXT:    [[X:%.*]] = xor i64 [[C]], 8149; CHECK-NEXT:    call void @use(i32 [[B]])150; CHECK-NEXT:    ret i64 [[X]]151;152  %b = trunc i64 %a to i32153  %c = and i32 %b, 8154  %x = xor i32 %c, 8155  %d = zext i32 %x to i64156  call void @use(i32 %b)157  ret i64 %d158}159 160define i32 @test5(i32 %A) {161; CHECK-LABEL: @test5(162; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[A:%.*]], 16163; CHECK-NEXT:    ret i32 [[TMP1]]164;165  %B = zext i32 %A to i128166  %C = lshr i128 %B, 16167  %D = trunc i128 %C to i32168  ret i32 %D169}170 171define i32 @test6(i64 %A) {172; CHECK-LABEL: @test6(173; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[A:%.*]], 32174; CHECK-NEXT:    [[D:%.*]] = trunc nuw i64 [[TMP1]] to i32175; CHECK-NEXT:    ret i32 [[D]]176;177  %B = zext i64 %A to i128178  %C = lshr i128 %B, 32179  %D = trunc i128 %C to i32180  ret i32 %D181}182 183; Test case where 'ashr' demanded bits does not contain any of the high bits,184; but does contain sign bits, where the sign bit is not known to be zero.185define i16 @ashr_mul_sign_bits(i8 %X, i8 %Y) {186; CHECK-LABEL: @ashr_mul_sign_bits(187; CHECK-NEXT:    [[A:%.*]] = sext i8 [[X:%.*]] to i16188; CHECK-NEXT:    [[B:%.*]] = sext i8 [[Y:%.*]] to i16189; CHECK-NEXT:    [[C:%.*]] = mul nsw i16 [[A]], [[B]]190; CHECK-NEXT:    [[D:%.*]] = ashr i16 [[C]], 3191; CHECK-NEXT:    ret i16 [[D]]192;193  %A = sext i8 %X to i32194  %B = sext i8 %Y to i32195  %C = mul i32 %A, %B196  %D = ashr i32 %C, 3197  %E = trunc i32 %D to i16198  ret i16 %E199}200 201define i16 @ashr_mul(i8 %X, i8 %Y) {202; CHECK-LABEL: @ashr_mul(203; CHECK-NEXT:    [[A:%.*]] = sext i8 [[X:%.*]] to i16204; CHECK-NEXT:    [[B:%.*]] = sext i8 [[Y:%.*]] to i16205; CHECK-NEXT:    [[C:%.*]] = mul nsw i16 [[A]], [[B]]206; CHECK-NEXT:    [[D:%.*]] = ashr i16 [[C]], 8207; CHECK-NEXT:    ret i16 [[D]]208;209  %A = sext i8 %X to i20210  %B = sext i8 %Y to i20211  %C = mul i20 %A, %B212  %D = ashr i20 %C, 8213  %E = trunc i20 %D to i16214  ret i16 %E215}216 217define i32 @trunc_ashr(i32 %X) {218; CHECK-LABEL: @trunc_ashr(219; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8220; CHECK-NEXT:    [[C:%.*]] = or i32 [[TMP1]], -8388608221; CHECK-NEXT:    ret i32 [[C]]222;223  %A = zext i32 %X to i36224  %B = or i36 %A, -2147483648 ; 0xF80000000225  %C = ashr i36 %B, 8226  %T = trunc i36 %C to i32227  ret i32  %T228}229 230define <2 x i32> @trunc_ashr_vec(<2 x i32> %X) {231; CHECK-LABEL: @trunc_ashr_vec(232; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 8)233; CHECK-NEXT:    [[C:%.*]] = or <2 x i32> [[TMP1]], splat (i32 -8388608)234; CHECK-NEXT:    ret <2 x i32> [[C]]235;236  %A = zext <2 x i32> %X to <2 x i36>237  %B = or <2 x i36> %A, <i36 -2147483648, i36 -2147483648> ; 0xF80000000238  %C = ashr <2 x i36> %B, <i36 8, i36 8>239  %T = trunc <2 x i36> %C to <2 x i32>240  ret <2 x i32>  %T241}242 243define i92 @test7(i64 %A) {244; CHECK-LABEL: @test7(245; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[A:%.*]], 32246; CHECK-NEXT:    [[D:%.*]] = zext nneg i64 [[TMP1]] to i92247; CHECK-NEXT:    ret i92 [[D]]248;249  %B = zext i64 %A to i128250  %C = lshr i128 %B, 32251  %D = trunc i128 %C to i92252  ret i92 %D253}254 255define i64 @test8(i32 %A, i32 %B) {256; CHECK-LABEL: @test8(257; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i64258; CHECK-NEXT:    [[D:%.*]] = zext i32 [[B:%.*]] to i64259; CHECK-NEXT:    [[E:%.*]] = shl nuw i64 [[D]], 32260; CHECK-NEXT:    [[F:%.*]] = or disjoint i64 [[E]], [[C]]261; CHECK-NEXT:    ret i64 [[F]]262;263  %C = zext i32 %A to i128264  %D = zext i32 %B to i128265  %E = shl i128 %D, 32266  %F = or i128 %E, %C267  %G = trunc i128 %F to i64268  ret i64 %G269}270 271define <2 x i64> @test8_vec(<2 x i32> %A, <2 x i32> %B) {272; CHECK-LABEL: @test8_vec(273; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>274; CHECK-NEXT:    [[D:%.*]] = zext <2 x i32> [[B:%.*]] to <2 x i64>275; CHECK-NEXT:    [[E:%.*]] = shl nuw <2 x i64> [[D]], splat (i64 32)276; CHECK-NEXT:    [[F:%.*]] = or disjoint <2 x i64> [[E]], [[C]]277; CHECK-NEXT:    ret <2 x i64> [[F]]278;279  %C = zext <2 x i32> %A to <2 x i128>280  %D = zext <2 x i32> %B to <2 x i128>281  %E = shl <2 x i128> %D, <i128 32, i128 32>282  %F = or <2 x i128> %E, %C283  %G = trunc <2 x i128> %F to <2 x i64>284  ret <2 x i64> %G285}286 287define <2 x i64> @test8_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {288; CHECK-LABEL: @test8_vec_nonuniform(289; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>290; CHECK-NEXT:    [[D:%.*]] = zext <2 x i32> [[B:%.*]] to <2 x i64>291; CHECK-NEXT:    [[E:%.*]] = shl <2 x i64> [[D]], <i64 32, i64 48>292; CHECK-NEXT:    [[F:%.*]] = or disjoint <2 x i64> [[E]], [[C]]293; CHECK-NEXT:    ret <2 x i64> [[F]]294;295  %C = zext <2 x i32> %A to <2 x i128>296  %D = zext <2 x i32> %B to <2 x i128>297  %E = shl <2 x i128> %D, <i128 32, i128 48>298  %F = or <2 x i128> %E, %C299  %G = trunc <2 x i128> %F to <2 x i64>300  ret <2 x i64> %G301}302 303define <2 x i64> @test8_vec_poison(<2 x i32> %A, <2 x i32> %B) {304; CHECK-LABEL: @test8_vec_poison(305; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>306; CHECK-NEXT:    [[D:%.*]] = zext <2 x i32> [[B:%.*]] to <2 x i64>307; CHECK-NEXT:    [[E:%.*]] = shl nuw <2 x i64> [[D]], <i64 32, i64 poison>308; CHECK-NEXT:    [[G:%.*]] = or disjoint <2 x i64> [[E]], [[C]]309; CHECK-NEXT:    ret <2 x i64> [[G]]310;311  %C = zext <2 x i32> %A to <2 x i128>312  %D = zext <2 x i32> %B to <2 x i128>313  %E = shl <2 x i128> %D, <i128 32, i128 poison>314  %F = or <2 x i128> %E, %C315  %G = trunc <2 x i128> %F to <2 x i64>316  ret <2 x i64> %G317}318 319define i8 @test9(i32 %X) {320; CHECK-LABEL: @test9(321; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8322; CHECK-NEXT:    [[Z:%.*]] = and i8 [[TMP1]], 42323; CHECK-NEXT:    ret i8 [[Z]]324;325  %Y = and i32 %X, 42326  %Z = trunc i32 %Y to i8327  ret i8 %Z328}329 330; rdar://8808586331define i8 @test10(i32 %X) {332; CHECK-LABEL: @test10(333; CHECK-NEXT:    [[Y:%.*]] = trunc i32 [[X:%.*]] to i8334; CHECK-NEXT:    [[Z:%.*]] = and i8 [[Y]], 42335; CHECK-NEXT:    ret i8 [[Z]]336;337  %Y = trunc i32 %X to i8338  %Z = and i8 %Y, 42339  ret i8 %Z340}341 342define i64 @test11(i32 %A, i32 %B) {343; CHECK-LABEL: @test11(344; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i64345; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], 31346; CHECK-NEXT:    [[E:%.*]] = zext nneg i32 [[TMP1]] to i64347; CHECK-NEXT:    [[F:%.*]] = shl nuw nsw i64 [[C]], [[E]]348; CHECK-NEXT:    ret i64 [[F]]349;350  %C = zext i32 %A to i128351  %D = zext i32 %B to i128352  %E = and i128 %D, 31353  %F = shl i128 %C, %E354  %G = trunc i128 %F to i64355  ret i64 %G356}357 358define <2 x i64> @test11_vec(<2 x i32> %A, <2 x i32> %B) {359; CHECK-LABEL: @test11_vec(360; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>361; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], splat (i32 31)362; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>363; CHECK-NEXT:    [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]364; CHECK-NEXT:    ret <2 x i64> [[F]]365;366  %C = zext <2 x i32> %A to <2 x i128>367  %D = zext <2 x i32> %B to <2 x i128>368  %E = and <2 x i128> %D, <i128 31, i128 31>369  %F = shl <2 x i128> %C, %E370  %G = trunc <2 x i128> %F to <2 x i64>371  ret <2 x i64> %G372}373 374define <2 x i64> @test11_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {375; CHECK-LABEL: @test11_vec_nonuniform(376; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>377; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>378; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>379; CHECK-NEXT:    [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]380; CHECK-NEXT:    ret <2 x i64> [[F]]381;382  %C = zext <2 x i32> %A to <2 x i128>383  %D = zext <2 x i32> %B to <2 x i128>384  %E = and <2 x i128> %D, <i128 31, i128 15>385  %F = shl <2 x i128> %C, %E386  %G = trunc <2 x i128> %F to <2 x i64>387  ret <2 x i64> %G388}389 390define <2 x i64> @test11_vec_poison(<2 x i32> %A, <2 x i32> %B) {391; CHECK-LABEL: @test11_vec_poison(392; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>393; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 poison>394; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>395; CHECK-NEXT:    [[G:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]396; CHECK-NEXT:    ret <2 x i64> [[G]]397;398  %C = zext <2 x i32> %A to <2 x i128>399  %D = zext <2 x i32> %B to <2 x i128>400  %E = and <2 x i128> %D, <i128 31, i128 poison>401  %F = shl <2 x i128> %C, %E402  %G = trunc <2 x i128> %F to <2 x i64>403  ret <2 x i64> %G404}405 406define i64 @test12(i32 %A, i32 %B) {407; CHECK-LABEL: @test12(408; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i64409; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], 31410; CHECK-NEXT:    [[E:%.*]] = zext nneg i32 [[TMP1]] to i64411; CHECK-NEXT:    [[F:%.*]] = lshr i64 [[C]], [[E]]412; CHECK-NEXT:    ret i64 [[F]]413;414  %C = zext i32 %A to i128415  %D = zext i32 %B to i128416  %E = and i128 %D, 31417  %F = lshr i128 %C, %E418  %G = trunc i128 %F to i64419  ret i64 %G420}421 422define <2 x i64> @test12_vec(<2 x i32> %A, <2 x i32> %B) {423; CHECK-LABEL: @test12_vec(424; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>425; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], splat (i32 31)426; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>427; CHECK-NEXT:    [[F:%.*]] = lshr <2 x i64> [[C]], [[E]]428; CHECK-NEXT:    ret <2 x i64> [[F]]429;430  %C = zext <2 x i32> %A to <2 x i128>431  %D = zext <2 x i32> %B to <2 x i128>432  %E = and <2 x i128> %D, <i128 31, i128 31>433  %F = lshr <2 x i128> %C, %E434  %G = trunc <2 x i128> %F to <2 x i64>435  ret <2 x i64> %G436}437 438define <2 x i64> @test12_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {439; CHECK-LABEL: @test12_vec_nonuniform(440; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>441; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>442; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>443; CHECK-NEXT:    [[F:%.*]] = lshr <2 x i64> [[C]], [[E]]444; CHECK-NEXT:    ret <2 x i64> [[F]]445;446  %C = zext <2 x i32> %A to <2 x i128>447  %D = zext <2 x i32> %B to <2 x i128>448  %E = and <2 x i128> %D, <i128 31, i128 15>449  %F = lshr <2 x i128> %C, %E450  %G = trunc <2 x i128> %F to <2 x i64>451  ret <2 x i64> %G452}453 454define <2 x i64> @test12_vec_poison(<2 x i32> %A, <2 x i32> %B) {455; CHECK-LABEL: @test12_vec_poison(456; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>457; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 poison>458; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>459; CHECK-NEXT:    [[G:%.*]] = lshr <2 x i64> [[C]], [[E]]460; CHECK-NEXT:    ret <2 x i64> [[G]]461;462  %C = zext <2 x i32> %A to <2 x i128>463  %D = zext <2 x i32> %B to <2 x i128>464  %E = and <2 x i128> %D, <i128 31, i128 poison>465  %F = lshr <2 x i128> %C, %E466  %G = trunc <2 x i128> %F to <2 x i64>467  ret <2 x i64> %G468}469 470define i64 @test13(i32 %A, i32 %B) {471; CHECK-LABEL: @test13(472; CHECK-NEXT:    [[C:%.*]] = sext i32 [[A:%.*]] to i64473; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], 31474; CHECK-NEXT:    [[E:%.*]] = zext nneg i32 [[TMP1]] to i64475; CHECK-NEXT:    [[F:%.*]] = ashr i64 [[C]], [[E]]476; CHECK-NEXT:    ret i64 [[F]]477;478  %C = sext i32 %A to i128479  %D = zext i32 %B to i128480  %E = and i128 %D, 31481  %F = ashr i128 %C, %E482  %G = trunc i128 %F to i64483  ret i64 %G484}485 486define <2 x i64> @test13_vec(<2 x i32> %A, <2 x i32> %B) {487; CHECK-LABEL: @test13_vec(488; CHECK-NEXT:    [[C:%.*]] = sext <2 x i32> [[A:%.*]] to <2 x i64>489; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], splat (i32 31)490; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>491; CHECK-NEXT:    [[F:%.*]] = ashr <2 x i64> [[C]], [[E]]492; CHECK-NEXT:    ret <2 x i64> [[F]]493;494  %C = sext <2 x i32> %A to <2 x i128>495  %D = zext <2 x i32> %B to <2 x i128>496  %E = and <2 x i128> %D, <i128 31, i128 31>497  %F = ashr <2 x i128> %C, %E498  %G = trunc <2 x i128> %F to <2 x i64>499  ret <2 x i64> %G500}501 502define <2 x i64> @test13_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {503; CHECK-LABEL: @test13_vec_nonuniform(504; CHECK-NEXT:    [[C:%.*]] = sext <2 x i32> [[A:%.*]] to <2 x i64>505; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>506; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>507; CHECK-NEXT:    [[F:%.*]] = ashr <2 x i64> [[C]], [[E]]508; CHECK-NEXT:    ret <2 x i64> [[F]]509;510  %C = sext <2 x i32> %A to <2 x i128>511  %D = zext <2 x i32> %B to <2 x i128>512  %E = and <2 x i128> %D, <i128 31, i128 15>513  %F = ashr <2 x i128> %C, %E514  %G = trunc <2 x i128> %F to <2 x i64>515  ret <2 x i64> %G516}517 518define <2 x i64> @test13_vec_poison(<2 x i32> %A, <2 x i32> %B) {519; CHECK-LABEL: @test13_vec_poison(520; CHECK-NEXT:    [[C:%.*]] = sext <2 x i32> [[A:%.*]] to <2 x i64>521; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 poison>522; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>523; CHECK-NEXT:    [[G:%.*]] = ashr <2 x i64> [[C]], [[E]]524; CHECK-NEXT:    ret <2 x i64> [[G]]525;526  %C = sext <2 x i32> %A to <2 x i128>527  %D = zext <2 x i32> %B to <2 x i128>528  %E = and <2 x i128> %D, <i128 31, i128 poison>529  %F = ashr <2 x i128> %C, %E530  %G = trunc <2 x i128> %F to <2 x i64>531  ret <2 x i64> %G532}533 534; PR25543535; https://llvm.org/bugs/show_bug.cgi?id=25543536; This is an extractelement.537 538define i32 @trunc_bitcast1(<4 x i32> %v) {539; CHECK-LABEL: @trunc_bitcast1(540; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x i32> [[V:%.*]], i64 1541; CHECK-NEXT:    ret i32 [[EXT]]542;543  %bc = bitcast <4 x i32> %v to i128544  %shr = lshr i128 %bc, 32545  %ext = trunc i128 %shr to i32546  ret i32 %ext547}548 549; A bitcast may still be required.550 551define i32 @trunc_bitcast2(<2 x i64> %v) {552; CHECK-LABEL: @trunc_bitcast2(553; CHECK-NEXT:    [[BC1:%.*]] = bitcast <2 x i64> [[V:%.*]] to <4 x i32>554; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x i32> [[BC1]], i64 2555; CHECK-NEXT:    ret i32 [[EXT]]556;557  %bc = bitcast <2 x i64> %v to i128558  %shr = lshr i128 %bc, 64559  %ext = trunc i128 %shr to i32560  ret i32 %ext561}562 563; The right shift is optional.564 565define i32 @trunc_bitcast3(<4 x i32> %v) {566; CHECK-LABEL: @trunc_bitcast3(567; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x i32> [[V:%.*]], i64 0568; CHECK-NEXT:    ret i32 [[EXT]]569;570  %bc = bitcast <4 x i32> %v to i128571  %ext = trunc i128 %bc to i32572  ret i32 %ext573}574 575define i32 @trunc_shl_31_i32_i64(i64 %val) {576; CHECK-LABEL: @trunc_shl_31_i32_i64(577; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32578; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31579; CHECK-NEXT:    ret i32 [[TRUNC]]580;581  %shl = shl i64 %val, 31582  %trunc = trunc i64 %shl to i32583  ret i32 %trunc584}585 586define i32 @trunc_shl_nsw_31_i32_i64(i64 %val) {587; CHECK-LABEL: @trunc_shl_nsw_31_i32_i64(588; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32589; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31590; CHECK-NEXT:    ret i32 [[TRUNC]]591;592  %shl = shl nsw i64 %val, 31593  %trunc = trunc i64 %shl to i32594  ret i32 %trunc595}596 597define i32 @trunc_shl_nuw_31_i32_i64(i64 %val) {598; CHECK-LABEL: @trunc_shl_nuw_31_i32_i64(599; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32600; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31601; CHECK-NEXT:    ret i32 [[TRUNC]]602;603  %shl = shl nuw i64 %val, 31604  %trunc = trunc i64 %shl to i32605  ret i32 %trunc606}607 608define i32 @trunc_shl_nsw_nuw_31_i32_i64(i64 %val) {609; CHECK-LABEL: @trunc_shl_nsw_nuw_31_i32_i64(610; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32611; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31612; CHECK-NEXT:    ret i32 [[TRUNC]]613;614  %shl = shl nsw nuw i64 %val, 31615  %trunc = trunc i64 %shl to i32616  ret i32 %trunc617}618 619define i16 @trunc_shl_15_i16_i64(i64 %val) {620; CHECK-LABEL: @trunc_shl_15_i16_i64(621; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i16622; CHECK-NEXT:    [[TRUNC:%.*]] = shl i16 [[VAL_TR]], 15623; CHECK-NEXT:    ret i16 [[TRUNC]]624;625  %shl = shl i64 %val, 15626  %trunc = trunc i64 %shl to i16627  ret i16 %trunc628}629 630define i16 @trunc_shl_15_i16_i32(i32 %val) {631; CHECK-LABEL: @trunc_shl_15_i16_i32(632; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i32 [[VAL:%.*]] to i16633; CHECK-NEXT:    [[TRUNC:%.*]] = shl i16 [[VAL_TR]], 15634; CHECK-NEXT:    ret i16 [[TRUNC]]635;636  %shl = shl i32 %val, 15637  %trunc = trunc i32 %shl to i16638  ret i16 %trunc639}640 641define i8 @trunc_shl_7_i8_i64(i64 %val) {642; CHECK-LABEL: @trunc_shl_7_i8_i64(643; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i8644; CHECK-NEXT:    [[TRUNC:%.*]] = shl i8 [[VAL_TR]], 7645; CHECK-NEXT:    ret i8 [[TRUNC]]646;647  %shl = shl i64 %val, 7648  %trunc = trunc i64 %shl to i8649  ret i8 %trunc650}651 652define i2 @trunc_shl_1_i2_i64(i64 %val) {653; CHECK-LABEL: @trunc_shl_1_i2_i64(654; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[VAL:%.*]], 1655; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[SHL]] to i2656; CHECK-NEXT:    ret i2 [[TRUNC]]657;658  %shl = shl i64 %val, 1659  %trunc = trunc i64 %shl to i2660  ret i2 %trunc661}662 663define i32 @trunc_shl_1_i32_i64(i64 %val) {664; CHECK-LABEL: @trunc_shl_1_i32_i64(665; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32666; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 1667; CHECK-NEXT:    ret i32 [[TRUNC]]668;669  %shl = shl i64 %val, 1670  %trunc = trunc i64 %shl to i32671  ret i32 %trunc672}673 674define i32 @trunc_shl_16_i32_i64(i64 %val) {675; CHECK-LABEL: @trunc_shl_16_i32_i64(676; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32677; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 16678; CHECK-NEXT:    ret i32 [[TRUNC]]679;680  %shl = shl i64 %val, 16681  %trunc = trunc i64 %shl to i32682  ret i32 %trunc683}684 685define i32 @trunc_shl_33_i32_i64(i64 %val) {686; CHECK-LABEL: @trunc_shl_33_i32_i64(687; CHECK-NEXT:    ret i32 0688;689  %shl = shl i64 %val, 33690  %trunc = trunc i64 %shl to i32691  ret i32 %trunc692}693 694define i32 @trunc_shl_32_i32_i64(i64 %val) {695; CHECK-LABEL: @trunc_shl_32_i32_i64(696; CHECK-NEXT:    ret i32 0697;698  %shl = shl i64 %val, 32699  %trunc = trunc i64 %shl to i32700  ret i32 %trunc701}702 703; Should be able to handle vectors704define <2 x i32> @trunc_shl_16_v2i32_v2i64(<2 x i64> %val) {705; CHECK-LABEL: @trunc_shl_16_v2i32_v2i64(706; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>707; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], splat (i32 16)708; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]709;710  %shl = shl <2 x i64> %val, <i64 16, i64 16>711  %trunc = trunc <2 x i64> %shl to <2 x i32>712  ret <2 x i32> %trunc713}714 715define <2 x i32> @trunc_shl_nosplat_v2i32_v2i64(<2 x i64> %val) {716; CHECK-LABEL: @trunc_shl_nosplat_v2i32_v2i64(717; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>718; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 15, i32 16>719; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]720;721  %shl = shl <2 x i64> %val, <i64 15, i64 16>722  %trunc = trunc <2 x i64> %shl to <2 x i32>723  ret <2 x i32> %trunc724}725 726define void @trunc_shl_31_i32_i64_multi_use(i64 %val, ptr addrspace(1) %ptr0, ptr addrspace(1) %ptr1) {727; CHECK-LABEL: @trunc_shl_31_i32_i64_multi_use(728; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[VAL:%.*]], 31729; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[SHL]] to i32730; CHECK-NEXT:    store volatile i32 [[TRUNC]], ptr addrspace(1) [[PTR0:%.*]], align 4731; CHECK-NEXT:    store volatile i64 [[SHL]], ptr addrspace(1) [[PTR1:%.*]], align 8732; CHECK-NEXT:    ret void733;734  %shl = shl i64 %val, 31735  %trunc = trunc i64 %shl to i32736  store volatile i32 %trunc, ptr addrspace(1) %ptr0737  store volatile i64 %shl, ptr addrspace(1) %ptr1738  ret void739}740 741define i32 @trunc_shl_lshr_infloop(i64 %arg) {742; CHECK-LABEL: @trunc_shl_lshr_infloop(743; CHECK-NEXT:    [[ARG_TR:%.*]] = trunc i64 [[ARG:%.*]] to i32744; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[ARG_TR]], 1745; CHECK-NEXT:    [[C:%.*]] = and i32 [[TMP1]], -4746; CHECK-NEXT:    ret i32 [[C]]747;748  %A = lshr i64 %arg, 1749  %B = shl i64 %A, 2750  %C = trunc i64 %B to i32751  ret i32 %C752}753 754define <2 x i32> @trunc_shl_v2i32_v2i64_uniform(<2 x i64> %val) {755; CHECK-LABEL: @trunc_shl_v2i32_v2i64_uniform(756; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>757; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], splat (i32 31)758; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]759;760  %shl = shl <2 x i64> %val, <i64 31, i64 31>761  %trunc = trunc <2 x i64> %shl to <2 x i32>762  ret <2 x i32> %trunc763}764 765define <2 x i32> @trunc_shl_v2i32_v2i64_poison(<2 x i64> %val) {766; CHECK-LABEL: @trunc_shl_v2i32_v2i64_poison(767; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>768; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 31, i32 poison>769; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]770;771  %shl = shl <2 x i64> %val, <i64 31, i64 poison>772  %trunc = trunc <2 x i64> %shl to <2 x i32>773  ret <2 x i32> %trunc774}775 776define <2 x i32> @trunc_shl_v2i32_v2i64_nonuniform(<2 x i64> %val) {777; CHECK-LABEL: @trunc_shl_v2i32_v2i64_nonuniform(778; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>779; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 31, i32 12>780; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]781;782  %shl = shl <2 x i64> %val, <i64 31, i64 12>783  %trunc = trunc <2 x i64> %shl to <2 x i32>784  ret <2 x i32> %trunc785}786 787define <2 x i32> @trunc_shl_v2i32_v2i64_outofrange(<2 x i64> %val) {788; CHECK-LABEL: @trunc_shl_v2i32_v2i64_outofrange(789; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i64> [[VAL:%.*]], <i64 31, i64 33>790; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i64> [[SHL]] to <2 x i32>791; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]792;793  %shl = shl <2 x i64> %val, <i64 31, i64 33>794  %trunc = trunc <2 x i64> %shl to <2 x i32>795  ret <2 x i32> %trunc796}797 798define i32 @trunc_shl_ashr_infloop(i64 %arg) {799; CHECK-LABEL: @trunc_shl_ashr_infloop(800; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[ARG:%.*]], 1801; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32802; CHECK-NEXT:    [[C:%.*]] = and i32 [[TMP2]], -4803; CHECK-NEXT:    ret i32 [[C]]804;805  %A = ashr i64 %arg, 3806  %B = shl i64 %A, 2807  %C = trunc i64 %B to i32808  ret i32 %C809}810 811define i32 @trunc_shl_shl_infloop(i64 %arg) {812; CHECK-LABEL: @trunc_shl_shl_infloop(813; CHECK-NEXT:    [[ARG_TR:%.*]] = trunc i64 [[ARG:%.*]] to i32814; CHECK-NEXT:    [[C:%.*]] = shl i32 [[ARG_TR]], 3815; CHECK-NEXT:    ret i32 [[C]]816;817  %A = shl i64 %arg, 1818  %B = shl i64 %A, 2819  %C = trunc i64 %B to i32820  ret i32 %C821}822 823define i32 @trunc_shl_lshr_var(i64 %arg, i64 %val) {824; CHECK-LABEL: @trunc_shl_lshr_var(825; CHECK-NEXT:    [[A:%.*]] = lshr i64 [[ARG:%.*]], [[VAL:%.*]]826; CHECK-NEXT:    [[A_TR:%.*]] = trunc i64 [[A]] to i32827; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A_TR]], 2828; CHECK-NEXT:    ret i32 [[C]]829;830  %A = lshr i64 %arg, %val831  %B = shl i64 %A, 2832  %C = trunc i64 %B to i32833  ret i32 %C834}835 836define i32 @trunc_shl_ashr_var(i64 %arg, i64 %val) {837; CHECK-LABEL: @trunc_shl_ashr_var(838; CHECK-NEXT:    [[A:%.*]] = ashr i64 [[ARG:%.*]], [[VAL:%.*]]839; CHECK-NEXT:    [[A_TR:%.*]] = trunc i64 [[A]] to i32840; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A_TR]], 2841; CHECK-NEXT:    ret i32 [[C]]842;843  %A = ashr i64 %arg, %val844  %B = shl i64 %A, 2845  %C = trunc i64 %B to i32846  ret i32 %C847}848 849define i32 @trunc_shl_shl_var(i64 %arg, i64 %val) {850; CHECK-LABEL: @trunc_shl_shl_var(851; CHECK-NEXT:    [[A:%.*]] = shl i64 [[ARG:%.*]], [[VAL:%.*]]852; CHECK-NEXT:    [[A_TR:%.*]] = trunc i64 [[A]] to i32853; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A_TR]], 2854; CHECK-NEXT:    ret i32 [[C]]855;856  %A = shl i64 %arg, %val857  %B = shl i64 %A, 2858  %C = trunc i64 %B to i32859  ret i32 %C860}861 862define <8 x i16> @trunc_shl_v8i15_v8i32_15(<8 x i32> %a) {863; CHECK-LABEL: @trunc_shl_v8i15_v8i32_15(864; CHECK-NEXT:    [[A_TR:%.*]] = trunc <8 x i32> [[A:%.*]] to <8 x i16>865; CHECK-NEXT:    [[CONV:%.*]] = shl <8 x i16> [[A_TR]], splat (i16 15)866; CHECK-NEXT:    ret <8 x i16> [[CONV]]867;868  %shl = shl <8 x i32> %a, <i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15>869  %conv = trunc <8 x i32> %shl to <8 x i16>870  ret <8 x i16> %conv871}872 873define <8 x i16> @trunc_shl_v8i16_v8i32_16(<8 x i32> %a) {874; CHECK-LABEL: @trunc_shl_v8i16_v8i32_16(875; CHECK-NEXT:    ret <8 x i16> zeroinitializer876;877  %shl = shl <8 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>878  %conv = trunc <8 x i32> %shl to <8 x i16>879  ret <8 x i16> %conv880}881 882define <8 x i16> @trunc_shl_v8i16_v8i32_17(<8 x i32> %a) {883; CHECK-LABEL: @trunc_shl_v8i16_v8i32_17(884; CHECK-NEXT:    ret <8 x i16> zeroinitializer885;886  %shl = shl <8 x i32> %a, <i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17>887  %conv = trunc <8 x i32> %shl to <8 x i16>888  ret <8 x i16> %conv889}890 891define <8 x i16> @trunc_shl_v8i16_v8i32_4(<8 x i32> %a) {892; CHECK-LABEL: @trunc_shl_v8i16_v8i32_4(893; CHECK-NEXT:    [[A_TR:%.*]] = trunc <8 x i32> [[A:%.*]] to <8 x i16>894; CHECK-NEXT:    [[CONV:%.*]] = shl <8 x i16> [[A_TR]], splat (i16 4)895; CHECK-NEXT:    ret <8 x i16> [[CONV]]896;897  %shl = shl <8 x i32> %a, <i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4>898  %conv = trunc <8 x i32> %shl to <8 x i16>899  ret <8 x i16> %conv900}901 902; Although the mask is the same value, we don't create a shuffle for types that the backend may not be able to handle:903; trunc (shuffle X, C, Mask) --> shuffle (trunc X), C', Mask904 905define <4 x i8> @wide_shuf(<4 x i32> %x) {906; CHECK-LABEL: @wide_shuf(907; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> <i32 poison, i32 3634, i32 90, i32 poison>, <4 x i32> <i32 1, i32 5, i32 6, i32 2>908; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <4 x i32> [[SHUF]] to <4 x i8>909; CHECK-NEXT:    ret <4 x i8> [[TRUNC]]910;911  %shuf = shufflevector <4 x i32> %x, <4 x i32> <i32 35, i32 3634, i32 90, i32 -1>, <4 x i32> <i32 1, i32 5, i32 6, i32 2>912  %trunc = trunc <4 x i32> %shuf to <4 x i8>913  ret <4 x i8> %trunc914}915 916; trunc (shuffle X, poison, SplatMask) --> shuffle (trunc X), poison, SplatMask917 918define <4 x i8> @wide_splat1(<4 x i32> %x) {919; CHECK-LABEL: @wide_splat1(920; CHECK-NEXT:    [[TMP1:%.*]] = trunc <4 x i32> [[X:%.*]] to <4 x i8>921; CHECK-NEXT:    [[TRUNC:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>922; CHECK-NEXT:    ret <4 x i8> [[TRUNC]]923;924  %shuf = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>925  %trunc = trunc <4 x i32> %shuf to <4 x i8>926  ret <4 x i8> %trunc927}928 929; Test weird types.930; trunc (shuffle X, poison, SplatMask) --> shuffle (trunc X), poison, SplatMask931 932define <3 x i31> @wide_splat2(<3 x i33> %x) {933; CHECK-LABEL: @wide_splat2(934; CHECK-NEXT:    [[TMP1:%.*]] = trunc <3 x i33> [[X:%.*]] to <3 x i31>935; CHECK-NEXT:    [[TRUNC:%.*]] = shufflevector <3 x i31> [[TMP1]], <3 x i31> poison, <3 x i32> <i32 1, i32 1, i32 1>936; CHECK-NEXT:    ret <3 x i31> [[TRUNC]]937;938  %shuf = shufflevector <3 x i33> %x, <3 x i33> poison, <3 x i32> <i32 1, i32 1, i32 1>939  %trunc = trunc <3 x i33> %shuf to <3 x i31>940  ret <3 x i31> %trunc941}942 943; FIXME:944; trunc (shuffle X, poison, SplatMask) --> shuffle (trunc X), poison, SplatMask945; A mask with poison elements should still be considered a splat mask.946 947define <3 x i31> @wide_splat3(<3 x i33> %x) {948; CHECK-LABEL: @wide_splat3(949; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <3 x i33> [[X:%.*]], <3 x i33> poison, <3 x i32> <i32 poison, i32 1, i32 1>950; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <3 x i33> [[SHUF]] to <3 x i31>951; CHECK-NEXT:    ret <3 x i31> [[TRUNC]]952;953  %shuf = shufflevector <3 x i33> %x, <3 x i33> poison, <3 x i32> <i32 poison, i32 1, i32 1>954  %trunc = trunc <3 x i33> %shuf to <3 x i31>955  ret <3 x i31> %trunc956}957 958; TODO: The shuffle extends the length of the input vector. Should we shrink this?959 960define <8 x i8> @wide_lengthening_splat(<4 x i16> %v) {961; CHECK-LABEL: @wide_lengthening_splat(962; CHECK-NEXT:    [[TMP1:%.*]] = trunc <4 x i16> [[V:%.*]] to <4 x i8>963; CHECK-NEXT:    [[TR:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <8 x i32> zeroinitializer964; CHECK-NEXT:    ret <8 x i8> [[TR]]965;966  %shuf = shufflevector <4 x i16> %v, <4 x i16> %v, <8 x i32> zeroinitializer967  %tr = trunc <8 x i16> %shuf to <8 x i8>968  ret <8 x i8> %tr969}970 971define <2 x i8> @narrow_add_vec_constant(<2 x i32> %x) {972; CHECK-LABEL: @narrow_add_vec_constant(973; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>974; CHECK-NEXT:    [[TR:%.*]] = add <2 x i8> [[TMP1]], <i8 0, i8 127>975; CHECK-NEXT:    ret <2 x i8> [[TR]]976;977  %add = add <2 x i32> %x, <i32 256, i32 -129>978  %tr = trunc <2 x i32> %add to <2 x i8>979  ret <2 x i8> %tr980}981 982define <2 x i8> @narrow_mul_vec_constant(<2 x i32> %x) {983; CHECK-LABEL: @narrow_mul_vec_constant(984; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>985; CHECK-NEXT:    [[TR:%.*]] = mul <2 x i8> [[TMP1]], <i8 0, i8 127>986; CHECK-NEXT:    ret <2 x i8> [[TR]]987;988  %add = mul <2 x i32> %x, <i32 256, i32 -129>989  %tr = trunc <2 x i32> %add to <2 x i8>990  ret <2 x i8> %tr991}992 993define <2 x i8> @narrow_sub_vec_constant(<2 x i32> %x) {994; CHECK-LABEL: @narrow_sub_vec_constant(995; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>996; CHECK-NEXT:    [[TR:%.*]] = sub <2 x i8> <i8 0, i8 127>, [[TMP1]]997; CHECK-NEXT:    ret <2 x i8> [[TR]]998;999  %sub = sub <2 x i32> <i32 256, i32 -129>, %x1000  %tr = trunc <2 x i32> %sub to <2 x i8>1001  ret <2 x i8> %tr1002}1003 1004; If the select is narrowed based on the target's datalayout, we allow more optimizations.1005 1006define i16 @PR44545(i32 %t0, i32 %data) {1007; CHECK-LABEL: @PR44545(1008; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[DATA:%.*]], 01009; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[T0:%.*]] to i161010; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[ISZERO]], i16 -1, i16 [[TMP1]]1011; CHECK-NEXT:    ret i16 [[SUB]]1012;1013  %t1 = add nuw nsw i32 %t0, 11014  %iszero = icmp eq i32 %data, 01015  %ffs = select i1 %iszero, i32 0, i32 %t11016  %cast = trunc i32 %ffs to i161017  %sub = add nsw i16 %cast, -11018  ret i16 %sub1019}1020