Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / conditional-variable-length-signext-after-high-bit-extract.ll
blob5569af452de4fcce46b01461610e4af08f233b0b
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`.
10 ; Base patterns.
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
45   ret i32 %signextended
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
76   ret i32 %signextended
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
221 ; Commutativity
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
314 ; Extra uses
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
673 ; Negative tests.
675 define i32 @n16(i32 %data, i32 %nbits) {
676 ; CHECK-LABEL: @n16(
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) {
738 ; CHECK-LABEL: @n18(
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) {
769 ; CHECK-LABEL: @n19(
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) {
800 ; CHECK-LABEL: @n20(
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) {
831 ; CHECK-LABEL: @n21(
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) {
862 ; CHECK-LABEL: @n22(
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) {
901 ; CHECK-LABEL: @n23(
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) {
932 ; CHECK-LABEL: @n24(
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) {
994 ; CHECK-LABEL: @n26(
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