1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
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`.
9
10; Base patterns.
11
12declare void @use1(i1)
13declare void @use16(i16)
14declare void @use32(i32)
15declare void @use64(i64)
16
17define 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]]
31;
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
37
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)
43
44  %signextended = add i32 %high_bits_extracted, %magic
45  ret i32 %signextended
46}
47
48define 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]]
62;
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
68
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)
74
75  %signextended = or i32 %high_bits_extracted, %magic
76  ret i32 %signextended
77}
78
79define 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]]
93;
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
99
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)
105
106  %signextended = sub i32 %high_bits_extracted, %magic
107  ret i32 %signextended
108}
109
110define 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]]
127;
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
135
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)
142
143  %signextended = add i32 %magic, %high_bits_extracted
144  ret i32 %signextended
145}
146
147define 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]]
164;
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
172
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)
179
180  %signextended = or i32 %magic, %high_bits_extracted
181  ret i32 %signextended
182}
183
184define 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]]
201;
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
209
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)
216
217  %signextended = sub i32 %high_bits_extracted, %magic
218  ret i32 %signextended
219}
220
221; Commutativity
222
223define 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]]
237;
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
243
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)
249
250  %signextended = add i32 %high_bits_extracted, %magic
251  ret i32 %signextended
252}
253define 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]]
267;
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
273
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)
279
280  %signextended = add i32 %high_bits_extracted, %magic
281  ret i32 %signextended
282}
283define 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]]
297;
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
303
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)
309
310  %signextended = add i32 %magic, %high_bits_extracted ; swapped
311  ret i32 %signextended
312}
313
314; Extra uses
315
316define 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]]
333;
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
341
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)
348
349  %signextended = add i32 %magic, %high_bits_extracted
350  ret i32 %signextended
351}
352define 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]]
369;
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
377
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)
384
385  %signextended = add i32 %magic, %high_bits_extracted
386  ret i32 %signextended
387}
388define 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]]
406;
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
414
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)
422
423  %signextended = add i32 %magic, %high_bits_extracted
424  ret i32 %signextended
425}
426
427define 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]]
441;
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
447
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)
453
454  %signextended = add i32 %high_bits_extracted, %magic
455  ret i32 %signextended
456}
457
458define 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]]
478;
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
487
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)
496
497  %signextended = add i32 %high_bits_extracted, %magic
498  ret i32 %signextended
499}
500
501define 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]]
521;
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
530
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)
539
540  %signextended = add i32 %high_bits_extracted, %magic_wide
541  ret i32 %signextended
542}
543
544define 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]]
564;
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
573
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)
582
583  %signextended = sub i32 %high_bits_extracted, %magic_wide
584  ret i32 %signextended
585}
586
587define 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]]
607;
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
616
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)
625
626  %signextended = add i32 %high_bits_extracted, %magic
627  ret i32 %signextended
628}
629
630define 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]]
650;
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
659
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)
668
669  %signextended = sub i32 %high_bits_extracted, %magic
670  ret i32 %signextended
671}
672
673; Negative tests.
674
675define 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]]
689;
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
695
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)
701
702  %signextended = add i32 %high_bits_extracted, %magic
703  ret i32 %signextended
704}
705
706define 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]]
720;
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
726
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)
732
733  %signextended = add i32 %high_bits_extracted, %magic
734  ret i32 %signextended
735}
736
737define 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]]
751;
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
757
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)
763
764  %signextended = add i32 %high_bits_extracted, %magic
765  ret i32 %signextended
766}
767
768define 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]]
782;
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
788
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)
794
795  %signextended = add i32 %high_bits_extracted, %magic
796  ret i32 %signextended
797}
798
799define 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]]
813;
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
819
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)
825
826  %signextended = add i32 %high_bits_extracted, %magic
827  ret i32 %signextended
828}
829
830define 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]]
844;
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
850
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)
856
857  %signextended = add i32 %high_bits_extracted, %magic
858  ret i32 %signextended
859}
860
861define 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]]
879;
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
887
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)
895
896  %signextended = add i32 %magic, %high_bits_extracted
897  ret i32 %signextended
898}
899
900define 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]]
914;
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
920
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)
926
927  %signextended = add i32 %high_bits_extracted, %magic
928  ret i32 %signextended
929}
930
931define 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]]
945;
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
951
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)
957
958  %signextended = sub i32 %magic, %high_bits_extracted ; wrong order; `sub` is not commutative
959  ret i32 %signextended
960}
961
962define 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]]
976;
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
982
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)
988
989  %signextended = sub i32 %high_bits_extracted, %magic
990  ret i32 %signextended
991}
992
993define 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]]
1007;
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
1013
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)
1019
1020  %signextended = add i32 %high_bits_extracted, %magic
1021  ret i32 %signextended
1022}
1023
1024define 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]]
1044;
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
1053
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)
1062
1063  %signextended = add i32 %high_bits_extracted, %magic_wide
1064  ret i32 %signextended
1065}
1066
1067define 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]]
1087;
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
1096
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)
1105
1106  %signextended = sub i32 %high_bits_extracted, %magic_wide
1107  ret i32 %signextended
1108}
1109
1110define 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]]
1124;
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
1130
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)
1136
1137  %signextended = or i32 %high_bits_extracted, %magic
1138  ret i32 %signextended
1139}
1140
1141define i32 @bitwidth_does_not_fit(i3 %arg) {
1142; CHECK-LABEL: @bitwidth_does_not_fit(
1143; CHECK-NEXT:    [[NEG:%.*]] = sub i3 0, [[ARG:%.*]]
1144; CHECK-NEXT:    [[NEG_EXT:%.*]] = zext i3 [[NEG]] to i32
1145; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 1, [[NEG_EXT]]
1146; CHECK-NEXT:    [[INC:%.*]] = add nuw nsw i32 [[SHR]], 1
1147; CHECK-NEXT:    ret i32 [[INC]]
1148;
1149  %neg = sub i3 0, %arg
1150  %neg.ext = zext i3 %neg to i32
1151  %shr = lshr i32 1, %neg.ext
1152  %inc = add i32 %shr, 1
1153  ret i32 %inc
1154}
1155