1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; If we extract (via lshr) some high bits, and then perform their sign-extension
5 ; conditionally depending on whether the extracted value is negative or not
6 ; (i.e. interpreting the highest extracted bit, which was the original signbit
7 ; of the value from which we extracted as a signbit), then we should just
8 ; perform extraction via `ashr`.
12 declare void @use1(i1)
13 declare void @use16(i16)
14 declare void @use32(i32)
15 declare void @use64(i64)
17 define i32 @t0_notrunc_add(i32 %data, i32 %nbits) {
18 ; CHECK-LABEL: @t0_notrunc_add(
19 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
20 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
21 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
22 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
23 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
24 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
25 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
26 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
27 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
28 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
29 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
30 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
32 %low_bits_to_skip = sub i32 32, %nbits
33 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
34 %should_signext = icmp slt i32 %data, 0
35 %all_bits_except_low_nbits = shl i32 -1, %nbits
36 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
38 call void @use32(i32 %low_bits_to_skip)
39 call void @use32(i32 %high_bits_extracted)
40 call void @use1(i1 %should_signext)
41 call void @use32(i32 %all_bits_except_low_nbits)
42 call void @use32(i32 %magic)
44 %signextended = add i32 %high_bits_extracted, %magic
48 define i32 @t0_notrunc_or(i32 %data, i32 %nbits) {
49 ; CHECK-LABEL: @t0_notrunc_or(
50 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
51 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
52 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
53 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
54 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
55 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
56 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
57 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
58 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
59 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
60 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
61 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
63 %low_bits_to_skip = sub i32 32, %nbits
64 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
65 %should_signext = icmp slt i32 %data, 0
66 %all_bits_except_low_nbits = shl i32 -1, %nbits
67 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
69 call void @use32(i32 %low_bits_to_skip)
70 call void @use32(i32 %high_bits_extracted)
71 call void @use1(i1 %should_signext)
72 call void @use32(i32 %all_bits_except_low_nbits)
73 call void @use32(i32 %magic)
75 %signextended = or i32 %high_bits_extracted, %magic
79 define i32 @t1_notrunc_sub(i32 %data, i32 %nbits) {
80 ; CHECK-LABEL: @t1_notrunc_sub(
81 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
82 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
83 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
84 ; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]
85 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
86 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
87 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
88 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
89 ; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
90 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
91 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
92 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
94 %low_bits_to_skip = sub i32 32, %nbits
95 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
96 %should_signext = icmp slt i32 %data, 0
97 %higher_bit_after_signbit = shl i32 1, %nbits
98 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0
100 call void @use32(i32 %low_bits_to_skip)
101 call void @use32(i32 %high_bits_extracted)
102 call void @use1(i1 %should_signext)
103 call void @use32(i32 %higher_bit_after_signbit)
104 call void @use32(i32 %magic)
106 %signextended = sub i32 %high_bits_extracted, %magic
107 ret i32 %signextended
110 define i32 @t2_trunc_add(i64 %data, i32 %nbits) {
111 ; CHECK-LABEL: @t2_trunc_add(
112 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
113 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
114 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
115 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
116 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
117 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
118 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
119 ; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
120 ; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
121 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
122 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
123 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
124 ; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
125 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
126 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
128 %low_bits_to_skip = sub i32 64, %nbits
129 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
130 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
131 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
132 %should_signext = icmp slt i64 %data, 0
133 %all_bits_except_low_nbits = shl i32 -1, %nbits
134 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use
136 call void @use32(i32 %low_bits_to_skip)
137 call void @use64(i64 %low_bits_to_skip_wide)
138 call void @use64(i64 %high_bits_extracted_wide)
139 call void @use32(i32 %high_bits_extracted)
140 call void @use1(i1 %should_signext)
141 call void @use32(i32 %all_bits_except_low_nbits)
143 %signextended = add i32 %magic, %high_bits_extracted
144 ret i32 %signextended
147 define i32 @t2_trunc_or(i64 %data, i32 %nbits) {
148 ; CHECK-LABEL: @t2_trunc_or(
149 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
150 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
151 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
152 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
153 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
154 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
155 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
156 ; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
157 ; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
158 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
159 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
160 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
161 ; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
162 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
163 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
165 %low_bits_to_skip = sub i32 64, %nbits
166 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
167 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
168 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
169 %should_signext = icmp slt i64 %data, 0
170 %all_bits_except_low_nbits = shl i32 -1, %nbits
171 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use
173 call void @use32(i32 %low_bits_to_skip)
174 call void @use64(i64 %low_bits_to_skip_wide)
175 call void @use64(i64 %high_bits_extracted_wide)
176 call void @use32(i32 %high_bits_extracted)
177 call void @use1(i1 %should_signext)
178 call void @use32(i32 %all_bits_except_low_nbits)
180 %signextended = or i32 %magic, %high_bits_extracted
181 ret i32 %signextended
184 define i32 @t3_trunc_sub(i64 %data, i32 %nbits) {
185 ; CHECK-LABEL: @t3_trunc_sub(
186 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
187 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
188 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
189 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
190 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
191 ; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]
192 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
193 ; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
194 ; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
195 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
196 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
197 ; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
198 ; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
199 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
200 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
202 %low_bits_to_skip = sub i32 64, %nbits
203 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
204 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
205 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
206 %should_signext = icmp slt i64 %data, 0
207 %higher_bit_after_signbit = shl i32 1, %nbits
208 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0 ; one-use
210 call void @use32(i32 %low_bits_to_skip)
211 call void @use64(i64 %low_bits_to_skip_wide)
212 call void @use64(i64 %high_bits_extracted_wide)
213 call void @use32(i32 %high_bits_extracted)
214 call void @use1(i1 %should_signext)
215 call void @use32(i32 %higher_bit_after_signbit)
217 %signextended = sub i32 %high_bits_extracted, %magic
218 ret i32 %signextended
223 define i32 @t4_commutativity0(i32 %data, i32 %nbits) {
224 ; CHECK-LABEL: @t4_commutativity0(
225 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
226 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
227 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
228 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
229 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
230 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
231 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
232 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
233 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
234 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
235 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
236 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
238 %low_bits_to_skip = sub i32 32, %nbits
239 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
240 %should_signext = icmp slt i32 %data, 0
241 %all_bits_except_low_nbits = shl i32 -1, %nbits
242 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
244 call void @use32(i32 %low_bits_to_skip)
245 call void @use32(i32 %high_bits_extracted)
246 call void @use1(i1 %should_signext)
247 call void @use32(i32 %all_bits_except_low_nbits)
248 call void @use32(i32 %magic)
250 %signextended = add i32 %high_bits_extracted, %magic
251 ret i32 %signextended
253 define i32 @t5_commutativity1(i32 %data, i32 %nbits) {
254 ; CHECK-LABEL: @t5_commutativity1(
255 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
256 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
257 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], -1
258 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
259 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]
260 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
261 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
262 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
263 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
264 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
265 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
266 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
268 %low_bits_to_skip = sub i32 32, %nbits
269 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
270 %should_signext = icmp sgt i32 %data, -1 ; swapped
271 %all_bits_except_low_nbits = shl i32 -1, %nbits
272 %magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; swapped
274 call void @use32(i32 %low_bits_to_skip)
275 call void @use32(i32 %high_bits_extracted)
276 call void @use1(i1 %should_signext)
277 call void @use32(i32 %all_bits_except_low_nbits)
278 call void @use32(i32 %magic)
280 %signextended = add i32 %high_bits_extracted, %magic
281 ret i32 %signextended
283 define i32 @t6_commutativity2(i32 %data, i32 %nbits) {
284 ; CHECK-LABEL: @t6_commutativity2(
285 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
286 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
287 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
288 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
289 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
290 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
291 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
292 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
293 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
294 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
295 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
296 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
298 %low_bits_to_skip = sub i32 32, %nbits
299 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
300 %should_signext = icmp slt i32 %data, 0
301 %all_bits_except_low_nbits = shl i32 -1, %nbits
302 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
304 call void @use32(i32 %low_bits_to_skip)
305 call void @use32(i32 %high_bits_extracted)
306 call void @use1(i1 %should_signext)
307 call void @use32(i32 %all_bits_except_low_nbits)
308 call void @use32(i32 %magic)
310 %signextended = add i32 %magic, %high_bits_extracted ; swapped
311 ret i32 %signextended
316 define i32 @t7_trunc_extrause0(i64 %data, i32 %nbits) {
317 ; CHECK-LABEL: @t7_trunc_extrause0(
318 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
319 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
320 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
321 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
322 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
323 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
324 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
325 ; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
326 ; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
327 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
328 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
329 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
330 ; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
331 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
332 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
334 %low_bits_to_skip = sub i32 64, %nbits
335 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
336 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
337 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use
338 %should_signext = icmp slt i64 %data, 0
339 %all_bits_except_low_nbits = shl i32 -1, %nbits
340 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use
342 call void @use32(i32 %low_bits_to_skip)
343 call void @use64(i64 %low_bits_to_skip_wide)
344 call void @use64(i64 %high_bits_extracted_wide)
345 call void @use32(i32 %high_bits_extracted)
346 call void @use1(i1 %should_signext)
347 call void @use32(i32 %all_bits_except_low_nbits)
349 %signextended = add i32 %magic, %high_bits_extracted
350 ret i32 %signextended
352 define i32 @t8_trunc_extrause1(i64 %data, i32 %nbits) {
353 ; CHECK-LABEL: @t8_trunc_extrause1(
354 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
355 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
356 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
357 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
358 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
359 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
360 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
361 ; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
362 ; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
363 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
364 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
365 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
366 ; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
367 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
368 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
370 %low_bits_to_skip = sub i32 64, %nbits
371 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
372 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
373 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; one-use
374 %should_signext = icmp slt i64 %data, 0
375 %all_bits_except_low_nbits = shl i32 -1, %nbits
376 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use
378 call void @use32(i32 %low_bits_to_skip)
379 call void @use64(i64 %low_bits_to_skip_wide)
380 call void @use64(i64 %high_bits_extracted_wide)
381 call void @use1(i1 %should_signext)
382 call void @use32(i32 %all_bits_except_low_nbits)
383 call void @use32(i32 %magic)
385 %signextended = add i32 %magic, %high_bits_extracted
386 ret i32 %signextended
388 define i32 @n9_trunc_extrause2(i64 %data, i32 %nbits) {
389 ; CHECK-LABEL: @n9_trunc_extrause2(
390 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
391 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
392 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
393 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
394 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
395 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
396 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
397 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
398 ; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
399 ; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
400 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
401 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
402 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
403 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
404 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
405 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
407 %low_bits_to_skip = sub i32 64, %nbits
408 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
409 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
410 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use
411 %should_signext = icmp slt i64 %data, 0
412 %all_bits_except_low_nbits = shl i32 -1, %nbits
413 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use
415 call void @use32(i32 %low_bits_to_skip)
416 call void @use64(i64 %low_bits_to_skip_wide)
417 call void @use64(i64 %high_bits_extracted_wide)
418 call void @use32(i32 %high_bits_extracted)
419 call void @use1(i1 %should_signext)
420 call void @use32(i32 %all_bits_except_low_nbits)
421 call void @use32(i32 %magic)
423 %signextended = add i32 %magic, %high_bits_extracted
424 ret i32 %signextended
427 define i32 @t10_preserve_exact(i32 %data, i32 %nbits) {
428 ; CHECK-LABEL: @t10_preserve_exact(
429 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
430 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr exact i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
431 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
432 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
433 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
434 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
435 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
436 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
437 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
438 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
439 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr exact i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
440 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
442 %low_bits_to_skip = sub i32 32, %nbits
443 %high_bits_extracted = lshr exact i32 %data, %low_bits_to_skip
444 %should_signext = icmp slt i32 %data, 0
445 %all_bits_except_low_nbits = shl i32 -1, %nbits
446 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
448 call void @use32(i32 %low_bits_to_skip)
449 call void @use32(i32 %high_bits_extracted)
450 call void @use1(i1 %should_signext)
451 call void @use32(i32 %all_bits_except_low_nbits)
452 call void @use32(i32 %magic)
454 %signextended = add i32 %high_bits_extracted, %magic
455 ret i32 %signextended
458 define i32 @t11_different_zext_of_shamt(i32 %data, i8 %nbits) {
459 ; CHECK-LABEL: @t11_different_zext_of_shamt(
460 ; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS:%.*]] to i16
461 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i16 32, [[NBITS_16BIT]]
462 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_32:%.*]] = zext i16 [[LOW_BITS_TO_SKIP]] to i32
463 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_32]]
464 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
465 ; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS]] to i32
466 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS_32BIT]]
467 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
468 ; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
469 ; CHECK-NEXT: call void @use16(i16 [[LOW_BITS_TO_SKIP]])
470 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP_32]])
471 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
472 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
473 ; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
474 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
475 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
476 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP_32]]
477 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
479 %nbits_16bit = zext i8 %nbits to i16
480 %low_bits_to_skip = sub i16 32, %nbits_16bit
481 %low_bits_to_skip_32 = zext i16 %low_bits_to_skip to i32
482 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip_32
483 %should_signext = icmp slt i32 %data, 0
484 %nbits_32bit = zext i8 %nbits to i32
485 %all_bits_except_low_nbits = shl i32 -1, %nbits_32bit
486 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
488 call void @use16(i16 %nbits_16bit)
489 call void @use16(i16 %low_bits_to_skip)
490 call void @use32(i32 %low_bits_to_skip_32)
491 call void @use32(i32 %high_bits_extracted)
492 call void @use1(i1 %should_signext)
493 call void @use32(i32 %nbits_32bit)
494 call void @use32(i32 %all_bits_except_low_nbits)
495 call void @use32(i32 %magic)
497 %signextended = add i32 %high_bits_extracted, %magic
498 ret i32 %signextended
501 define i32 @t12_add_sext_of_magic(i32 %data, i8 %nbits) {
502 ; CHECK-LABEL: @t12_add_sext_of_magic(
503 ; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
504 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
505 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
506 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
507 ; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
508 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]
509 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
510 ; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32
511 ; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
512 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
513 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
514 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
515 ; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
516 ; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
517 ; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
518 ; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
519 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
520 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
522 %nbits_32bit = zext i8 %nbits to i32
523 %low_bits_to_skip = sub i32 32, %nbits_32bit
524 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
525 %should_signext = icmp slt i32 %data, 0
526 %nbits_16bit = zext i8 %nbits to i16
527 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit
528 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
529 %magic_wide = sext i16 %magic to i32
531 call void @use32(i32 %nbits_32bit)
532 call void @use32(i32 %low_bits_to_skip)
533 call void @use32(i32 %high_bits_extracted)
534 call void @use1(i1 %should_signext)
535 call void @use16(i16 %nbits_16bit)
536 call void @use16(i16 %all_bits_except_low_nbits)
537 call void @use16(i16 %magic)
538 call void @use32(i32 %magic_wide)
540 %signextended = add i32 %high_bits_extracted, %magic_wide
541 ret i32 %signextended
544 define i32 @t13_sub_zext_of_magic(i32 %data, i8 %nbits) {
545 ; CHECK-LABEL: @t13_sub_zext_of_magic(
546 ; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
547 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
548 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
549 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
550 ; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
551 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]
552 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
553 ; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32
554 ; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
555 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
556 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
557 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
558 ; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
559 ; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
560 ; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
561 ; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
562 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
563 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
565 %nbits_32bit = zext i8 %nbits to i32
566 %low_bits_to_skip = sub i32 32, %nbits_32bit
567 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
568 %should_signext = icmp slt i32 %data, 0
569 %nbits_16bit = zext i8 %nbits to i16
570 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit
571 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
572 %magic_wide = zext i16 %magic to i32
574 call void @use32(i32 %nbits_32bit)
575 call void @use32(i32 %low_bits_to_skip)
576 call void @use32(i32 %high_bits_extracted)
577 call void @use1(i1 %should_signext)
578 call void @use16(i16 %nbits_16bit)
579 call void @use16(i16 %all_bits_except_low_nbits)
580 call void @use16(i16 %magic)
581 call void @use32(i32 %magic_wide)
583 %signextended = sub i32 %high_bits_extracted, %magic_wide
584 ret i32 %signextended
587 define i32 @t14_add_sext_of_shl(i32 %data, i8 %nbits) {
588 ; CHECK-LABEL: @t14_add_sext_of_shl(
589 ; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
590 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
591 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
592 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
593 ; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
594 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]
595 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = sext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32
596 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0
597 ; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
598 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
599 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
600 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
601 ; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
602 ; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
603 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]])
604 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
605 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
606 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
608 %nbits_32bit = zext i8 %nbits to i32
609 %low_bits_to_skip = sub i32 32, %nbits_32bit
610 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
611 %should_signext = icmp slt i32 %data, 0
612 %nbits_16bit = zext i8 %nbits to i16
613 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit
614 %all_bits_except_low_nbits_wide = sext i16 %all_bits_except_low_nbits to i32
615 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0
617 call void @use32(i32 %nbits_32bit)
618 call void @use32(i32 %low_bits_to_skip)
619 call void @use32(i32 %high_bits_extracted)
620 call void @use1(i1 %should_signext)
621 call void @use16(i16 %nbits_16bit)
622 call void @use16(i16 %all_bits_except_low_nbits)
623 call void @use32(i32 %all_bits_except_low_nbits_wide)
624 call void @use32(i32 %magic)
626 %signextended = add i32 %high_bits_extracted, %magic
627 ret i32 %signextended
630 define i32 @t15_sub_zext_of_shl(i32 %data, i8 %nbits) {
631 ; CHECK-LABEL: @t15_sub_zext_of_shl(
632 ; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
633 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
634 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
635 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
636 ; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
637 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]
638 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = zext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32
639 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0
640 ; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
641 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
642 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
643 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
644 ; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
645 ; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
646 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]])
647 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
648 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
649 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
651 %nbits_32bit = zext i8 %nbits to i32
652 %low_bits_to_skip = sub i32 32, %nbits_32bit
653 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
654 %should_signext = icmp slt i32 %data, 0
655 %nbits_16bit = zext i8 %nbits to i16
656 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit
657 %all_bits_except_low_nbits_wide = zext i16 %all_bits_except_low_nbits to i32
658 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0
660 call void @use32(i32 %nbits_32bit)
661 call void @use32(i32 %low_bits_to_skip)
662 call void @use32(i32 %high_bits_extracted)
663 call void @use1(i1 %should_signext)
664 call void @use16(i16 %nbits_16bit)
665 call void @use16(i16 %all_bits_except_low_nbits)
666 call void @use32(i32 %all_bits_except_low_nbits_wide)
667 call void @use32(i32 %magic)
669 %signextended = sub i32 %high_bits_extracted, %magic
670 ret i32 %signextended
675 define i32 @n16(i32 %data, i32 %nbits) {
677 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 31, [[NBITS:%.*]]
678 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
679 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
680 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
681 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
682 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
683 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
684 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
685 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
686 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
687 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
688 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
690 %low_bits_to_skip = sub i32 31, %nbits ; not 32
691 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
692 %should_signext = icmp slt i32 %data, 0
693 %all_bits_except_low_nbits = shl i32 -1, %nbits
694 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
696 call void @use32(i32 %low_bits_to_skip)
697 call void @use32(i32 %high_bits_extracted)
698 call void @use1(i1 %should_signext)
699 call void @use32(i32 %all_bits_except_low_nbits)
700 call void @use32(i32 %magic)
702 %signextended = add i32 %high_bits_extracted, %magic
703 ret i32 %signextended
706 define i32 @n17_add(i32 %data, i32 %nbits) {
707 ; CHECK-LABEL: @n17_add(
708 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
709 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
710 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
711 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i32 1, [[NBITS]]
712 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
713 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
714 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
715 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
716 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
717 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
718 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
719 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
721 %low_bits_to_skip = sub i32 32, %nbits
722 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
723 %should_signext = icmp slt i32 %data, 0
724 %all_bits_except_low_nbits = shl i32 1, %nbits ; not -1
725 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
727 call void @use32(i32 %low_bits_to_skip)
728 call void @use32(i32 %high_bits_extracted)
729 call void @use1(i1 %should_signext)
730 call void @use32(i32 %all_bits_except_low_nbits)
731 call void @use32(i32 %magic)
733 %signextended = add i32 %high_bits_extracted, %magic
734 ret i32 %signextended
737 define i32 @n18(i32 %data, i32 %nbits) {
739 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
740 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
741 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
742 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
743 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]
744 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
745 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
746 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
747 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
748 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
749 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
750 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
752 %low_bits_to_skip = sub i32 32, %nbits
753 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
754 %should_signext = icmp slt i32 %data, 0
755 %all_bits_except_low_nbits = shl i32 -1, %nbits
756 %magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; wrong order
758 call void @use32(i32 %low_bits_to_skip)
759 call void @use32(i32 %high_bits_extracted)
760 call void @use1(i1 %should_signext)
761 call void @use32(i32 %all_bits_except_low_nbits)
762 call void @use32(i32 %magic)
764 %signextended = add i32 %high_bits_extracted, %magic
765 ret i32 %signextended
768 define i32 @n19(i32 %data1, i32 %data2, i32 %nbits) {
770 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
771 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA1:%.*]], [[LOW_BITS_TO_SKIP]]
772 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA2:%.*]], 0
773 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
774 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
775 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
776 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
777 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
778 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
779 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
780 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
781 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
783 %low_bits_to_skip = sub i32 32, %nbits
784 %high_bits_extracted = lshr i32 %data1, %low_bits_to_skip ; not %data2
785 %should_signext = icmp slt i32 %data2, 0 ; not %data1
786 %all_bits_except_low_nbits = shl i32 -1, %nbits
787 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
789 call void @use32(i32 %low_bits_to_skip)
790 call void @use32(i32 %high_bits_extracted)
791 call void @use1(i1 %should_signext)
792 call void @use32(i32 %all_bits_except_low_nbits)
793 call void @use32(i32 %magic)
795 %signextended = add i32 %high_bits_extracted, %magic
796 ret i32 %signextended
799 define i32 @n20(i32 %data, i32 %nbits1, i32 %nbits2) {
801 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS1:%.*]]
802 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
803 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
804 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS2:%.*]]
805 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
806 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
807 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
808 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
809 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
810 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
811 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
812 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
814 %low_bits_to_skip = sub i32 32, %nbits1 ; not %nbits2
815 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
816 %should_signext = icmp slt i32 %data, 0
817 %all_bits_except_low_nbits = shl i32 -1, %nbits2 ; not %nbits1
818 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
820 call void @use32(i32 %low_bits_to_skip)
821 call void @use32(i32 %high_bits_extracted)
822 call void @use1(i1 %should_signext)
823 call void @use32(i32 %all_bits_except_low_nbits)
824 call void @use32(i32 %magic)
826 %signextended = add i32 %high_bits_extracted, %magic
827 ret i32 %signextended
830 define i32 @n21(i32 %data, i32 %nbits) {
832 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
833 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
834 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], 0
835 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
836 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
837 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
838 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
839 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
840 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
841 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
842 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
843 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
845 %low_bits_to_skip = sub i32 32, %nbits
846 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
847 %should_signext = icmp sgt i32 %data, 0 ; this isn't a sign bit test
848 %all_bits_except_low_nbits = shl i32 -1, %nbits
849 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
851 call void @use32(i32 %low_bits_to_skip)
852 call void @use32(i32 %high_bits_extracted)
853 call void @use1(i1 %should_signext)
854 call void @use32(i32 %all_bits_except_low_nbits)
855 call void @use32(i32 %magic)
857 %signextended = add i32 %high_bits_extracted, %magic
858 ret i32 %signextended
861 define i32 @n22(i64 %data, i32 %nbits) {
863 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 63, [[NBITS:%.*]]
864 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
865 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
866 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
867 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
868 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
869 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
870 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
871 ; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
872 ; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
873 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
874 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
875 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
876 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
877 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
878 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
880 %low_bits_to_skip = sub i32 63, %nbits ; not 64
881 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
882 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
883 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
884 %should_signext = icmp slt i64 %data, 0
885 %all_bits_except_low_nbits = shl i32 -1, %nbits
886 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
888 call void @use32(i32 %low_bits_to_skip)
889 call void @use64(i64 %low_bits_to_skip_wide)
890 call void @use64(i64 %high_bits_extracted_wide)
891 call void @use32(i32 %high_bits_extracted)
892 call void @use1(i1 %should_signext)
893 call void @use32(i32 %all_bits_except_low_nbits)
894 call void @use32(i32 %magic)
896 %signextended = add i32 %magic, %high_bits_extracted
897 ret i32 %signextended
900 define i32 @n23(i32 %data, i32 %nbits) {
902 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
903 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = ashr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
904 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
905 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
906 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
907 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
908 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
909 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
910 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
911 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
912 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
913 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
915 %low_bits_to_skip = sub i32 32, %nbits
916 %high_bits_extracted = ashr i32 %data, %low_bits_to_skip ; not `lshr`
917 %should_signext = icmp slt i32 %data, 0
918 %all_bits_except_low_nbits = shl i32 -1, %nbits
919 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
921 call void @use32(i32 %low_bits_to_skip)
922 call void @use32(i32 %high_bits_extracted)
923 call void @use1(i1 %should_signext)
924 call void @use32(i32 %all_bits_except_low_nbits)
925 call void @use32(i32 %magic)
927 %signextended = add i32 %high_bits_extracted, %magic
928 ret i32 %signextended
931 define i32 @n24(i32 %data, i32 %nbits) {
933 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
934 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
935 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
936 ; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]
937 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
938 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
939 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
940 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
941 ; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
942 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
943 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
944 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
946 %low_bits_to_skip = sub i32 32, %nbits
947 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
948 %should_signext = icmp slt i32 %data, 0
949 %higher_bit_after_signbit = shl i32 1, %nbits
950 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0
952 call void @use32(i32 %low_bits_to_skip)
953 call void @use32(i32 %high_bits_extracted)
954 call void @use1(i1 %should_signext)
955 call void @use32(i32 %higher_bit_after_signbit)
956 call void @use32(i32 %magic)
958 %signextended = sub i32 %magic, %high_bits_extracted ; wrong order; `sub` is not commutative
959 ret i32 %signextended
962 define i32 @n25_sub(i32 %data, i32 %nbits) {
963 ; CHECK-LABEL: @n25_sub(
964 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
965 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
966 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
967 ; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nsw i32 -1, [[NBITS]]
968 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
969 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
970 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
971 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
972 ; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
973 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
974 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
975 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
977 %low_bits_to_skip = sub i32 32, %nbits
978 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
979 %should_signext = icmp slt i32 %data, 0
980 %higher_bit_after_signbit = shl i32 -1, %nbits ; not 1
981 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0
983 call void @use32(i32 %low_bits_to_skip)
984 call void @use32(i32 %high_bits_extracted)
985 call void @use1(i1 %should_signext)
986 call void @use32(i32 %higher_bit_after_signbit)
987 call void @use32(i32 %magic)
989 %signextended = sub i32 %high_bits_extracted, %magic
990 ret i32 %signextended
993 define i32 @n26(i32 %data, i32 %nbits) {
995 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
996 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
997 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
998 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
999 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 -1
1000 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
1001 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
1002 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
1003 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
1004 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
1005 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
1006 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
1008 %low_bits_to_skip = sub i32 32, %nbits
1009 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
1010 %should_signext = icmp slt i32 %data, 0
1011 %all_bits_except_low_nbits = shl i32 -1, %nbits
1012 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 -1 ; not 0
1014 call void @use32(i32 %low_bits_to_skip)
1015 call void @use32(i32 %high_bits_extracted)
1016 call void @use1(i1 %should_signext)
1017 call void @use32(i32 %all_bits_except_low_nbits)
1018 call void @use32(i32 %magic)
1020 %signextended = add i32 %high_bits_extracted, %magic
1021 ret i32 %signextended
1024 define i32 @n27_add_zext_of_magic(i32 %data, i8 %nbits) {
1025 ; CHECK-LABEL: @n27_add_zext_of_magic(
1026 ; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
1027 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
1028 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
1029 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
1030 ; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
1031 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]
1032 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
1033 ; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32
1034 ; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
1035 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
1036 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
1037 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
1038 ; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
1039 ; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
1040 ; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
1041 ; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
1042 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC_WIDE]]
1043 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
1045 %nbits_32bit = zext i8 %nbits to i32
1046 %low_bits_to_skip = sub i32 32, %nbits_32bit
1047 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
1048 %should_signext = icmp slt i32 %data, 0
1049 %nbits_16bit = zext i8 %nbits to i16
1050 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit
1051 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
1052 %magic_wide = zext i16 %magic to i32 ; not sext
1054 call void @use32(i32 %nbits_32bit)
1055 call void @use32(i32 %low_bits_to_skip)
1056 call void @use32(i32 %high_bits_extracted)
1057 call void @use1(i1 %should_signext)
1058 call void @use16(i16 %nbits_16bit)
1059 call void @use16(i16 %all_bits_except_low_nbits)
1060 call void @use16(i16 %magic)
1061 call void @use32(i32 %magic_wide)
1063 %signextended = add i32 %high_bits_extracted, %magic_wide
1064 ret i32 %signextended
1067 define i32 @n28_sub_sext_of_magic(i32 %data, i8 %nbits) {
1068 ; CHECK-LABEL: @n28_sub_sext_of_magic(
1069 ; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
1070 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
1071 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
1072 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
1073 ; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
1074 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]
1075 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
1076 ; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32
1077 ; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
1078 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
1079 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
1080 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
1081 ; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
1082 ; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
1083 ; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
1084 ; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
1085 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC_WIDE]]
1086 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
1088 %nbits_32bit = zext i8 %nbits to i32
1089 %low_bits_to_skip = sub i32 32, %nbits_32bit
1090 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
1091 %should_signext = icmp slt i32 %data, 0
1092 %nbits_16bit = zext i8 %nbits to i16
1093 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit
1094 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
1095 %magic_wide = sext i16 %magic to i32 ; not zext
1097 call void @use32(i32 %nbits_32bit)
1098 call void @use32(i32 %low_bits_to_skip)
1099 call void @use32(i32 %high_bits_extracted)
1100 call void @use1(i1 %should_signext)
1101 call void @use16(i16 %nbits_16bit)
1102 call void @use16(i16 %all_bits_except_low_nbits)
1103 call void @use16(i16 %magic)
1104 call void @use32(i32 %magic_wide)
1106 %signextended = sub i32 %high_bits_extracted, %magic_wide
1107 ret i32 %signextended
1110 define i32 @n290_or_with_wrong_magic(i32 %data, i32 %nbits) {
1111 ; CHECK-LABEL: @n290_or_with_wrong_magic(
1112 ; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
1113 ; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
1114 ; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
1115 ; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i32 1, [[NBITS]]
1116 ; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
1117 ; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
1118 ; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
1119 ; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
1120 ; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
1121 ; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
1122 ; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
1123 ; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
1125 %low_bits_to_skip = sub i32 32, %nbits
1126 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip
1127 %should_signext = icmp slt i32 %data, 0
1128 %all_bits_except_low_nbits = shl i32 1, %nbits ; not -1
1129 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
1131 call void @use32(i32 %low_bits_to_skip)
1132 call void @use32(i32 %high_bits_extracted)
1133 call void @use1(i1 %should_signext)
1134 call void @use32(i32 %all_bits_except_low_nbits)
1135 call void @use32(i32 %magic)
1137 %signextended = or i32 %high_bits_extracted, %magic
1138 ret i32 %signextended