[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / InstCombine / variable-signext-of-variable-high-bit-extraction.ll
blob55bad9a57b86341257001751652e097bc5dfbc8e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use16(i16)
5 declare void @use32(i32)
6 declare void @use64(i64)
8 define i32 @t0(i64 %data, i32 %nbits) {
9 ; CHECK-LABEL: @t0(
10 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
11 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
12 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
13 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
14 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
15 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
16 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
17 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
18 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
19 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
20 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]
21 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
22 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
24   %skip_high = sub i32 64, %nbits
25   call void @use32(i32 %skip_high)
26   %skip_high_wide = zext i32 %skip_high to i64
27   call void @use64(i64 %skip_high_wide)
28   %extracted = lshr i64 %data, %skip_high_wide
29   call void @use64(i64 %extracted)
30   %extracted_narrow = trunc i64 %extracted to i32
31   call void @use32(i32 %extracted_narrow)
32   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
33   call void @use32(i32 %num_high_bits_to_smear_narrow)
34   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
35   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
36   ret i32 %signextended
38 define i32 @t0_zext_of_nbits(i64 %data, i8 %nbits_narrow) {
39 ; CHECK-LABEL: @t0_zext_of_nbits(
40 ; CHECK-NEXT:    [[NBITS:%.*]] = zext i8 [[NBITS_NARROW:%.*]] to i16
41 ; CHECK-NEXT:    call void @use16(i16 [[NBITS]])
42 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub nsw i16 64, [[NBITS]]
43 ; CHECK-NEXT:    call void @use16(i16 [[SKIP_HIGH]])
44 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i16 [[SKIP_HIGH]] to i64
45 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
46 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
47 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
48 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
49 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
50 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW_NARROW:%.*]] = sub nsw i16 32, [[NBITS]]
51 ; CHECK-NEXT:    call void @use16(i16 [[NUM_HIGH_BITS_TO_SMEAR_NARROW_NARROW]])
52 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = zext i16 [[NUM_HIGH_BITS_TO_SMEAR_NARROW_NARROW]] to i32
53 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
54 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]
55 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
56 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
58   %nbits = zext i8 %nbits_narrow to i16
59   call void @use16(i16 %nbits)
60   %skip_high = sub i16 64, %nbits
61   call void @use16(i16 %skip_high)
62   %skip_high_wide = zext i16 %skip_high to i64
63   call void @use64(i64 %skip_high_wide)
64   %extracted = lshr i64 %data, %skip_high_wide
65   call void @use64(i64 %extracted)
66   %extracted_narrow = trunc i64 %extracted to i32
67   call void @use32(i32 %extracted_narrow)
68   %num_high_bits_to_smear_narrow_narrow = sub i16 32, %nbits
69   call void @use16(i16 %num_high_bits_to_smear_narrow_narrow)
70   %num_high_bits_to_smear_narrow = zext i16 %num_high_bits_to_smear_narrow_narrow to i32
71   call void @use32(i32 %num_high_bits_to_smear_narrow)
72   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
73   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
74   ret i32 %signextended
76 define i32 @t0_exact(i64 %data, i32 %nbits) {
77 ; CHECK-LABEL: @t0_exact(
78 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
79 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
80 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
81 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
82 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr exact i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
83 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
84 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
85 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
86 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
87 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
88 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i64 [[DATA]], [[SKIP_HIGH_WIDE]]
89 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
90 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
92   %skip_high = sub i32 64, %nbits
93   call void @use32(i32 %skip_high)
94   %skip_high_wide = zext i32 %skip_high to i64
95   call void @use64(i64 %skip_high_wide)
96   %extracted = lshr exact i64 %data, %skip_high_wide ; We can preserve `exact`-ness of the original shift.
97   call void @use64(i64 %extracted)
98   %extracted_narrow = trunc i64 %extracted to i32
99   call void @use32(i32 %extracted_narrow)
100   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
101   call void @use32(i32 %num_high_bits_to_smear_narrow)
102   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
103   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
104   ret i32 %signextended
107 define i32 @t1_redundant_sext(i64 %data, i32 %nbits) {
108 ; CHECK-LABEL: @t1_redundant_sext(
109 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
110 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
111 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
112 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
113 ; CHECK-NEXT:    [[EXTRACTED_WITH_SIGNEXTENSION:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
114 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED_WITH_SIGNEXTENSION]])
115 ; CHECK-NEXT:    [[EXTRACTED_WITH_SIGNEXTENSION_NARROW:%.*]] = trunc i64 [[EXTRACTED_WITH_SIGNEXTENSION]] to i32
116 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_WITH_SIGNEXTENSION_NARROW]])
117 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
118 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
119 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_WITH_SIGNEXTENSION_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
120 ; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT_POSITIONED]])
121 ; CHECK-NEXT:    ret i32 [[EXTRACTED_WITH_SIGNEXTENSION_NARROW]]
123   %skip_high = sub i32 64, %nbits
124   call void @use32(i32 %skip_high)
125   %skip_high_wide = zext i32 %skip_high to i64
126   call void @use64(i64 %skip_high_wide)
127   %extracted_with_signextension = ashr i64 %data, %skip_high_wide
128   call void @use64(i64 %extracted_with_signextension)
129   %extracted_with_signextension_narrow = trunc i64 %extracted_with_signextension to i32 ; this is already the answer.
130   call void @use32(i32 %extracted_with_signextension_narrow)
131   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
132   call void @use32(i32 %num_high_bits_to_smear_narrow)
133   %signbit_positioned = shl i32 %extracted_with_signextension_narrow, %num_high_bits_to_smear_narrow
134   call void @use32(i32 %signbit_positioned)
135   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
136   ret i32 %signextended
139 define i64 @t2_notrunc(i64 %data, i64 %nbits) {
140 ; CHECK-LABEL: @t2_notrunc(
141 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i64 64, [[NBITS:%.*]]
142 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH]])
143 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH]]
144 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
145 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR:%.*]] = sub i64 64, [[NBITS]]
146 ; CHECK-NEXT:    call void @use64(i64 [[NUM_HIGH_BITS_TO_SMEAR]])
147 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i64 [[EXTRACTED]], [[NUM_HIGH_BITS_TO_SMEAR]]
148 ; CHECK-NEXT:    call void @use64(i64 [[SIGNBIT_POSITIONED]])
149 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH]]
150 ; CHECK-NEXT:    ret i64 [[SIGNEXTENDED]]
152   %skip_high = sub i64 64, %nbits
153   call void @use64(i64 %skip_high)
154   %extracted = lshr i64 %data, %skip_high
155   call void @use64(i64 %extracted)
156   %num_high_bits_to_smear = sub i64 64, %nbits
157   call void @use64(i64 %num_high_bits_to_smear)
158   %signbit_positioned = shl i64 %extracted, %num_high_bits_to_smear ;
159   call void @use64(i64 %signbit_positioned)
160   %signextended = ashr i64 %signbit_positioned, %num_high_bits_to_smear ; can just shift %data itself.
161   ret i64 %signextended
164 define i64 @t3_notrunc_redundant_sext(i64 %data, i64 %nbits) {
165 ; CHECK-LABEL: @t3_notrunc_redundant_sext(
166 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i64 64, [[NBITS:%.*]]
167 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH]])
168 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH]]
169 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
170 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR:%.*]] = sub i64 64, [[NBITS]]
171 ; CHECK-NEXT:    call void @use64(i64 [[NUM_HIGH_BITS_TO_SMEAR]])
172 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i64 [[EXTRACTED]], [[NUM_HIGH_BITS_TO_SMEAR]]
173 ; CHECK-NEXT:    call void @use64(i64 [[SIGNBIT_POSITIONED]])
174 ; CHECK-NEXT:    ret i64 [[EXTRACTED]]
176   %skip_high = sub i64 64, %nbits
177   call void @use64(i64 %skip_high)
178   %extracted = ashr i64 %data, %skip_high ; this is already the answer.
179   call void @use64(i64 %extracted)
180   %num_high_bits_to_smear = sub i64 64, %nbits
181   call void @use64(i64 %num_high_bits_to_smear)
182   %signbit_positioned = shl i64 %extracted, %num_high_bits_to_smear
183   call void @use64(i64 %signbit_positioned)
184   %signextended = ashr i64 %signbit_positioned, %num_high_bits_to_smear
185   ret i64 %signextended
188 define <2 x i32> @t4_vec(<2 x i64> %data, <2 x i32> %nbits) {
189 ; CHECK-LABEL: @t4_vec(
190 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub <2 x i32> splat (i32 64), [[NBITS:%.*]]
191 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext nneg <2 x i32> [[SKIP_HIGH]] to <2 x i64>
192 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i64> [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
193 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i32>
194 ; CHECK-NEXT:    ret <2 x i32> [[SIGNEXTENDED]]
196   %skip_high = sub <2 x i32> <i32 64, i32 64>, %nbits
197   %skip_high_wide = zext <2 x i32> %skip_high to <2 x i64>
198   %extracted = lshr <2 x i64> %data, %skip_high_wide
199   %extracted_narrow = trunc <2 x i64> %extracted to <2 x i32>
200   %num_high_bits_to_smear_narrow = sub <2 x i32> <i32 32, i32 32>, %nbits
201   %signbit_positioned = shl <2 x i32> %extracted_narrow, %num_high_bits_to_smear_narrow
202   %signextended = ashr <2 x i32> %signbit_positioned, %num_high_bits_to_smear_narrow
203   ret <2 x i32> %signextended
206 define <3 x i32> @t5_vec_poison(<3 x i64> %data, <3 x i32> %nbits) {
207 ; CHECK-LABEL: @t5_vec_poison(
208 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub <3 x i32> <i32 64, i32 64, i32 poison>, [[NBITS:%.*]]
209 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext nneg <3 x i32> [[SKIP_HIGH]] to <3 x i64>
210 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr <3 x i64> [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
211 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc <3 x i64> [[TMP1]] to <3 x i32>
212 ; CHECK-NEXT:    ret <3 x i32> [[SIGNEXTENDED]]
214   %skip_high = sub <3 x i32> <i32 64, i32 64, i32 poison>, %nbits
215   %skip_high_wide = zext <3 x i32> %skip_high to <3 x i64>
216   %extracted = lshr <3 x i64> %data, %skip_high_wide
217   %extracted_narrow = trunc <3 x i64> %extracted to <3 x i32>
218   %num_high_bits_to_smear_narrow0 = sub <3 x i32> <i32 32, i32 32, i32 poison>, %nbits
219   %num_high_bits_to_smear_narrow1 = sub <3 x i32> <i32 poison, i32 32, i32 32>, %nbits
220   %signbit_positioned = shl <3 x i32> %extracted_narrow, %num_high_bits_to_smear_narrow0
221   %signextended = ashr <3 x i32> %signbit_positioned, %num_high_bits_to_smear_narrow1
222   ret <3 x i32> %signextended
225 ; Extra-uses
226 define i32 @t6_extrause_good0(i64 %data, i32 %nbits) {
227 ; CHECK-LABEL: @t6_extrause_good0(
228 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
229 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
230 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
231 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
232 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
233 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
234 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
235 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
236 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
237 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
238 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]
239 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
240 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
242   %skip_high = sub i32 64, %nbits
243   call void @use32(i32 %skip_high)
244   %skip_high_wide = zext i32 %skip_high to i64
245   call void @use64(i64 %skip_high_wide)
246   %extracted = lshr i64 %data, %skip_high_wide
247   call void @use64(i64 %extracted)
248   %extracted_narrow = trunc i64 %extracted to i32
249   call void @use32(i32 %extracted_narrow)
250   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
251   call void @use32(i32 %num_high_bits_to_smear_narrow)
252   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow ; will go away
253   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
254   ret i32 %signextended
256 define i32 @t7_extrause_good1(i64 %data, i32 %nbits) {
257 ; CHECK-LABEL: @t7_extrause_good1(
258 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
259 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
260 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
261 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
262 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
263 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
264 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
265 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
266 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW0:%.*]] = sub i32 32, [[NBITS]]
267 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW0]])
268 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW0]]
269 ; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT_POSITIONED]])
270 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]
271 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
272 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
274   %skip_high = sub i32 64, %nbits
275   call void @use32(i32 %skip_high)
276   %skip_high_wide = zext i32 %skip_high to i64
277   call void @use64(i64 %skip_high_wide)
278   %extracted = lshr i64 %data, %skip_high_wide
279   call void @use64(i64 %extracted)
280   %extracted_narrow = trunc i64 %extracted to i32
281   call void @use32(i32 %extracted_narrow)
282   %num_high_bits_to_smear_narrow0 = sub i32 32, %nbits
283   call void @use32(i32 %num_high_bits_to_smear_narrow0)
284   %num_high_bits_to_smear_narrow1 = sub i32 32, %nbits ; will go away.
285   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow0
286   call void @use32(i32 %signbit_positioned)
287   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow1
288   ret i32 %signextended
290 define i32 @n8_extrause_bad(i64 %data, i32 %nbits) {
291 ; CHECK-LABEL: @n8_extrause_bad(
292 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
293 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
294 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
295 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
296 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
297 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
298 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
299 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
300 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
301 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
302 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
303 ; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT_POSITIONED]])
304 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
305 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
307   %skip_high = sub i32 64, %nbits
308   call void @use32(i32 %skip_high)
309   %skip_high_wide = zext i32 %skip_high to i64
310   call void @use64(i64 %skip_high_wide)
311   %extracted = lshr i64 %data, %skip_high_wide
312   call void @use64(i64 %extracted)
313   %extracted_narrow = trunc i64 %extracted to i32
314   call void @use32(i32 %extracted_narrow)
315   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
316   call void @use32(i32 %num_high_bits_to_smear_narrow)
317   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
318   call void @use32(i32 %signbit_positioned)
319   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow ; neither of operands will go away.
320   ret i32 %signextended
323 ; Negative tests
324 define i32 @n9(i64 %data, i32 %nbits) {
325 ; CHECK-LABEL: @n9(
326 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 63, [[NBITS:%.*]]
327 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
328 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
329 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
330 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
331 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
332 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
333 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
334 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
335 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
336 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
337 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
338 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
340   %skip_high = sub i32 63, %nbits ; not 64
341   call void @use32(i32 %skip_high)
342   %skip_high_wide = zext i32 %skip_high to i64
343   call void @use64(i64 %skip_high_wide)
344   %extracted = lshr i64 %data, %skip_high_wide
345   call void @use64(i64 %extracted)
346   %extracted_narrow = trunc i64 %extracted to i32
347   call void @use32(i32 %extracted_narrow)
348   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
349   call void @use32(i32 %num_high_bits_to_smear_narrow)
350   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
351   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
352   ret i32 %signextended
355 define i32 @n10(i64 %data, i32 %nbits) {
356 ; CHECK-LABEL: @n10(
357 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
358 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
359 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
360 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
361 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
362 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
363 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
364 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
365 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 31, [[NBITS]]
366 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
367 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
368 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
369 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
371   %skip_high = sub i32 64, %nbits
372   call void @use32(i32 %skip_high)
373   %skip_high_wide = zext i32 %skip_high to i64
374   call void @use64(i64 %skip_high_wide)
375   %extracted = lshr i64 %data, %skip_high_wide
376   call void @use64(i64 %extracted)
377   %extracted_narrow = trunc i64 %extracted to i32
378   call void @use32(i32 %extracted_narrow)
379   %num_high_bits_to_smear_narrow = sub i32 31, %nbits ; not 32
380   call void @use32(i32 %num_high_bits_to_smear_narrow)
381   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
382   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
383   ret i32 %signextended
386 define i32 @n11(i64 %data, i32 %nbits1, i32 %nbits2) {
387 ; CHECK-LABEL: @n11(
388 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS1:%.*]]
389 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
390 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
391 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
392 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
393 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
394 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
395 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
396 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS2:%.*]]
397 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
398 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
399 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
400 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
402   %skip_high = sub i32 64, %nbits1 ; not %nbits2
403   call void @use32(i32 %skip_high)
404   %skip_high_wide = zext i32 %skip_high to i64
405   call void @use64(i64 %skip_high_wide)
406   %extracted = lshr i64 %data, %skip_high_wide
407   call void @use64(i64 %extracted)
408   %extracted_narrow = trunc i64 %extracted to i32
409   call void @use32(i32 %extracted_narrow)
410   %num_high_bits_to_smear_narrow = sub i32 32, %nbits2 ; not %nbits1
411   call void @use32(i32 %num_high_bits_to_smear_narrow)
412   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
413   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow
414   ret i32 %signextended
417 define i32 @n12(i64 %data, i32 %nbits1, i32 %nbits2) {
418 ; CHECK-LABEL: @n12(
419 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS1:%.*]]
420 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
421 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
422 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
423 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
424 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
425 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
426 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
427 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW1:%.*]] = sub i32 32, [[NBITS1]]
428 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW2:%.*]] = sub i32 32, [[NBITS2:%.*]]
429 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW1]])
430 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW2]])
431 ; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW1]]
432 ; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW2]]
433 ; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]
435   %skip_high = sub i32 64, %nbits1
436   call void @use32(i32 %skip_high)
437   %skip_high_wide = zext i32 %skip_high to i64
438   call void @use64(i64 %skip_high_wide)
439   %extracted = lshr i64 %data, %skip_high_wide
440   call void @use64(i64 %extracted)
441   %extracted_narrow = trunc i64 %extracted to i32
442   call void @use32(i32 %extracted_narrow)
443   %num_high_bits_to_smear_narrow1 = sub i32 32, %nbits1 ; not %nbits2
444   %num_high_bits_to_smear_narrow2 = sub i32 32, %nbits2 ; not %nbits1
445   call void @use32(i32 %num_high_bits_to_smear_narrow1)
446   call void @use32(i32 %num_high_bits_to_smear_narrow2)
447   %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow1
448   %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow2
449   ret i32 %signextended
452 define i32 @n13(i64 %data, i32 %nbits) {
453 ; CHECK-LABEL: @n13(
454 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
455 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
456 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
457 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
458 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
459 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
460 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
461 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
462 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
463 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
464 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 -1, [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
465 ; CHECK-NEXT:    [[RES:%.*]] = and i32 [[TMP1]], [[EXTRACTED_NARROW]]
466 ; CHECK-NEXT:    ret i32 [[RES]]
468   %skip_high = sub i32 64, %nbits
469   call void @use32(i32 %skip_high)
470   %skip_high_wide = zext i32 %skip_high to i64
471   call void @use64(i64 %skip_high_wide)
472   %extracted = lshr i64 %data, %skip_high_wide
473   call void @use64(i64 %extracted)
474   %extracted_narrow = trunc i64 %extracted to i32
475   call void @use32(i32 %extracted_narrow)
476   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
477   call void @use32(i32 %num_high_bits_to_smear_narrow)
478   %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
479   %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr
480   ret i32 %res
482 define i32 @n13_extrause(i64 %data, i32 %nbits) {
483 ; CHECK-LABEL: @n13_extrause(
484 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
485 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
486 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
487 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
488 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
489 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
490 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
491 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
492 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
493 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
494 ; CHECK-NEXT:    [[HIGHBITS_CLEANED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
495 ; CHECK-NEXT:    call void @use32(i32 [[HIGHBITS_CLEANED]])
496 ; CHECK-NEXT:    [[RES:%.*]] = lshr exact i32 [[HIGHBITS_CLEANED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
497 ; CHECK-NEXT:    ret i32 [[RES]]
499   %skip_high = sub i32 64, %nbits
500   call void @use32(i32 %skip_high)
501   %skip_high_wide = zext i32 %skip_high to i64
502   call void @use64(i64 %skip_high_wide)
503   %extracted = lshr i64 %data, %skip_high_wide
504   call void @use64(i64 %extracted)
505   %extracted_narrow = trunc i64 %extracted to i32
506   call void @use32(i32 %extracted_narrow)
507   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
508   call void @use32(i32 %num_high_bits_to_smear_narrow)
509   %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
510   call void @use32(i32 %highbits_cleaned)
511   %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr
512   ret i32 %res
514 define i32 @n14(i64 %data, i32 %nbits) {
515 ; CHECK-LABEL: @n14(
516 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
517 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
518 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
519 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
520 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
521 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
522 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
523 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
524 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
525 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
526 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 -1, [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
527 ; CHECK-NEXT:    [[RES:%.*]] = and i32 [[TMP1]], [[EXTRACTED_NARROW]]
528 ; CHECK-NEXT:    ret i32 [[RES]]
530   %skip_high = sub i32 64, %nbits
531   call void @use32(i32 %skip_high)
532   %skip_high_wide = zext i32 %skip_high to i64
533   call void @use64(i64 %skip_high_wide)
534   %extracted = ashr i64 %data, %skip_high_wide
535   call void @use64(i64 %extracted)
536   %extracted_narrow = trunc i64 %extracted to i32
537   call void @use32(i32 %extracted_narrow)
538   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
539   call void @use32(i32 %num_high_bits_to_smear_narrow)
540   %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
541   %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr
542   ret i32 %res
544 define i32 @n14_extrause(i64 %data, i32 %nbits) {
545 ; CHECK-LABEL: @n14_extrause(
546 ; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]
547 ; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])
548 ; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64
549 ; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])
550 ; CHECK-NEXT:    [[EXTRACTED:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]
551 ; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])
552 ; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32
553 ; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])
554 ; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]
555 ; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])
556 ; CHECK-NEXT:    [[HIGHBITS_CLEANED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
557 ; CHECK-NEXT:    call void @use32(i32 [[HIGHBITS_CLEANED]])
558 ; CHECK-NEXT:    [[RES:%.*]] = lshr exact i32 [[HIGHBITS_CLEANED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]
559 ; CHECK-NEXT:    ret i32 [[RES]]
561   %skip_high = sub i32 64, %nbits
562   call void @use32(i32 %skip_high)
563   %skip_high_wide = zext i32 %skip_high to i64
564   call void @use64(i64 %skip_high_wide)
565   %extracted = ashr i64 %data, %skip_high_wide
566   call void @use64(i64 %extracted)
567   %extracted_narrow = trunc i64 %extracted to i32
568   call void @use32(i32 %extracted_narrow)
569   %num_high_bits_to_smear_narrow = sub i32 32, %nbits
570   call void @use32(i32 %num_high_bits_to_smear_narrow)
571   %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow
572   call void @use32(i32 %highbits_cleaned)
573   %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr
574   ret i32 %res