299 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=ANY,LE3; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=ANY,BE4 5define i32 @shrinkExtractElt_i64_to_i32_0(<3 x i64> %x) {6; LE-LABEL: @shrinkExtractElt_i64_to_i32_0(7; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>8; LE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 09; LE-NEXT: ret i32 [[T]]10;11; BE-LABEL: @shrinkExtractElt_i64_to_i32_0(12; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>13; BE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 114; BE-NEXT: ret i32 [[T]]15;16 %e = extractelement <3 x i64> %x, i32 017 %t = trunc i64 %e to i3218 ret i32 %t19}20 21define i32 @shrinkShiftExtractElt_i64_to_i32_0(<3 x i64> %x) {22; LE-LABEL: @shrinkShiftExtractElt_i64_to_i32_0(23; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>24; LE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 125; LE-NEXT: ret i32 [[T]]26;27; BE-LABEL: @shrinkShiftExtractElt_i64_to_i32_0(28; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>29; BE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 030; BE-NEXT: ret i32 [[T]]31;32 %e = extractelement <3 x i64> %x, i32 033 %s = lshr i64 %e, 3234 %t = trunc i64 %s to i3235 ret i32 %t36}37 38define i32 @vscale_shrinkExtractElt_i64_to_i32_0(<vscale x 3 x i64> %x) {39; LE-LABEL: @vscale_shrinkExtractElt_i64_to_i32_0(40; LE-NEXT: [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>41; LE-NEXT: [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 042; LE-NEXT: ret i32 [[T]]43;44; BE-LABEL: @vscale_shrinkExtractElt_i64_to_i32_0(45; BE-NEXT: [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>46; BE-NEXT: [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 147; BE-NEXT: ret i32 [[T]]48;49 %e = extractelement <vscale x 3 x i64> %x, i32 050 %t = trunc i64 %e to i3251 ret i32 %t52}53 54define i32 @vscale_shrinkShiftExtractElt_i64_to_i32_0(<vscale x 3 x i64> %x) {55; LE-LABEL: @vscale_shrinkShiftExtractElt_i64_to_i32_0(56; LE-NEXT: [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>57; LE-NEXT: [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 158; LE-NEXT: ret i32 [[T]]59;60; BE-LABEL: @vscale_shrinkShiftExtractElt_i64_to_i32_0(61; BE-NEXT: [[TMP1:%.*]] = bitcast <vscale x 3 x i64> [[X:%.*]] to <vscale x 6 x i32>62; BE-NEXT: [[T:%.*]] = extractelement <vscale x 6 x i32> [[TMP1]], i64 063; BE-NEXT: ret i32 [[T]]64;65 %e = extractelement <vscale x 3 x i64> %x, i32 066 %s = lshr i64 %e, 3267 %t = trunc i64 %s to i3268 ret i32 %t69}70 71define i32 @shrinkExtractElt_i64_to_i32_1(<3 x i64> %x) {72; LE-LABEL: @shrinkExtractElt_i64_to_i32_1(73; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>74; LE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 275; LE-NEXT: ret i32 [[T]]76;77; BE-LABEL: @shrinkExtractElt_i64_to_i32_1(78; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>79; BE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 380; BE-NEXT: ret i32 [[T]]81;82 %e = extractelement <3 x i64> %x, i32 183 %t = trunc i64 %e to i3284 ret i32 %t85}86 87define i32 @shrinkExtractElt_i64_to_i32_2(<3 x i64> %x) {88; LE-LABEL: @shrinkExtractElt_i64_to_i32_2(89; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>90; LE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 491; LE-NEXT: ret i32 [[T]]92;93; BE-LABEL: @shrinkExtractElt_i64_to_i32_2(94; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32>95; BE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i64 596; BE-NEXT: ret i32 [[T]]97;98 %e = extractelement <3 x i64> %x, i32 299 %t = trunc i64 %e to i32100 ret i32 %t101}102 103define i16 @shrinkExtractElt_i64_to_i16_0(<3 x i64> %x) {104; LE-LABEL: @shrinkExtractElt_i64_to_i16_0(105; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>106; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 0107; LE-NEXT: ret i16 [[T]]108;109; BE-LABEL: @shrinkExtractElt_i64_to_i16_0(110; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>111; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 3112; BE-NEXT: ret i16 [[T]]113;114 %e = extractelement <3 x i64> %x, i16 0115 %t = trunc i64 %e to i16116 ret i16 %t117}118 119define i16 @shrinkShiftExtractElt_i64_to_i16_0(<3 x i64> %x) {120; LE-LABEL: @shrinkShiftExtractElt_i64_to_i16_0(121; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>122; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 3123; LE-NEXT: ret i16 [[T]]124;125; BE-LABEL: @shrinkShiftExtractElt_i64_to_i16_0(126; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>127; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 0128; BE-NEXT: ret i16 [[T]]129;130 %e = extractelement <3 x i64> %x, i16 0131 %s = ashr i64 %e, 48132 %t = trunc i64 %s to i16133 ret i16 %t134}135 136define i16 @shrinkExtractElt_i64_to_i16_1(<3 x i64> %x) {137; LE-LABEL: @shrinkExtractElt_i64_to_i16_1(138; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>139; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 4140; LE-NEXT: ret i16 [[T]]141;142; BE-LABEL: @shrinkExtractElt_i64_to_i16_1(143; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>144; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 7145; BE-NEXT: ret i16 [[T]]146;147 %e = extractelement <3 x i64> %x, i16 1148 %t = trunc i64 %e to i16149 ret i16 %t150}151 152define i16 @shrinkExtractElt_i64_to_i16_2(<3 x i64> %x) {153; LE-LABEL: @shrinkExtractElt_i64_to_i16_2(154; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>155; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 8156; LE-NEXT: ret i16 [[T]]157;158; BE-LABEL: @shrinkExtractElt_i64_to_i16_2(159; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16>160; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 11161; BE-NEXT: ret i16 [[T]]162;163 %e = extractelement <3 x i64> %x, i16 2164 %t = trunc i64 %e to i16165 ret i16 %t166}167 168; Crazy types may be ok.169define i11 @shrinkExtractElt_i33_to_11_2(<3 x i33> %x) {170; LE-LABEL: @shrinkExtractElt_i33_to_11_2(171; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11>172; LE-NEXT: [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i64 6173; LE-NEXT: ret i11 [[T]]174;175; BE-LABEL: @shrinkExtractElt_i33_to_11_2(176; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11>177; BE-NEXT: [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i64 8178; BE-NEXT: ret i11 [[T]]179;180 %e = extractelement <3 x i33> %x, i16 2181 %t = trunc i33 %e to i11182 ret i11 %t183}184 185; Do not optimize if it would result in an invalid bitcast instruction.186define i13 @shrinkExtractElt_i67_to_i13_2(<3 x i67> %x) {187; ANY-LABEL: @shrinkExtractElt_i67_to_i13_2(188; ANY-NEXT: [[E:%.*]] = extractelement <3 x i67> [[X:%.*]], i64 2189; ANY-NEXT: [[T:%.*]] = trunc i67 [[E]] to i13190; ANY-NEXT: ret i13 [[T]]191;192 %e = extractelement <3 x i67> %x, i459 2193 %t = trunc i67 %e to i13194 ret i13 %t195}196 197; Do not optimize if the bitcast instruction would be valid, but the198; transform would be wrong.199define i30 @shrinkExtractElt_i40_to_i30_1(<3 x i40> %x) {200; ANY-LABEL: @shrinkExtractElt_i40_to_i30_1(201; ANY-NEXT: [[E:%.*]] = extractelement <3 x i40> [[X:%.*]], i64 1202; ANY-NEXT: [[T:%.*]] = trunc i40 [[E]] to i30203; ANY-NEXT: ret i30 [[T]]204;205 %e = extractelement <3 x i40> %x, i32 1206 %t = trunc i40 %e to i30207 ret i30 %t208}209 210; Do not optimize if the shift amount isn't a whole number of truncated bits.211define i16 @shrinkShiftExtractElt_i64_to_i16_0_badshift(<3 x i64> %x) {212; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_0_badshift(213; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 0214; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 31215; ANY-NEXT: [[T:%.*]] = trunc i64 [[S]] to i16216; ANY-NEXT: ret i16 [[T]]217;218 %e = extractelement <3 x i64> %x, i16 0219 %s = lshr i64 %e, 31220 %t = trunc i64 %s to i16221 ret i16 %t222}223 224; Do not canonicalize if that would increase the instruction count.225declare void @use(i64)226define i16 @shrinkExtractElt_i64_to_i16_2_extra_use(<3 x i64> %x) {227; ANY-LABEL: @shrinkExtractElt_i64_to_i16_2_extra_use(228; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2229; ANY-NEXT: call void @use(i64 [[E]])230; ANY-NEXT: [[T:%.*]] = trunc i64 [[E]] to i16231; ANY-NEXT: ret i16 [[T]]232;233 %e = extractelement <3 x i64> %x, i64 2234 call void @use(i64 %e)235 %t = trunc i64 %e to i16236 ret i16 %t237}238 239; Do not canonicalize if that would increase the instruction count.240define i16 @shrinkShiftExtractElt_i64_to_i16_2_extra_shift_use(<3 x i64> %x) {241; ANY-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_shift_use(242; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2243; ANY-NEXT: [[S:%.*]] = lshr i64 [[E]], 48244; ANY-NEXT: call void @use(i64 [[S]])245; ANY-NEXT: [[T:%.*]] = trunc nuw i64 [[S]] to i16246; ANY-NEXT: ret i16 [[T]]247;248 %e = extractelement <3 x i64> %x, i64 2249 %s = lshr i64 %e, 48250 call void @use(i64 %s)251 %t = trunc i64 %s to i16252 ret i16 %t253}254 255; OK to reuse the extract if we remove the shift+trunc.256define i16 @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use(<3 x i64> %x) {257; LE-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use(258; LE-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2259; LE-NEXT: call void @use(i64 [[E]])260; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X]] to <12 x i16>261; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 11262; LE-NEXT: ret i16 [[T]]263;264; BE-LABEL: @shrinkShiftExtractElt_i64_to_i16_2_extra_extract_use(265; BE-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2266; BE-NEXT: call void @use(i64 [[E]])267; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X]] to <12 x i16>268; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i64 8269; BE-NEXT: ret i16 [[T]]270;271 %e = extractelement <3 x i64> %x, i64 2272 call void @use(i64 %e)273 %s = lshr i64 %e, 48274 %t = trunc i64 %s to i16275 ret i16 %t276}277 278; Check to ensure PR45314 remains fixed.279define <4 x i64> @PR45314(<4 x i64> %x) {280; LE-LABEL: @PR45314(281; LE-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32>282; LE-NEXT: [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <8 x i32> zeroinitializer283; LE-NEXT: [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64>284; LE-NEXT: ret <4 x i64> [[B]]285;286; BE-LABEL: @PR45314(287; BE-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32>288; BE-NEXT: [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>289; BE-NEXT: [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64>290; BE-NEXT: ret <4 x i64> [[B]]291;292 %e = extractelement <4 x i64> %x, i32 0293 %t = trunc i64 %e to i32294 %i = insertelement <8 x i32> undef, i32 %t, i32 0295 %s = shufflevector <8 x i32> %i, <8 x i32> undef, <8 x i32> zeroinitializer296 %b = bitcast <8 x i32> %s to <4 x i64>297 ret <4 x i64> %b298}299