1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=ANY,LE 3; RUN: opt < %s -instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=ANY,BE 4 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]], i32 0 9; 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]], i32 1 14; BE-NEXT: ret i32 [[T]] 15; 16 %e = extractelement <3 x i64> %x, i32 0 17 %t = trunc i64 %e to i32 18 ret i32 %t 19} 20 21define i32 @shrinkExtractElt_i64_to_i32_1(<3 x i64> %x) { 22; LE-LABEL: @shrinkExtractElt_i64_to_i32_1( 23; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32> 24; LE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 2 25; LE-NEXT: ret i32 [[T]] 26; 27; BE-LABEL: @shrinkExtractElt_i64_to_i32_1( 28; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32> 29; BE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 3 30; BE-NEXT: ret i32 [[T]] 31; 32 %e = extractelement <3 x i64> %x, i32 1 33 %t = trunc i64 %e to i32 34 ret i32 %t 35} 36 37define i32 @shrinkExtractElt_i64_to_i32_2(<3 x i64> %x) { 38; LE-LABEL: @shrinkExtractElt_i64_to_i32_2( 39; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32> 40; LE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 4 41; LE-NEXT: ret i32 [[T]] 42; 43; BE-LABEL: @shrinkExtractElt_i64_to_i32_2( 44; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32> 45; BE-NEXT: [[T:%.*]] = extractelement <6 x i32> [[TMP1]], i32 5 46; BE-NEXT: ret i32 [[T]] 47; 48 %e = extractelement <3 x i64> %x, i32 2 49 %t = trunc i64 %e to i32 50 ret i32 %t 51} 52 53define i16 @shrinkExtractElt_i64_to_i16_0(<3 x i64> %x) { 54; LE-LABEL: @shrinkExtractElt_i64_to_i16_0( 55; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16> 56; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 0 57; LE-NEXT: ret i16 [[T]] 58; 59; BE-LABEL: @shrinkExtractElt_i64_to_i16_0( 60; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16> 61; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 3 62; BE-NEXT: ret i16 [[T]] 63; 64 %e = extractelement <3 x i64> %x, i16 0 65 %t = trunc i64 %e to i16 66 ret i16 %t 67} 68 69define i16 @shrinkExtractElt_i64_to_i16_1(<3 x i64> %x) { 70; LE-LABEL: @shrinkExtractElt_i64_to_i16_1( 71; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16> 72; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 4 73; LE-NEXT: ret i16 [[T]] 74; 75; BE-LABEL: @shrinkExtractElt_i64_to_i16_1( 76; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16> 77; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 7 78; BE-NEXT: ret i16 [[T]] 79; 80 %e = extractelement <3 x i64> %x, i16 1 81 %t = trunc i64 %e to i16 82 ret i16 %t 83} 84 85define i16 @shrinkExtractElt_i64_to_i16_2(<3 x i64> %x) { 86; LE-LABEL: @shrinkExtractElt_i64_to_i16_2( 87; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16> 88; LE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 8 89; LE-NEXT: ret i16 [[T]] 90; 91; BE-LABEL: @shrinkExtractElt_i64_to_i16_2( 92; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <12 x i16> 93; BE-NEXT: [[T:%.*]] = extractelement <12 x i16> [[TMP1]], i32 11 94; BE-NEXT: ret i16 [[T]] 95; 96 %e = extractelement <3 x i64> %x, i16 2 97 %t = trunc i64 %e to i16 98 ret i16 %t 99} 100 101; Crazy types may be ok. 102define i11 @shrinkExtractElt_i33_to_11_2(<3 x i33> %x) { 103; LE-LABEL: @shrinkExtractElt_i33_to_11_2( 104; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11> 105; LE-NEXT: [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i32 6 106; LE-NEXT: ret i11 [[T]] 107; 108; BE-LABEL: @shrinkExtractElt_i33_to_11_2( 109; BE-NEXT: [[TMP1:%.*]] = bitcast <3 x i33> [[X:%.*]] to <9 x i11> 110; BE-NEXT: [[T:%.*]] = extractelement <9 x i11> [[TMP1]], i32 8 111; BE-NEXT: ret i11 [[T]] 112; 113 %e = extractelement <3 x i33> %x, i16 2 114 %t = trunc i33 %e to i11 115 ret i11 %t 116} 117 118; Do not optimize if it would result in an invalid bitcast instruction. 119define i13 @shrinkExtractElt_i67_to_i13_2(<3 x i67> %x) { 120; ANY-LABEL: @shrinkExtractElt_i67_to_i13_2( 121; ANY-NEXT: [[E:%.*]] = extractelement <3 x i67> [[X:%.*]], i459 2 122; ANY-NEXT: [[T:%.*]] = trunc i67 [[E]] to i13 123; ANY-NEXT: ret i13 [[T]] 124; 125 %e = extractelement <3 x i67> %x, i459 2 126 %t = trunc i67 %e to i13 127 ret i13 %t 128} 129 130; Do not optimize if the bitcast instruction would be valid, but the 131; transform would be wrong. 132define i30 @shrinkExtractElt_i40_to_i30_1(<3 x i40> %x) { 133; ANY-LABEL: @shrinkExtractElt_i40_to_i30_1( 134; ANY-NEXT: [[E:%.*]] = extractelement <3 x i40> [[X:%.*]], i32 1 135; ANY-NEXT: [[T:%.*]] = trunc i40 [[E]] to i30 136; ANY-NEXT: ret i30 [[T]] 137; 138 %e = extractelement <3 x i40> %x, i32 1 139 %t = trunc i40 %e to i30 140 ret i30 %t 141} 142 143; Do not canonicalize if that would increase the instruction count. 144declare void @use(i64) 145define i16 @shrinkExtractElt_i64_to_i16_2_extra_use(<3 x i64> %x) { 146; ANY-LABEL: @shrinkExtractElt_i64_to_i16_2_extra_use( 147; ANY-NEXT: [[E:%.*]] = extractelement <3 x i64> [[X:%.*]], i64 2 148; ANY-NEXT: call void @use(i64 [[E]]) 149; ANY-NEXT: [[T:%.*]] = trunc i64 [[E]] to i16 150; ANY-NEXT: ret i16 [[T]] 151; 152 %e = extractelement <3 x i64> %x, i64 2 153 call void @use(i64 %e) 154 %t = trunc i64 %e to i16 155 ret i16 %t 156} 157 158; Check to ensure PR45314 remains fixed. 159define <4 x i64> @PR45314(<4 x i64> %x) { 160; LE-LABEL: @PR45314( 161; LE-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32> 162; LE-NEXT: [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> zeroinitializer 163; LE-NEXT: [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64> 164; LE-NEXT: ret <4 x i64> [[B]] 165; 166; BE-LABEL: @PR45314( 167; BE-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32> 168; BE-NEXT: [[S:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> undef, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> 169; BE-NEXT: [[B:%.*]] = bitcast <8 x i32> [[S]] to <4 x i64> 170; BE-NEXT: ret <4 x i64> [[B]] 171; 172 %e = extractelement <4 x i64> %x, i32 0 173 %t = trunc i64 %e to i32 174 %i = insertelement <8 x i32> undef, i32 %t, i32 0 175 %s = shufflevector <8 x i32> %i, <8 x i32> undef, <8 x i32> zeroinitializer 176 %b = bitcast <8 x i32> %s to <4 x i64> 177 ret <4 x i64> %b 178} 179