brintos

brintos / llvm-project-archived public Read only

0
0
Text · 39.0 KiB · dfe9d94 Raw
1221 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.i8(i8)9declare void @use_vec(<2 x i32>)10 11define i64 @test1(i64 %a) {12; CHECK-LABEL: @test1(13; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i3214; CHECK-NEXT:    [[C:%.*]] = and i64 [[A]], 1515; CHECK-NEXT:    call void @use(i32 [[B]])16; CHECK-NEXT:    ret i64 [[C]]17;18  %b = trunc i64 %a to i3219  %c = and i32 %b, 1520  %d = zext i32 %c to i6421  call void @use(i32 %b)22  ret i64 %d23}24 25define <2 x i64> @test1_vec(<2 x i64> %a) {26; CHECK-LABEL: @test1_vec(27; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>28; CHECK-NEXT:    [[D:%.*]] = and <2 x i64> [[A]], splat (i64 15)29; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])30; CHECK-NEXT:    ret <2 x i64> [[D]]31;32  %b = trunc <2 x i64> %a to <2 x i32>33  %c = and <2 x i32> %b, <i32 15, i32 15>34  %d = zext <2 x i32> %c to <2 x i64>35  call void @use_vec(<2 x i32> %b)36  ret <2 x i64> %d37}38 39define <2 x i64> @test1_vec_nonuniform(<2 x i64> %a) {40; CHECK-LABEL: @test1_vec_nonuniform(41; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>42; CHECK-NEXT:    [[D:%.*]] = and <2 x i64> [[A]], <i64 15, i64 7>43; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])44; CHECK-NEXT:    ret <2 x i64> [[D]]45;46  %b = trunc <2 x i64> %a to <2 x i32>47  %c = and <2 x i32> %b, <i32 15, i32 7>48  %d = zext <2 x i32> %c to <2 x i64>49  call void @use_vec(<2 x i32> %b)50  ret <2 x i64> %d51}52 53define <2 x i64> @test1_vec_poison(<2 x i64> %a) {54; CHECK-LABEL: @test1_vec_poison(55; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>56; CHECK-NEXT:    [[D:%.*]] = and <2 x i64> [[A]], <i64 15, i64 poison>57; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])58; CHECK-NEXT:    ret <2 x i64> [[D]]59;60  %b = trunc <2 x i64> %a to <2 x i32>61  %c = and <2 x i32> %b, <i32 15, i32 poison>62  %d = zext <2 x i32> %c to <2 x i64>63  call void @use_vec(<2 x i32> %b)64  ret <2 x i64> %d65}66 67define i64 @test2(i64 %a) {68; CHECK-LABEL: @test2(69; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i3270; CHECK-NEXT:    [[D1:%.*]] = shl i64 [[A]], 3671; CHECK-NEXT:    [[D:%.*]] = ashr exact i64 [[D1]], 3672; CHECK-NEXT:    call void @use(i32 [[B]])73; CHECK-NEXT:    ret i64 [[D]]74;75  %b = trunc i64 %a to i3276  %c = shl i32 %b, 477  %q = ashr i32 %c, 478  %d = sext i32 %q to i6479  call void @use(i32 %b)80  ret i64 %d81}82 83define <2 x i64> @test2_vec(<2 x i64> %a) {84; CHECK-LABEL: @test2_vec(85; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>86; CHECK-NEXT:    [[D1:%.*]] = shl <2 x i64> [[A]], splat (i64 36)87; CHECK-NEXT:    [[D:%.*]] = ashr exact <2 x i64> [[D1]], splat (i64 36)88; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])89; CHECK-NEXT:    ret <2 x i64> [[D]]90;91  %b = trunc <2 x i64> %a to <2 x i32>92  %c = shl <2 x i32> %b, <i32 4, i32 4>93  %q = ashr <2 x i32> %c, <i32 4, i32 4>94  %d = sext <2 x i32> %q to <2 x i64>95  call void @use_vec(<2 x i32> %b)96  ret <2 x i64> %d97}98 99define <2 x i64> @test2_vec_nonuniform(<2 x i64> %a) {100; CHECK-LABEL: @test2_vec_nonuniform(101; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>102; CHECK-NEXT:    [[D1:%.*]] = shl <2 x i64> [[A]], <i64 36, i64 37>103; CHECK-NEXT:    [[D:%.*]] = ashr exact <2 x i64> [[D1]], <i64 36, i64 37>104; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])105; CHECK-NEXT:    ret <2 x i64> [[D]]106;107  %b = trunc <2 x i64> %a to <2 x i32>108  %c = shl <2 x i32> %b, <i32 4, i32 5>109  %q = ashr <2 x i32> %c, <i32 4, i32 5>110  %d = sext <2 x i32> %q to <2 x i64>111  call void @use_vec(<2 x i32> %b)112  ret <2 x i64> %d113}114 115define <2 x i64> @test2_vec_poison(<2 x i64> %a) {116; CHECK-LABEL: @test2_vec_poison(117; CHECK-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>118; CHECK-NEXT:    [[D1:%.*]] = shl <2 x i64> [[A]], <i64 36, i64 poison>119; CHECK-NEXT:    [[D:%.*]] = ashr exact <2 x i64> [[D1]], <i64 36, i64 poison>120; CHECK-NEXT:    call void @use_vec(<2 x i32> [[B]])121; CHECK-NEXT:    ret <2 x i64> [[D]]122;123  %b = trunc <2 x i64> %a to <2 x i32>124  %c = shl <2 x i32> %b, <i32 4, i32 poison>125  %q = ashr <2 x i32> %c, <i32 4, i32 poison>126  %d = sext <2 x i32> %q to <2 x i64>127  call void @use_vec(<2 x i32> %b)128  ret <2 x i64> %d129}130 131define i64 @test3(i64 %a) {132; CHECK-LABEL: @test3(133; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i32134; CHECK-NEXT:    [[C:%.*]] = and i64 [[A]], 8135; CHECK-NEXT:    call void @use(i32 [[B]])136; CHECK-NEXT:    ret i64 [[C]]137;138  %b = trunc i64 %a to i32139  %c = and i32 %b, 8140  %d = zext i32 %c to i64141  call void @use(i32 %b)142  ret i64 %d143}144 145define i64 @test4(i64 %a) {146; CHECK-LABEL: @test4(147; CHECK-NEXT:    [[B:%.*]] = trunc i64 [[A:%.*]] to i32148; CHECK-NEXT:    [[C:%.*]] = and i64 [[A]], 8149; CHECK-NEXT:    [[X:%.*]] = xor i64 [[C]], 8150; CHECK-NEXT:    call void @use(i32 [[B]])151; CHECK-NEXT:    ret i64 [[X]]152;153  %b = trunc i64 %a to i32154  %c = and i32 %b, 8155  %x = xor i32 %c, 8156  %d = zext i32 %x to i64157  call void @use(i32 %b)158  ret i64 %d159}160 161define i32 @test5(i32 %A) {162; CHECK-LABEL: @test5(163; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[A:%.*]], 16164; CHECK-NEXT:    ret i32 [[TMP1]]165;166  %B = zext i32 %A to i128167  %C = lshr i128 %B, 16168  %D = trunc i128 %C to i32169  ret i32 %D170}171 172define i32 @test6(i64 %A) {173; CHECK-LABEL: @test6(174; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[A:%.*]], 32175; CHECK-NEXT:    [[D:%.*]] = trunc nuw i64 [[TMP1]] to i32176; CHECK-NEXT:    ret i32 [[D]]177;178  %B = zext i64 %A to i128179  %C = lshr i128 %B, 32180  %D = trunc i128 %C to i32181  ret i32 %D182}183 184; Test case where 'ashr' demanded bits does not contain any of the high bits,185; but does contain sign bits, where the sign bit is not known to be zero.186define i16 @ashr_mul_sign_bits(i8 %X, i8 %Y) {187; CHECK-LABEL: @ashr_mul_sign_bits(188; CHECK-NEXT:    [[A:%.*]] = sext i8 [[X:%.*]] to i16189; CHECK-NEXT:    [[B:%.*]] = sext i8 [[Y:%.*]] to i16190; CHECK-NEXT:    [[C:%.*]] = mul nsw i16 [[A]], [[B]]191; CHECK-NEXT:    [[D:%.*]] = ashr i16 [[C]], 3192; CHECK-NEXT:    ret i16 [[D]]193;194  %A = sext i8 %X to i32195  %B = sext i8 %Y to i32196  %C = mul i32 %A, %B197  %D = ashr i32 %C, 3198  %E = trunc i32 %D to i16199  ret i16 %E200}201 202define i16 @ashr_mul(i8 %X, i8 %Y) {203; CHECK-LABEL: @ashr_mul(204; CHECK-NEXT:    [[A:%.*]] = sext i8 [[X:%.*]] to i16205; CHECK-NEXT:    [[B:%.*]] = sext i8 [[Y:%.*]] to i16206; CHECK-NEXT:    [[C:%.*]] = mul nsw i16 [[A]], [[B]]207; CHECK-NEXT:    [[D:%.*]] = ashr i16 [[C]], 8208; CHECK-NEXT:    ret i16 [[D]]209;210  %A = sext i8 %X to i20211  %B = sext i8 %Y to i20212  %C = mul i20 %A, %B213  %D = ashr i20 %C, 8214  %E = trunc i20 %D to i16215  ret i16 %E216}217 218define i32 @trunc_ashr(i32 %X) {219; CHECK-LABEL: @trunc_ashr(220; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8221; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], -8388608222; CHECK-NEXT:    ret i32 [[TMP2]]223;224  %A = zext i32 %X to i36225  %B = or i36 %A, -2147483648 ; 0xF80000000226  %C = ashr i36 %B, 8227  %T = trunc i36 %C to i32228  ret i32  %T229}230 231define <2 x i32> @trunc_ashr_vec(<2 x i32> %X) {232; CHECK-LABEL: @trunc_ashr_vec(233; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 8)234; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i32> [[TMP1]], splat (i32 -8388608)235; CHECK-NEXT:    ret <2 x i32> [[TMP2]]236;237  %A = zext <2 x i32> %X to <2 x i36>238  %B = or <2 x i36> %A, <i36 -2147483648, i36 -2147483648> ; 0xF80000000239  %C = ashr <2 x i36> %B, <i36 8, i36 8>240  %T = trunc <2 x i36> %C to <2 x i32>241  ret <2 x i32>  %T242}243 244define i92 @test7(i64 %A) {245; CHECK-LABEL: @test7(246; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[A:%.*]], 32247; CHECK-NEXT:    [[D:%.*]] = zext nneg i64 [[TMP1]] to i92248; CHECK-NEXT:    ret i92 [[D]]249;250  %B = zext i64 %A to i128251  %C = lshr i128 %B, 32252  %D = trunc i128 %C to i92253  ret i92 %D254}255 256define i64 @test8(i32 %A, i32 %B) {257; CHECK-LABEL: @test8(258; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i64259; CHECK-NEXT:    [[D:%.*]] = zext i32 [[B:%.*]] to i64260; CHECK-NEXT:    [[E:%.*]] = shl nuw i64 [[D]], 32261; CHECK-NEXT:    [[F:%.*]] = or disjoint i64 [[E]], [[C]]262; CHECK-NEXT:    ret i64 [[F]]263;264  %C = zext i32 %A to i128265  %D = zext i32 %B to i128266  %E = shl i128 %D, 32267  %F = or i128 %E, %C268  %G = trunc i128 %F to i64269  ret i64 %G270}271 272define <2 x i64> @test8_vec(<2 x i32> %A, <2 x i32> %B) {273; CHECK-LABEL: @test8_vec(274; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>275; CHECK-NEXT:    [[D:%.*]] = zext <2 x i32> [[B:%.*]] to <2 x i64>276; CHECK-NEXT:    [[E:%.*]] = shl nuw <2 x i64> [[D]], splat (i64 32)277; CHECK-NEXT:    [[F:%.*]] = or disjoint <2 x i64> [[E]], [[C]]278; CHECK-NEXT:    ret <2 x i64> [[F]]279;280  %C = zext <2 x i32> %A to <2 x i128>281  %D = zext <2 x i32> %B to <2 x i128>282  %E = shl <2 x i128> %D, <i128 32, i128 32>283  %F = or <2 x i128> %E, %C284  %G = trunc <2 x i128> %F to <2 x i64>285  ret <2 x i64> %G286}287 288define <2 x i64> @test8_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {289; CHECK-LABEL: @test8_vec_nonuniform(290; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>291; CHECK-NEXT:    [[D:%.*]] = zext <2 x i32> [[B:%.*]] to <2 x i64>292; CHECK-NEXT:    [[E:%.*]] = shl <2 x i64> [[D]], <i64 32, i64 48>293; CHECK-NEXT:    [[F:%.*]] = or disjoint <2 x i64> [[E]], [[C]]294; CHECK-NEXT:    ret <2 x i64> [[F]]295;296  %C = zext <2 x i32> %A to <2 x i128>297  %D = zext <2 x i32> %B to <2 x i128>298  %E = shl <2 x i128> %D, <i128 32, i128 48>299  %F = or <2 x i128> %E, %C300  %G = trunc <2 x i128> %F to <2 x i64>301  ret <2 x i64> %G302}303 304define <2 x i64> @test8_vec_poison(<2 x i32> %A, <2 x i32> %B) {305; CHECK-LABEL: @test8_vec_poison(306; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>307; CHECK-NEXT:    [[D:%.*]] = zext <2 x i32> [[B:%.*]] to <2 x i64>308; CHECK-NEXT:    [[E:%.*]] = shl nuw <2 x i64> [[D]], <i64 32, i64 poison>309; CHECK-NEXT:    [[F:%.*]] = or disjoint <2 x i64> [[E]], [[C]]310; CHECK-NEXT:    ret <2 x i64> [[F]]311;312  %C = zext <2 x i32> %A to <2 x i128>313  %D = zext <2 x i32> %B to <2 x i128>314  %E = shl <2 x i128> %D, <i128 32, i128 poison>315  %F = or <2 x i128> %E, %C316  %G = trunc <2 x i128> %F to <2 x i64>317  ret <2 x i64> %G318}319 320define i8 @test9(i32 %X) {321; CHECK-LABEL: @test9(322; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8323; CHECK-NEXT:    [[Z:%.*]] = and i8 [[TMP1]], 42324; CHECK-NEXT:    ret i8 [[Z]]325;326  %Y = and i32 %X, 42327  %Z = trunc i32 %Y to i8328  ret i8 %Z329}330 331; rdar://8808586332define i8 @test10(i32 %X) {333; CHECK-LABEL: @test10(334; CHECK-NEXT:    [[Y:%.*]] = trunc i32 [[X:%.*]] to i8335; CHECK-NEXT:    [[Z:%.*]] = and i8 [[Y]], 42336; CHECK-NEXT:    ret i8 [[Z]]337;338  %Y = trunc i32 %X to i8339  %Z = and i8 %Y, 42340  ret i8 %Z341}342 343define i64 @test11(i32 %A, i32 %B) {344; CHECK-LABEL: @test11(345; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i64346; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], 31347; CHECK-NEXT:    [[E:%.*]] = zext nneg i32 [[TMP1]] to i64348; CHECK-NEXT:    [[F:%.*]] = shl nuw nsw i64 [[C]], [[E]]349; CHECK-NEXT:    ret i64 [[F]]350;351  %C = zext i32 %A to i128352  %D = zext i32 %B to i128353  %E = and i128 %D, 31354  %F = shl i128 %C, %E355  %G = trunc i128 %F to i64356  ret i64 %G357}358 359define <2 x i64> @test11_vec(<2 x i32> %A, <2 x i32> %B) {360; CHECK-LABEL: @test11_vec(361; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>362; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], splat (i32 31)363; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>364; CHECK-NEXT:    [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]365; CHECK-NEXT:    ret <2 x i64> [[F]]366;367  %C = zext <2 x i32> %A to <2 x i128>368  %D = zext <2 x i32> %B to <2 x i128>369  %E = and <2 x i128> %D, <i128 31, i128 31>370  %F = shl <2 x i128> %C, %E371  %G = trunc <2 x i128> %F to <2 x i64>372  ret <2 x i64> %G373}374 375define <2 x i64> @test11_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {376; CHECK-LABEL: @test11_vec_nonuniform(377; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>378; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>379; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>380; CHECK-NEXT:    [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]381; CHECK-NEXT:    ret <2 x i64> [[F]]382;383  %C = zext <2 x i32> %A to <2 x i128>384  %D = zext <2 x i32> %B to <2 x i128>385  %E = and <2 x i128> %D, <i128 31, i128 15>386  %F = shl <2 x i128> %C, %E387  %G = trunc <2 x i128> %F to <2 x i64>388  ret <2 x i64> %G389}390 391define <2 x i64> @test11_vec_poison(<2 x i32> %A, <2 x i32> %B) {392; CHECK-LABEL: @test11_vec_poison(393; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>394; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 poison>395; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>396; CHECK-NEXT:    [[F:%.*]] = shl nuw nsw <2 x i64> [[C]], [[E]]397; CHECK-NEXT:    ret <2 x i64> [[F]]398;399  %C = zext <2 x i32> %A to <2 x i128>400  %D = zext <2 x i32> %B to <2 x i128>401  %E = and <2 x i128> %D, <i128 31, i128 poison>402  %F = shl <2 x i128> %C, %E403  %G = trunc <2 x i128> %F to <2 x i64>404  ret <2 x i64> %G405}406 407define i64 @test12(i32 %A, i32 %B) {408; CHECK-LABEL: @test12(409; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i64410; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], 31411; CHECK-NEXT:    [[E:%.*]] = zext nneg i32 [[TMP1]] to i64412; CHECK-NEXT:    [[F:%.*]] = lshr i64 [[C]], [[E]]413; CHECK-NEXT:    ret i64 [[F]]414;415  %C = zext i32 %A to i128416  %D = zext i32 %B to i128417  %E = and i128 %D, 31418  %F = lshr i128 %C, %E419  %G = trunc i128 %F to i64420  ret i64 %G421}422 423define <2 x i64> @test12_vec(<2 x i32> %A, <2 x i32> %B) {424; CHECK-LABEL: @test12_vec(425; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>426; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], splat (i32 31)427; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>428; CHECK-NEXT:    [[F:%.*]] = lshr <2 x i64> [[C]], [[E]]429; CHECK-NEXT:    ret <2 x i64> [[F]]430;431  %C = zext <2 x i32> %A to <2 x i128>432  %D = zext <2 x i32> %B to <2 x i128>433  %E = and <2 x i128> %D, <i128 31, i128 31>434  %F = lshr <2 x i128> %C, %E435  %G = trunc <2 x i128> %F to <2 x i64>436  ret <2 x i64> %G437}438 439define <2 x i64> @test12_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {440; CHECK-LABEL: @test12_vec_nonuniform(441; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>442; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>443; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>444; CHECK-NEXT:    [[F:%.*]] = lshr <2 x i64> [[C]], [[E]]445; CHECK-NEXT:    ret <2 x i64> [[F]]446;447  %C = zext <2 x i32> %A to <2 x i128>448  %D = zext <2 x i32> %B to <2 x i128>449  %E = and <2 x i128> %D, <i128 31, i128 15>450  %F = lshr <2 x i128> %C, %E451  %G = trunc <2 x i128> %F to <2 x i64>452  ret <2 x i64> %G453}454 455define <2 x i64> @test12_vec_poison(<2 x i32> %A, <2 x i32> %B) {456; CHECK-LABEL: @test12_vec_poison(457; CHECK-NEXT:    [[C:%.*]] = zext <2 x i32> [[A:%.*]] to <2 x i64>458; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 poison>459; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>460; CHECK-NEXT:    [[F:%.*]] = lshr <2 x i64> [[C]], [[E]]461; CHECK-NEXT:    ret <2 x i64> [[F]]462;463  %C = zext <2 x i32> %A to <2 x i128>464  %D = zext <2 x i32> %B to <2 x i128>465  %E = and <2 x i128> %D, <i128 31, i128 poison>466  %F = lshr <2 x i128> %C, %E467  %G = trunc <2 x i128> %F to <2 x i64>468  ret <2 x i64> %G469}470 471define i64 @test13(i32 %A, i32 %B) {472; CHECK-LABEL: @test13(473; CHECK-NEXT:    [[C:%.*]] = sext i32 [[A:%.*]] to i64474; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], 31475; CHECK-NEXT:    [[E:%.*]] = zext nneg i32 [[TMP1]] to i64476; CHECK-NEXT:    [[F:%.*]] = ashr i64 [[C]], [[E]]477; CHECK-NEXT:    ret i64 [[F]]478;479  %C = sext i32 %A to i128480  %D = zext i32 %B to i128481  %E = and i128 %D, 31482  %F = ashr i128 %C, %E483  %G = trunc i128 %F to i64484  ret i64 %G485}486 487define <2 x i64> @test13_vec(<2 x i32> %A, <2 x i32> %B) {488; CHECK-LABEL: @test13_vec(489; CHECK-NEXT:    [[C:%.*]] = sext <2 x i32> [[A:%.*]] to <2 x i64>490; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], splat (i32 31)491; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>492; CHECK-NEXT:    [[F:%.*]] = ashr <2 x i64> [[C]], [[E]]493; CHECK-NEXT:    ret <2 x i64> [[F]]494;495  %C = sext <2 x i32> %A to <2 x i128>496  %D = zext <2 x i32> %B to <2 x i128>497  %E = and <2 x i128> %D, <i128 31, i128 31>498  %F = ashr <2 x i128> %C, %E499  %G = trunc <2 x i128> %F to <2 x i64>500  ret <2 x i64> %G501}502 503define <2 x i64> @test13_vec_nonuniform(<2 x i32> %A, <2 x i32> %B) {504; CHECK-LABEL: @test13_vec_nonuniform(505; CHECK-NEXT:    [[C:%.*]] = sext <2 x i32> [[A:%.*]] to <2 x i64>506; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 15>507; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>508; CHECK-NEXT:    [[F:%.*]] = ashr <2 x i64> [[C]], [[E]]509; CHECK-NEXT:    ret <2 x i64> [[F]]510;511  %C = sext <2 x i32> %A to <2 x i128>512  %D = zext <2 x i32> %B to <2 x i128>513  %E = and <2 x i128> %D, <i128 31, i128 15>514  %F = ashr <2 x i128> %C, %E515  %G = trunc <2 x i128> %F to <2 x i64>516  ret <2 x i64> %G517}518 519define <2 x i64> @test13_vec_poison(<2 x i32> %A, <2 x i32> %B) {520; CHECK-LABEL: @test13_vec_poison(521; CHECK-NEXT:    [[C:%.*]] = sext <2 x i32> [[A:%.*]] to <2 x i64>522; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[B:%.*]], <i32 31, i32 poison>523; CHECK-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>524; CHECK-NEXT:    [[F:%.*]] = ashr <2 x i64> [[C]], [[E]]525; CHECK-NEXT:    ret <2 x i64> [[F]]526;527  %C = sext <2 x i32> %A to <2 x i128>528  %D = zext <2 x i32> %B to <2 x i128>529  %E = and <2 x i128> %D, <i128 31, i128 poison>530  %F = ashr <2 x i128> %C, %E531  %G = trunc <2 x i128> %F to <2 x i64>532  ret <2 x i64> %G533}534 535; PR25543536; https://llvm.org/bugs/show_bug.cgi?id=25543537; This is an extractelement.538 539define i32 @trunc_bitcast1(<4 x i32> %v) {540; CHECK-LABEL: @trunc_bitcast1(541; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x i32> [[V:%.*]], i64 1542; CHECK-NEXT:    ret i32 [[EXT]]543;544  %bc = bitcast <4 x i32> %v to i128545  %shr = lshr i128 %bc, 32546  %ext = trunc i128 %shr to i32547  ret i32 %ext548}549 550; A bitcast may still be required.551 552define i32 @trunc_bitcast2(<2 x i64> %v) {553; CHECK-LABEL: @trunc_bitcast2(554; CHECK-NEXT:    [[BC1:%.*]] = bitcast <2 x i64> [[V:%.*]] to <4 x i32>555; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x i32> [[BC1]], i64 2556; CHECK-NEXT:    ret i32 [[EXT]]557;558  %bc = bitcast <2 x i64> %v to i128559  %shr = lshr i128 %bc, 64560  %ext = trunc i128 %shr to i32561  ret i32 %ext562}563 564; The right shift is optional.565 566define i32 @trunc_bitcast3(<4 x i32> %v) {567; CHECK-LABEL: @trunc_bitcast3(568; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x i32> [[V:%.*]], i64 0569; CHECK-NEXT:    ret i32 [[EXT]]570;571  %bc = bitcast <4 x i32> %v to i128572  %ext = trunc i128 %bc to i32573  ret i32 %ext574}575 576define i32 @trunc_shl_31_i32_i64(i64 %val) {577; CHECK-LABEL: @trunc_shl_31_i32_i64(578; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32579; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31580; CHECK-NEXT:    ret i32 [[TRUNC]]581;582  %shl = shl i64 %val, 31583  %trunc = trunc i64 %shl to i32584  ret i32 %trunc585}586 587define i32 @trunc_shl_nsw_31_i32_i64(i64 %val) {588; CHECK-LABEL: @trunc_shl_nsw_31_i32_i64(589; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32590; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31591; CHECK-NEXT:    ret i32 [[TRUNC]]592;593  %shl = shl nsw i64 %val, 31594  %trunc = trunc i64 %shl to i32595  ret i32 %trunc596}597 598define i32 @trunc_shl_nuw_31_i32_i64(i64 %val) {599; CHECK-LABEL: @trunc_shl_nuw_31_i32_i64(600; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32601; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31602; CHECK-NEXT:    ret i32 [[TRUNC]]603;604  %shl = shl nuw i64 %val, 31605  %trunc = trunc i64 %shl to i32606  ret i32 %trunc607}608 609define i32 @trunc_shl_nsw_nuw_31_i32_i64(i64 %val) {610; CHECK-LABEL: @trunc_shl_nsw_nuw_31_i32_i64(611; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32612; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 31613; CHECK-NEXT:    ret i32 [[TRUNC]]614;615  %shl = shl nsw nuw i64 %val, 31616  %trunc = trunc i64 %shl to i32617  ret i32 %trunc618}619 620define i16 @trunc_shl_15_i16_i64(i64 %val) {621; CHECK-LABEL: @trunc_shl_15_i16_i64(622; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i16623; CHECK-NEXT:    [[TRUNC:%.*]] = shl i16 [[VAL_TR]], 15624; CHECK-NEXT:    ret i16 [[TRUNC]]625;626  %shl = shl i64 %val, 15627  %trunc = trunc i64 %shl to i16628  ret i16 %trunc629}630 631define i16 @trunc_shl_15_i16_i32(i32 %val) {632; CHECK-LABEL: @trunc_shl_15_i16_i32(633; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i32 [[VAL:%.*]] to i16634; CHECK-NEXT:    [[TRUNC:%.*]] = shl i16 [[VAL_TR]], 15635; CHECK-NEXT:    ret i16 [[TRUNC]]636;637  %shl = shl i32 %val, 15638  %trunc = trunc i32 %shl to i16639  ret i16 %trunc640}641 642define i8 @trunc_shl_7_i8_i64(i64 %val) {643; CHECK-LABEL: @trunc_shl_7_i8_i64(644; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i8645; CHECK-NEXT:    [[TRUNC:%.*]] = shl i8 [[VAL_TR]], 7646; CHECK-NEXT:    ret i8 [[TRUNC]]647;648  %shl = shl i64 %val, 7649  %trunc = trunc i64 %shl to i8650  ret i8 %trunc651}652 653define i2 @trunc_shl_1_i2_i64(i64 %val) {654; CHECK-LABEL: @trunc_shl_1_i2_i64(655; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[VAL:%.*]], 1656; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[SHL]] to i2657; CHECK-NEXT:    ret i2 [[TRUNC]]658;659  %shl = shl i64 %val, 1660  %trunc = trunc i64 %shl to i2661  ret i2 %trunc662}663 664define i32 @trunc_shl_1_i32_i64(i64 %val) {665; CHECK-LABEL: @trunc_shl_1_i32_i64(666; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32667; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 1668; CHECK-NEXT:    ret i32 [[TRUNC]]669;670  %shl = shl i64 %val, 1671  %trunc = trunc i64 %shl to i32672  ret i32 %trunc673}674 675define i32 @trunc_shl_16_i32_i64(i64 %val) {676; CHECK-LABEL: @trunc_shl_16_i32_i64(677; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32678; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 16679; CHECK-NEXT:    ret i32 [[TRUNC]]680;681  %shl = shl i64 %val, 16682  %trunc = trunc i64 %shl to i32683  ret i32 %trunc684}685 686define i32 @trunc_shl_33_i32_i64(i64 %val) {687; CHECK-LABEL: @trunc_shl_33_i32_i64(688; CHECK-NEXT:    ret i32 0689;690  %shl = shl i64 %val, 33691  %trunc = trunc i64 %shl to i32692  ret i32 %trunc693}694 695define i32 @trunc_shl_32_i32_i64(i64 %val) {696; CHECK-LABEL: @trunc_shl_32_i32_i64(697; CHECK-NEXT:    ret i32 0698;699  %shl = shl i64 %val, 32700  %trunc = trunc i64 %shl to i32701  ret i32 %trunc702}703 704; Should be able to handle vectors705define <2 x i32> @trunc_shl_16_v2i32_v2i64(<2 x i64> %val) {706; CHECK-LABEL: @trunc_shl_16_v2i32_v2i64(707; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>708; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], splat (i32 16)709; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]710;711  %shl = shl <2 x i64> %val, <i64 16, i64 16>712  %trunc = trunc <2 x i64> %shl to <2 x i32>713  ret <2 x i32> %trunc714}715 716define <2 x i32> @trunc_shl_nosplat_v2i32_v2i64(<2 x i64> %val) {717; CHECK-LABEL: @trunc_shl_nosplat_v2i32_v2i64(718; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>719; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 15, i32 16>720; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]721;722  %shl = shl <2 x i64> %val, <i64 15, i64 16>723  %trunc = trunc <2 x i64> %shl to <2 x i32>724  ret <2 x i32> %trunc725}726 727define void @trunc_shl_31_i32_i64_multi_use(i64 %val, ptr addrspace(1) %ptr0, ptr addrspace(1) %ptr1) {728; CHECK-LABEL: @trunc_shl_31_i32_i64_multi_use(729; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[VAL:%.*]], 31730; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[SHL]] to i32731; CHECK-NEXT:    store volatile i32 [[TRUNC]], ptr addrspace(1) [[PTR0:%.*]], align 4732; CHECK-NEXT:    store volatile i64 [[SHL]], ptr addrspace(1) [[PTR1:%.*]], align 8733; CHECK-NEXT:    ret void734;735  %shl = shl i64 %val, 31736  %trunc = trunc i64 %shl to i32737  store volatile i32 %trunc, ptr addrspace(1) %ptr0738  store volatile i64 %shl, ptr addrspace(1) %ptr1739  ret void740}741 742define i32 @trunc_shl_lshr_infloop(i64 %arg) {743; CHECK-LABEL: @trunc_shl_lshr_infloop(744; CHECK-NEXT:    [[ARG_TR:%.*]] = trunc i64 [[ARG:%.*]] to i32745; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[ARG_TR]], 1746; CHECK-NEXT:    [[C:%.*]] = and i32 [[TMP1]], -4747; CHECK-NEXT:    ret i32 [[C]]748;749  %A = lshr i64 %arg, 1750  %B = shl i64 %A, 2751  %C = trunc i64 %B to i32752  ret i32 %C753}754 755define <2 x i32> @trunc_shl_v2i32_v2i64_uniform(<2 x i64> %val) {756; CHECK-LABEL: @trunc_shl_v2i32_v2i64_uniform(757; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>758; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], splat (i32 31)759; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]760;761  %shl = shl <2 x i64> %val, <i64 31, i64 31>762  %trunc = trunc <2 x i64> %shl to <2 x i32>763  ret <2 x i32> %trunc764}765 766define <2 x i32> @trunc_shl_v2i32_v2i64_poison(<2 x i64> %val) {767; CHECK-LABEL: @trunc_shl_v2i32_v2i64_poison(768; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>769; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 31, i32 poison>770; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]771;772  %shl = shl <2 x i64> %val, <i64 31, i64 poison>773  %trunc = trunc <2 x i64> %shl to <2 x i32>774  ret <2 x i32> %trunc775}776 777define <2 x i32> @trunc_shl_v2i32_v2i64_nonuniform(<2 x i64> %val) {778; CHECK-LABEL: @trunc_shl_v2i32_v2i64_nonuniform(779; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc <2 x i64> [[VAL:%.*]] to <2 x i32>780; CHECK-NEXT:    [[TRUNC:%.*]] = shl <2 x i32> [[VAL_TR]], <i32 31, i32 12>781; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]782;783  %shl = shl <2 x i64> %val, <i64 31, i64 12>784  %trunc = trunc <2 x i64> %shl to <2 x i32>785  ret <2 x i32> %trunc786}787 788define <2 x i32> @trunc_shl_v2i32_v2i64_outofrange(<2 x i64> %val) {789; CHECK-LABEL: @trunc_shl_v2i32_v2i64_outofrange(790; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i64> [[VAL:%.*]], <i64 31, i64 33>791; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i64> [[SHL]] to <2 x i32>792; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]793;794  %shl = shl <2 x i64> %val, <i64 31, i64 33>795  %trunc = trunc <2 x i64> %shl to <2 x i32>796  ret <2 x i32> %trunc797}798 799define i32 @trunc_shl_ashr_infloop(i64 %arg) {800; CHECK-LABEL: @trunc_shl_ashr_infloop(801; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[ARG:%.*]], 1802; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32803; CHECK-NEXT:    [[C:%.*]] = and i32 [[TMP2]], -4804; CHECK-NEXT:    ret i32 [[C]]805;806  %A = ashr i64 %arg, 3807  %B = shl i64 %A, 2808  %C = trunc i64 %B to i32809  ret i32 %C810}811 812define i32 @trunc_shl_shl_infloop(i64 %arg) {813; CHECK-LABEL: @trunc_shl_shl_infloop(814; CHECK-NEXT:    [[ARG_TR:%.*]] = trunc i64 [[ARG:%.*]] to i32815; CHECK-NEXT:    [[C:%.*]] = shl i32 [[ARG_TR]], 3816; CHECK-NEXT:    ret i32 [[C]]817;818  %A = shl i64 %arg, 1819  %B = shl i64 %A, 2820  %C = trunc i64 %B to i32821  ret i32 %C822}823 824define i32 @trunc_shl_lshr_var(i64 %arg, i64 %val) {825; CHECK-LABEL: @trunc_shl_lshr_var(826; CHECK-NEXT:    [[A:%.*]] = lshr i64 [[ARG:%.*]], [[VAL:%.*]]827; CHECK-NEXT:    [[A_TR:%.*]] = trunc i64 [[A]] to i32828; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A_TR]], 2829; CHECK-NEXT:    ret i32 [[C]]830;831  %A = lshr i64 %arg, %val832  %B = shl i64 %A, 2833  %C = trunc i64 %B to i32834  ret i32 %C835}836 837define i32 @trunc_shl_ashr_var(i64 %arg, i64 %val) {838; CHECK-LABEL: @trunc_shl_ashr_var(839; CHECK-NEXT:    [[A:%.*]] = ashr i64 [[ARG:%.*]], [[VAL:%.*]]840; CHECK-NEXT:    [[A_TR:%.*]] = trunc i64 [[A]] to i32841; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A_TR]], 2842; CHECK-NEXT:    ret i32 [[C]]843;844  %A = ashr i64 %arg, %val845  %B = shl i64 %A, 2846  %C = trunc i64 %B to i32847  ret i32 %C848}849 850define i32 @trunc_shl_shl_var(i64 %arg, i64 %val) {851; CHECK-LABEL: @trunc_shl_shl_var(852; CHECK-NEXT:    [[A:%.*]] = shl i64 [[ARG:%.*]], [[VAL:%.*]]853; CHECK-NEXT:    [[A_TR:%.*]] = trunc i64 [[A]] to i32854; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A_TR]], 2855; CHECK-NEXT:    ret i32 [[C]]856;857  %A = shl i64 %arg, %val858  %B = shl i64 %A, 2859  %C = trunc i64 %B to i32860  ret i32 %C861}862 863define <8 x i16> @trunc_shl_v8i15_v8i32_15(<8 x i32> %a) {864; CHECK-LABEL: @trunc_shl_v8i15_v8i32_15(865; CHECK-NEXT:    [[A_TR:%.*]] = trunc <8 x i32> [[A:%.*]] to <8 x i16>866; CHECK-NEXT:    [[CONV:%.*]] = shl <8 x i16> [[A_TR]], splat (i16 15)867; CHECK-NEXT:    ret <8 x i16> [[CONV]]868;869  %shl = shl <8 x i32> %a, <i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15>870  %conv = trunc <8 x i32> %shl to <8 x i16>871  ret <8 x i16> %conv872}873 874define <8 x i16> @trunc_shl_v8i16_v8i32_16(<8 x i32> %a) {875; CHECK-LABEL: @trunc_shl_v8i16_v8i32_16(876; CHECK-NEXT:    ret <8 x i16> zeroinitializer877;878  %shl = shl <8 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>879  %conv = trunc <8 x i32> %shl to <8 x i16>880  ret <8 x i16> %conv881}882 883define <8 x i16> @trunc_shl_v8i16_v8i32_17(<8 x i32> %a) {884; CHECK-LABEL: @trunc_shl_v8i16_v8i32_17(885; CHECK-NEXT:    ret <8 x i16> zeroinitializer886;887  %shl = shl <8 x i32> %a, <i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17>888  %conv = trunc <8 x i32> %shl to <8 x i16>889  ret <8 x i16> %conv890}891 892define <8 x i16> @trunc_shl_v8i16_v8i32_4(<8 x i32> %a) {893; CHECK-LABEL: @trunc_shl_v8i16_v8i32_4(894; CHECK-NEXT:    [[A_TR:%.*]] = trunc <8 x i32> [[A:%.*]] to <8 x i16>895; CHECK-NEXT:    [[CONV:%.*]] = shl <8 x i16> [[A_TR]], splat (i16 4)896; CHECK-NEXT:    ret <8 x i16> [[CONV]]897;898  %shl = shl <8 x i32> %a, <i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4>899  %conv = trunc <8 x i32> %shl to <8 x i16>900  ret <8 x i16> %conv901}902 903; Although the mask is the same value, we don't create a shuffle for types that the backend may not be able to handle:904; trunc (shuffle X, C, Mask) --> shuffle (trunc X), C', Mask905 906define <4 x i8> @wide_shuf(<4 x i32> %x) {907; CHECK-LABEL: @wide_shuf(908; 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>909; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <4 x i32> [[SHUF]] to <4 x i8>910; CHECK-NEXT:    ret <4 x i8> [[TRUNC]]911;912  %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>913  %trunc = trunc <4 x i32> %shuf to <4 x i8>914  ret <4 x i8> %trunc915}916 917; trunc (shuffle X, poison, SplatMask) --> shuffle (trunc X), poison, SplatMask918 919define <4 x i8> @wide_splat1(<4 x i32> %x) {920; CHECK-LABEL: @wide_splat1(921; CHECK-NEXT:    [[TMP1:%.*]] = trunc <4 x i32> [[X:%.*]] to <4 x i8>922; CHECK-NEXT:    [[TRUNC:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>923; CHECK-NEXT:    ret <4 x i8> [[TRUNC]]924;925  %shuf = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>926  %trunc = trunc <4 x i32> %shuf to <4 x i8>927  ret <4 x i8> %trunc928}929 930; Test weird types.931; trunc (shuffle X, poison, SplatMask) --> shuffle (trunc X), poison, SplatMask932 933define <3 x i31> @wide_splat2(<3 x i33> %x) {934; CHECK-LABEL: @wide_splat2(935; CHECK-NEXT:    [[TMP1:%.*]] = trunc <3 x i33> [[X:%.*]] to <3 x i31>936; CHECK-NEXT:    [[TRUNC:%.*]] = shufflevector <3 x i31> [[TMP1]], <3 x i31> poison, <3 x i32> <i32 1, i32 1, i32 1>937; CHECK-NEXT:    ret <3 x i31> [[TRUNC]]938;939  %shuf = shufflevector <3 x i33> %x, <3 x i33> poison, <3 x i32> <i32 1, i32 1, i32 1>940  %trunc = trunc <3 x i33> %shuf to <3 x i31>941  ret <3 x i31> %trunc942}943 944; FIXME:945; trunc (shuffle X, poison, SplatMask) --> shuffle (trunc X), poison, SplatMask946; A mask with poison elements should still be considered a splat mask.947 948define <3 x i31> @wide_splat3(<3 x i33> %x) {949; CHECK-LABEL: @wide_splat3(950; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <3 x i33> [[X:%.*]], <3 x i33> poison, <3 x i32> <i32 poison, i32 1, i32 1>951; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <3 x i33> [[SHUF]] to <3 x i31>952; CHECK-NEXT:    ret <3 x i31> [[TRUNC]]953;954  %shuf = shufflevector <3 x i33> %x, <3 x i33> poison, <3 x i32> <i32 poison, i32 1, i32 1>955  %trunc = trunc <3 x i33> %shuf to <3 x i31>956  ret <3 x i31> %trunc957}958 959; TODO: The shuffle extends the length of the input vector. Should we shrink this?960 961define <8 x i8> @wide_lengthening_splat(<4 x i16> %v) {962; CHECK-LABEL: @wide_lengthening_splat(963; CHECK-NEXT:    [[TMP1:%.*]] = trunc <4 x i16> [[V:%.*]] to <4 x i8>964; CHECK-NEXT:    [[TR:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <8 x i32> zeroinitializer965; CHECK-NEXT:    ret <8 x i8> [[TR]]966;967  %shuf = shufflevector <4 x i16> %v, <4 x i16> %v, <8 x i32> zeroinitializer968  %tr = trunc <8 x i16> %shuf to <8 x i8>969  ret <8 x i8> %tr970}971 972; This is a negative test, we expect the trunc to remain after the shuffle as it973; might not be beneficial to preform trunc on a wider type974define <4 x i8> @wide_shortening_splat(<8 x i16> %v) {975; CHECK-LABEL: @wide_shortening_splat(976; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <8 x i16> [[V:%.*]], <8 x i16> poison, <4 x i32> zeroinitializer977; CHECK-NEXT:    [[TR:%.*]] = trunc <4 x i16> [[SHUF]] to <4 x i8>978; CHECK-NEXT:    ret <4 x i8> [[TR]]979;980  %shuf = shufflevector <8 x i16> %v, <8 x i16> %v, <4 x i32> zeroinitializer981  %tr = trunc <4 x i16> %shuf to <4 x i8>982  ret <4 x i8> %tr983}984 985define <2 x i8> @narrow_add_vec_constant(<2 x i32> %x) {986; CHECK-LABEL: @narrow_add_vec_constant(987; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>988; CHECK-NEXT:    [[TR:%.*]] = add <2 x i8> [[TMP1]], <i8 0, i8 127>989; CHECK-NEXT:    ret <2 x i8> [[TR]]990;991  %add = add <2 x i32> %x, <i32 256, i32 -129>992  %tr = trunc <2 x i32> %add to <2 x i8>993  ret <2 x i8> %tr994}995 996define <2 x i8> @narrow_mul_vec_constant(<2 x i32> %x) {997; CHECK-LABEL: @narrow_mul_vec_constant(998; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>999; CHECK-NEXT:    [[TR:%.*]] = mul <2 x i8> [[TMP1]], <i8 0, i8 127>1000; CHECK-NEXT:    ret <2 x i8> [[TR]]1001;1002  %add = mul <2 x i32> %x, <i32 256, i32 -129>1003  %tr = trunc <2 x i32> %add to <2 x i8>1004  ret <2 x i8> %tr1005}1006 1007define <2 x i8> @narrow_sub_vec_constant(<2 x i32> %x) {1008; CHECK-LABEL: @narrow_sub_vec_constant(1009; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>1010; CHECK-NEXT:    [[TR:%.*]] = sub <2 x i8> <i8 0, i8 127>, [[TMP1]]1011; CHECK-NEXT:    ret <2 x i8> [[TR]]1012;1013  %sub = sub <2 x i32> <i32 256, i32 -129>, %x1014  %tr = trunc <2 x i32> %sub to <2 x i8>1015  ret <2 x i8> %tr1016}1017 1018; If the select is narrowed based on the target's datalayout, we allow more optimizations.1019 1020define i16 @PR44545(i32 %t0, i32 %data) {1021; CHECK-LABEL: @PR44545(1022; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[DATA:%.*]], 01023; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[T0:%.*]] to i161024; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[ISZERO]], i16 -1, i16 [[TMP1]]1025; CHECK-NEXT:    ret i16 [[SUB]]1026;1027  %t1 = add nuw nsw i32 %t0, 11028  %iszero = icmp eq i32 %data, 01029  %ffs = select i1 %iszero, i32 0, i32 %t11030  %cast = trunc i32 %ffs to i161031  %sub = add nsw i16 %cast, -11032  ret i16 %sub1033}1034 1035; Make sure that SimplifyDemandedBits drops the nowrap flags1036define i8 @drop_nsw_trunc(i16 %x, i16 %y) {1037; CHECK-LABEL: @drop_nsw_trunc(1038; CHECK-NEXT:    [[AND2:%.*]] = and i16 [[X:%.*]], [[Y:%.*]]1039; CHECK-NEXT:    [[RES:%.*]] = trunc i16 [[AND2]] to i81040; CHECK-NEXT:    ret i8 [[RES]]1041;1042  %and = and i16 %x, 2551043  %and2 = and i16 %and, %y1044  %res = trunc nsw i16 %and2 to i81045  ret i8 %res1046}1047 1048define i8 @drop_nuw_trunc(i16 %x, i16 %y) {1049; CHECK-LABEL: @drop_nuw_trunc(1050; CHECK-NEXT:    [[AND2:%.*]] = and i16 [[X:%.*]], [[Y:%.*]]1051; CHECK-NEXT:    [[RES:%.*]] = trunc i16 [[AND2]] to i81052; CHECK-NEXT:    ret i8 [[RES]]1053;1054  %and = and i16 %x, 2551055  %and2 = and i16 %and, %y1056  %res = trunc nuw i16 %and2 to i81057  ret i8 %res1058}1059 1060define i8 @drop_both_trunc(i16 %x, i16 %y) {1061; CHECK-LABEL: @drop_both_trunc(1062; CHECK-NEXT:    [[AND2:%.*]] = and i16 [[X:%.*]], [[Y:%.*]]1063; CHECK-NEXT:    [[RES:%.*]] = trunc i16 [[AND2]] to i81064; CHECK-NEXT:    ret i8 [[RES]]1065;1066  %and = and i16 %x, 2551067  %and2 = and i16 %and, %y1068  %res = trunc nuw nsw i16 %and2 to i81069  ret i8 %res1070}1071 1072define i1 @trunc_xor(i8 %x, i8 %y) {1073; CHECK-LABEL: @trunc_xor(1074; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]1075; CHECK-NEXT:    [[R:%.*]] = trunc i8 [[XOR]] to i11076; CHECK-NEXT:    ret i1 [[R]]1077;1078  %xor = xor i8 %x, %y1079  %r = trunc i8 %xor to i11080  ret i1 %r1081}1082 1083define i1 @trunc_nuw_xor(i8 %x, i8 %y) {1084; CHECK-LABEL: @trunc_nuw_xor(1085; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]1086; CHECK-NEXT:    ret i1 [[R]]1087;1088  %xor = xor i8 %x, %y1089  %r = trunc nuw i8 %xor to i11090  ret i1 %r1091}1092 1093define i1 @trunc_nsw_xor(i8 %x, i8 %y) {1094; CHECK-LABEL: @trunc_nsw_xor(1095; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]1096; CHECK-NEXT:    ret i1 [[R]]1097;1098  %xor = xor i8 %x, %y1099  %r = trunc nsw i8 %xor to i11100  ret i1 %r1101}1102 1103define <2 x i1> @trunc_nuw_xor_vector(<2 x i8> %x, <2 x i8> %y) {1104; CHECK-LABEL: @trunc_nuw_xor_vector(1105; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[X:%.*]], [[Y:%.*]]1106; CHECK-NEXT:    ret <2 x i1> [[R]]1107;1108  %xor = xor <2 x i8> %x, %y1109  %r = trunc nuw <2 x i8> %xor to <2 x i1>1110  ret <2 x i1> %r1111}1112 1113define void @pr95547(i32 %x) {1114; CHECK-LABEL: @pr95547(1115; CHECK-NEXT:    [[X_TRUNC:%.*]] = trunc i32 [[X:%.*]] to i161116; CHECK-NEXT:    [[DIV:%.*]] = udiv i16 11, [[X_TRUNC]]1117; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X]], 2561118; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP:%.*]], label [[EXIT:%.*]]1119; CHECK:       loop:1120; CHECK-NEXT:    [[TRUNC:%.*]] = trunc nuw nsw i16 [[DIV]] to i81121; CHECK-NEXT:    call void @use.i8(i8 [[TRUNC]])1122; CHECK-NEXT:    br label [[LOOP]]1123; CHECK:       exit:1124; CHECK-NEXT:    ret void1125;1126  %x.trunc = trunc i32 %x to i161127  %div = udiv i16 11, %x.trunc1128  %cmp = icmp ult i32 %x, 2561129  br i1 %cmp, label %loop, label %exit1130 1131loop:1132  ; The loop is just here to prevent sinking.1133  %trunc = trunc i16 %div to i81134  call void @use.i8(i8 %trunc)1135  br label %loop1136 1137exit:1138  ret void1139}1140 1141define i1 @trunc_nuw_i1_non_zero(i8 %1) {1142; CHECK-LABEL: @trunc_nuw_i1_non_zero(1143; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP0:%.*]], 01144; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])1145; CHECK-NEXT:    ret i1 true1146;1147  %3 = icmp ne i8 %1, 01148  tail call void @llvm.assume(i1 %3)1149  %ret = trunc nuw i8 %1 to i11150  ret i1 %ret1151}1152 1153define i1 @neg_trunc_nuw_i1_maybe_zero(i8 %1) {1154; CHECK-LABEL: @neg_trunc_nuw_i1_maybe_zero(1155; CHECK-NEXT:    [[RET:%.*]] = trunc nuw i8 [[TMP0:%.*]] to i11156; CHECK-NEXT:    ret i1 [[RET]]1157;1158  %ret = trunc nuw i8 %1 to i11159  ret i1 %ret1160}1161 1162define i2 @neg_trunc_nuw_i2_non_zero(i8 %1) {1163; CHECK-LABEL: @neg_trunc_nuw_i2_non_zero(1164; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP0:%.*]], 01165; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])1166; CHECK-NEXT:    [[RET:%.*]] = trunc nuw i8 [[TMP0]] to i21167; CHECK-NEXT:    ret i2 [[RET]]1168;1169  %3 = icmp ne i8 %1, 01170  tail call void @llvm.assume(i1 %3)1171  %ret = trunc nuw i8 %1 to i21172  ret i2 %ret1173}1174 1175define i1 @neg_trunc_i1_non_zero(i8 %1) {1176; CHECK-LABEL: @neg_trunc_i1_non_zero(1177; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP0:%.*]], 01178; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])1179; CHECK-NEXT:    [[RET:%.*]] = trunc i8 [[TMP0]] to i11180; CHECK-NEXT:    ret i1 [[RET]]1181;1182  %3 = icmp ne i8 %1, 01183  tail call void @llvm.assume(i1 %3)1184  %ret = trunc i8 %1 to i11185  ret i1 %ret1186}1187 1188define i1 @trunc_nsw_i1_non_zero(i8 %1) {1189; CHECK-LABEL: @trunc_nsw_i1_non_zero(1190; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP0:%.*]], 01191; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])1192; CHECK-NEXT:    ret i1 true1193;1194  %3 = icmp ne i8 %1, 01195  tail call void @llvm.assume(i1 %3)1196  %ret = trunc nsw i8 %1 to i11197  ret i1 %ret1198}1199 1200define i1 @neg_trunc_nsw_i1_maybe_zero(i8 %1) {1201; CHECK-LABEL: @neg_trunc_nsw_i1_maybe_zero(1202; CHECK-NEXT:    [[RET:%.*]] = trunc nsw i8 [[TMP0:%.*]] to i11203; CHECK-NEXT:    ret i1 [[RET]]1204;1205  %ret = trunc nsw i8 %1 to i11206  ret i1 %ret1207}1208 1209define i2 @neg_trunc_nsw_i2_non_zero(i8 %1) {1210; CHECK-LABEL: @neg_trunc_nsw_i2_non_zero(1211; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP0:%.*]], 01212; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP2]])1213; CHECK-NEXT:    [[RET:%.*]] = trunc nsw i8 [[TMP0]] to i21214; CHECK-NEXT:    ret i2 [[RET]]1215;1216  %3 = icmp ne i8 %1, 01217  tail call void @llvm.assume(i1 %3)1218  %ret = trunc nsw i8 %1 to i21219  ret i2 %ret1220}1221