blob: 8caf93d690b500449ee19f7702a5c72300479b2a [file] [log] [blame]
David Majnemerb5e365c2017-01-04 02:21:37 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
David Majnemerb5e365c2017-01-04 02:21:37 +00004declare i32 @callee()
5
Sanjay Patelfcf8c7c2018-09-14 20:33:40 +00006declare void @use(i64)
7
Sanjay Patel7b9e1af2018-09-14 18:05:14 +00008define i64 @sext_sext_add(i32 %A) {
9; CHECK-LABEL: @sext_sext_add(
10; CHECK-NEXT: [[B:%.*]] = ashr i32 [[A:%.*]], 7
11; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A]], 9
Sanjay Patel2426eb42018-09-14 20:40:46 +000012; CHECK-NEXT: [[NARROW:%.*]] = add nsw i32 [[B]], [[C]]
13; CHECK-NEXT: [[F:%.*]] = sext i32 [[NARROW]] to i64
Sanjay Patel7b9e1af2018-09-14 18:05:14 +000014; CHECK-NEXT: ret i64 [[F]]
15;
16 %B = ashr i32 %A, 7
17 %C = ashr i32 %A, 9
18 %D = sext i32 %B to i64
19 %E = sext i32 %C to i64
20 %F = add i64 %D, %E
21 ret i64 %F
22}
23
Sanjay Patelfcf8c7c2018-09-14 20:33:40 +000024; Negative test
25
26define i64 @sext_zext_add_mismatched_exts(i32 %A) {
27; CHECK-LABEL: @sext_zext_add_mismatched_exts(
28; CHECK-NEXT: [[B:%.*]] = ashr i32 [[A:%.*]], 7
29; CHECK-NEXT: [[C:%.*]] = lshr i32 [[A]], 9
30; CHECK-NEXT: [[D:%.*]] = sext i32 [[B]] to i64
31; CHECK-NEXT: [[E:%.*]] = zext i32 [[C]] to i64
32; CHECK-NEXT: [[F:%.*]] = add nsw i64 [[D]], [[E]]
33; CHECK-NEXT: ret i64 [[F]]
34;
35 %B = ashr i32 %A, 7
36 %C = lshr i32 %A, 9
37 %D = sext i32 %B to i64
38 %E = zext i32 %C to i64
39 %F = add i64 %D, %E
40 ret i64 %F
41}
42
43; Negative test
44
45define i64 @sext_sext_add_mismatched_types(i16 %A, i32 %x) {
46; CHECK-LABEL: @sext_sext_add_mismatched_types(
47; CHECK-NEXT: [[B:%.*]] = ashr i16 [[A:%.*]], 7
48; CHECK-NEXT: [[C:%.*]] = ashr i32 [[X:%.*]], 9
49; CHECK-NEXT: [[D:%.*]] = sext i16 [[B]] to i64
50; CHECK-NEXT: [[E:%.*]] = sext i32 [[C]] to i64
51; CHECK-NEXT: [[F:%.*]] = add nsw i64 [[D]], [[E]]
52; CHECK-NEXT: ret i64 [[F]]
53;
54 %B = ashr i16 %A, 7
55 %C = ashr i32 %x, 9
56 %D = sext i16 %B to i64
57 %E = sext i32 %C to i64
58 %F = add i64 %D, %E
59 ret i64 %F
60}
61
62define i64 @sext_sext_add_extra_use1(i32 %A) {
63; CHECK-LABEL: @sext_sext_add_extra_use1(
64; CHECK-NEXT: [[B:%.*]] = ashr i32 [[A:%.*]], 7
65; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A]], 9
66; CHECK-NEXT: [[D:%.*]] = sext i32 [[B]] to i64
67; CHECK-NEXT: call void @use(i64 [[D]])
Sanjay Patel2426eb42018-09-14 20:40:46 +000068; CHECK-NEXT: [[NARROW:%.*]] = add nsw i32 [[B]], [[C]]
69; CHECK-NEXT: [[F:%.*]] = sext i32 [[NARROW]] to i64
Sanjay Patelfcf8c7c2018-09-14 20:33:40 +000070; CHECK-NEXT: ret i64 [[F]]
71;
72 %B = ashr i32 %A, 7
73 %C = ashr i32 %A, 9
74 %D = sext i32 %B to i64
75 call void @use(i64 %D)
76 %E = sext i32 %C to i64
77 %F = add i64 %D, %E
78 ret i64 %F
79}
80
81define i64 @sext_sext_add_extra_use2(i32 %A) {
82; CHECK-LABEL: @sext_sext_add_extra_use2(
83; CHECK-NEXT: [[B:%.*]] = ashr i32 [[A:%.*]], 7
84; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A]], 9
85; CHECK-NEXT: [[E:%.*]] = sext i32 [[C]] to i64
86; CHECK-NEXT: call void @use(i64 [[E]])
Sanjay Patel2426eb42018-09-14 20:40:46 +000087; CHECK-NEXT: [[NARROW:%.*]] = add nsw i32 [[B]], [[C]]
88; CHECK-NEXT: [[F:%.*]] = sext i32 [[NARROW]] to i64
Sanjay Patelfcf8c7c2018-09-14 20:33:40 +000089; CHECK-NEXT: ret i64 [[F]]
90;
91 %B = ashr i32 %A, 7
92 %C = ashr i32 %A, 9
93 %D = sext i32 %B to i64
94 %E = sext i32 %C to i64
95 call void @use(i64 %E)
96 %F = add i64 %D, %E
97 ret i64 %F
98}
99
100; Negative test - if both extends have extra uses, we need an extra instruction.
101
102define i64 @sext_sext_add_extra_use3(i32 %A) {
103; CHECK-LABEL: @sext_sext_add_extra_use3(
104; CHECK-NEXT: [[B:%.*]] = ashr i32 [[A:%.*]], 7
105; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A]], 9
106; CHECK-NEXT: [[D:%.*]] = sext i32 [[B]] to i64
107; CHECK-NEXT: call void @use(i64 [[D]])
108; CHECK-NEXT: [[E:%.*]] = sext i32 [[C]] to i64
109; CHECK-NEXT: call void @use(i64 [[E]])
110; CHECK-NEXT: [[F:%.*]] = add nsw i64 [[D]], [[E]]
111; CHECK-NEXT: ret i64 [[F]]
112;
113 %B = ashr i32 %A, 7
114 %C = ashr i32 %A, 9
115 %D = sext i32 %B to i64
116 call void @use(i64 %D)
117 %E = sext i32 %C to i64
118 call void @use(i64 %E)
119 %F = add i64 %D, %E
120 ret i64 %F
121}
122
David Majnemerb5e365c2017-01-04 02:21:37 +0000123define i64 @test1(i32 %V) {
124; CHECK-LABEL: @test1(
125; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !0
126; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !0
Sanjay Patel2426eb42018-09-14 20:40:46 +0000127; CHECK-NEXT: [[NARROW:%.*]] = add nuw nsw i32 [[CALL1]], [[CALL2]]
128; CHECK-NEXT: [[ADD:%.*]] = zext i32 [[NARROW]] to i64
David Majnemerb5e365c2017-01-04 02:21:37 +0000129; CHECK-NEXT: ret i64 [[ADD]]
130;
131 %call1 = call i32 @callee(), !range !0
132 %call2 = call i32 @callee(), !range !0
133 %zext1 = sext i32 %call1 to i64
134 %zext2 = sext i32 %call2 to i64
135 %add = add i64 %zext1, %zext2
136 ret i64 %add
137}
138
139define i64 @test2(i32 %V) {
140; CHECK-LABEL: @test2(
141; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !0
142; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !0
143; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[CALL1]], [[CALL2]]
Sanjay Patelf7ba0ac2018-09-14 17:53:44 +0000144; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[ADD]] to i64
145; CHECK-NEXT: ret i64 [[TMP1]]
David Majnemerb5e365c2017-01-04 02:21:37 +0000146;
147 %call1 = call i32 @callee(), !range !0
148 %call2 = call i32 @callee(), !range !0
149 %add = add i32 %call1, %call2
150 %zext = sext i32 %add to i64
151 ret i64 %zext
152}
153
154define i64 @test3(i32 %V) {
155; CHECK-LABEL: @test3(
156; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !0
157; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !0
Sanjay Patel90a36342018-09-14 22:23:35 +0000158; CHECK-NEXT: [[NARROW:%.*]] = mul nuw nsw i32 [[CALL1]], [[CALL2]]
159; CHECK-NEXT: [[ADD:%.*]] = zext i32 [[NARROW]] to i64
David Majnemerb5e365c2017-01-04 02:21:37 +0000160; CHECK-NEXT: ret i64 [[ADD]]
161;
162 %call1 = call i32 @callee(), !range !0
163 %call2 = call i32 @callee(), !range !0
164 %zext1 = sext i32 %call1 to i64
165 %zext2 = sext i32 %call2 to i64
166 %add = mul i64 %zext1, %zext2
167 ret i64 %add
168}
169
170define i64 @test4(i32 %V) {
171; CHECK-LABEL: @test4(
172; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !0
173; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !0
174; CHECK-NEXT: [[ADD:%.*]] = mul nuw nsw i32 [[CALL1]], [[CALL2]]
Sanjay Patelf7ba0ac2018-09-14 17:53:44 +0000175; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[ADD]] to i64
176; CHECK-NEXT: ret i64 [[TMP1]]
David Majnemerb5e365c2017-01-04 02:21:37 +0000177;
178 %call1 = call i32 @callee(), !range !0
179 %call2 = call i32 @callee(), !range !0
180 %add = mul i32 %call1, %call2
181 %zext = sext i32 %add to i64
182 ret i64 %zext
183}
184
Craig Toppere23e8a42018-08-27 22:55:49 +0000185define i64 @test5(i32 %V) {
186; CHECK-LABEL: @test5(
187; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[V:%.*]], 1
Sanjay Patel2426eb42018-09-14 20:40:46 +0000188; CHECK-NEXT: [[NARROW:%.*]] = add nsw i32 [[ASHR]], 1073741823
189; CHECK-NEXT: [[ADD:%.*]] = sext i32 [[NARROW]] to i64
Craig Toppere23e8a42018-08-27 22:55:49 +0000190; CHECK-NEXT: ret i64 [[ADD]]
191;
192 %ashr = ashr i32 %V, 1
193 %sext = sext i32 %ashr to i64
194 %add = add i64 %sext, 1073741823
195 ret i64 %add
196}
197
Sanjay Patelfcf8c7c2018-09-14 20:33:40 +0000198; Negative test - extra use means we'd have more instructions than we started with.
199
200define i64 @sext_add_constant_extra_use(i32 %V) {
201; CHECK-LABEL: @sext_add_constant_extra_use(
202; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[V:%.*]], 1
203; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[ASHR]] to i64
204; CHECK-NEXT: call void @use(i64 [[SEXT]])
205; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SEXT]], 1073741823
206; CHECK-NEXT: ret i64 [[ADD]]
207;
208 %ashr = ashr i32 %V, 1
209 %sext = sext i32 %ashr to i64
210 call void @use(i64 %sext)
211 %add = add i64 %sext, 1073741823
212 ret i64 %add
213}
214
Craig Toppere23e8a42018-08-27 22:55:49 +0000215define <2 x i64> @test5_splat(<2 x i32> %V) {
216; CHECK-LABEL: @test5_splat(
217; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 1, i32 1>
Sanjay Patel2426eb42018-09-14 20:40:46 +0000218; CHECK-NEXT: [[NARROW:%.*]] = add nsw <2 x i32> [[ASHR]], <i32 1073741823, i32 1073741823>
219; CHECK-NEXT: [[ADD:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Toppere23e8a42018-08-27 22:55:49 +0000220; CHECK-NEXT: ret <2 x i64> [[ADD]]
221;
222 %ashr = ashr <2 x i32> %V, <i32 1, i32 1>
223 %sext = sext <2 x i32> %ashr to <2 x i64>
224 %add = add <2 x i64> %sext, <i64 1073741823, i64 1073741823>
225 ret <2 x i64> %add
226}
227
228define <2 x i64> @test5_vec(<2 x i32> %V) {
229; CHECK-LABEL: @test5_vec(
230; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 1, i32 1>
Sanjay Patel2426eb42018-09-14 20:40:46 +0000231; CHECK-NEXT: [[NARROW:%.*]] = add nsw <2 x i32> [[ASHR]], <i32 1, i32 2>
232; CHECK-NEXT: [[ADD:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Toppere23e8a42018-08-27 22:55:49 +0000233; CHECK-NEXT: ret <2 x i64> [[ADD]]
234;
235 %ashr = ashr <2 x i32> %V, <i32 1, i32 1>
236 %sext = sext <2 x i32> %ashr to <2 x i64>
237 %add = add <2 x i64> %sext, <i64 1, i64 2>
238 ret <2 x i64> %add
239}
240
241define i64 @test6(i32 %V) {
242; CHECK-LABEL: @test6(
243; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[V:%.*]], 1
Sanjay Patel2426eb42018-09-14 20:40:46 +0000244; CHECK-NEXT: [[NARROW:%.*]] = add nsw i32 [[ASHR]], -1073741824
245; CHECK-NEXT: [[ADD:%.*]] = sext i32 [[NARROW]] to i64
Craig Toppere23e8a42018-08-27 22:55:49 +0000246; CHECK-NEXT: ret i64 [[ADD]]
247;
248 %ashr = ashr i32 %V, 1
249 %sext = sext i32 %ashr to i64
250 %add = add i64 %sext, -1073741824
251 ret i64 %add
252}
253
254define <2 x i64> @test6_splat(<2 x i32> %V) {
255; CHECK-LABEL: @test6_splat(
256; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 1, i32 1>
Sanjay Patel2426eb42018-09-14 20:40:46 +0000257; CHECK-NEXT: [[NARROW:%.*]] = add nsw <2 x i32> [[ASHR]], <i32 -1073741824, i32 -1073741824>
258; CHECK-NEXT: [[ADD:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Toppere23e8a42018-08-27 22:55:49 +0000259; CHECK-NEXT: ret <2 x i64> [[ADD]]
260;
261 %ashr = ashr <2 x i32> %V, <i32 1, i32 1>
262 %sext = sext <2 x i32> %ashr to <2 x i64>
263 %add = add <2 x i64> %sext, <i64 -1073741824, i64 -1073741824>
264 ret <2 x i64> %add
265}
266
267define <2 x i64> @test6_vec(<2 x i32> %V) {
268; CHECK-LABEL: @test6_vec(
269; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 1, i32 1>
Sanjay Patel2426eb42018-09-14 20:40:46 +0000270; CHECK-NEXT: [[NARROW:%.*]] = add nsw <2 x i32> [[ASHR]], <i32 -1, i32 -2>
271; CHECK-NEXT: [[ADD:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Toppere23e8a42018-08-27 22:55:49 +0000272; CHECK-NEXT: ret <2 x i64> [[ADD]]
273;
274 %ashr = ashr <2 x i32> %V, <i32 1, i32 1>
275 %sext = sext <2 x i32> %ashr to <2 x i64>
276 %add = add <2 x i64> %sext, <i64 -1, i64 -2>
277 ret <2 x i64> %add
278}
279
280define <2 x i64> @test6_vec2(<2 x i32> %V) {
281; CHECK-LABEL: @test6_vec2(
282; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 1, i32 1>
Sanjay Patel2426eb42018-09-14 20:40:46 +0000283; CHECK-NEXT: [[NARROW:%.*]] = add nsw <2 x i32> [[ASHR]], <i32 -1, i32 1>
284; CHECK-NEXT: [[ADD:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Toppere23e8a42018-08-27 22:55:49 +0000285; CHECK-NEXT: ret <2 x i64> [[ADD]]
286;
287 %ashr = ashr <2 x i32> %V, <i32 1, i32 1>
288 %sext = sext <2 x i32> %ashr to <2 x i64>
289 %add = add <2 x i64> %sext, <i64 -1, i64 1>
290 ret <2 x i64> %add
291}
292
293define i64 @test7(i32 %V) {
294; CHECK-LABEL: @test7(
295; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[V:%.*]], 1
Sanjay Patel2426eb42018-09-14 20:40:46 +0000296; CHECK-NEXT: [[NARROW:%.*]] = add nuw i32 [[LSHR]], 2147483647
297; CHECK-NEXT: [[ADD:%.*]] = zext i32 [[NARROW]] to i64
Craig Toppere23e8a42018-08-27 22:55:49 +0000298; CHECK-NEXT: ret i64 [[ADD]]
299;
300 %lshr = lshr i32 %V, 1
301 %zext = zext i32 %lshr to i64
302 %add = add i64 %zext, 2147483647
303 ret i64 %add
304}
305
306define <2 x i64> @test7_splat(<2 x i32> %V) {
307; CHECK-LABEL: @test7_splat(
308; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[V:%.*]], <i32 1, i32 1>
Sanjay Patel2426eb42018-09-14 20:40:46 +0000309; CHECK-NEXT: [[NARROW:%.*]] = add nuw <2 x i32> [[LSHR]], <i32 2147483647, i32 2147483647>
310; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i32> [[NARROW]] to <2 x i64>
Craig Toppere23e8a42018-08-27 22:55:49 +0000311; CHECK-NEXT: ret <2 x i64> [[ADD]]
312;
313 %lshr = lshr <2 x i32> %V, <i32 1, i32 1>
314 %zext = zext <2 x i32> %lshr to <2 x i64>
315 %add = add <2 x i64> %zext, <i64 2147483647, i64 2147483647>
316 ret <2 x i64> %add
317}
318
319define <2 x i64> @test7_vec(<2 x i32> %V) {
320; CHECK-LABEL: @test7_vec(
321; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[V:%.*]], <i32 1, i32 1>
Sanjay Patel2426eb42018-09-14 20:40:46 +0000322; CHECK-NEXT: [[NARROW:%.*]] = add nuw <2 x i32> [[LSHR]], <i32 1, i32 2>
323; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i32> [[NARROW]] to <2 x i64>
Craig Toppere23e8a42018-08-27 22:55:49 +0000324; CHECK-NEXT: ret <2 x i64> [[ADD]]
325;
326 %lshr = lshr <2 x i32> %V, <i32 1, i32 1>
327 %zext = zext <2 x i32> %lshr to <2 x i64>
328 %add = add <2 x i64> %zext, <i64 1, i64 2>
329 ret <2 x i64> %add
330}
331
Craig Topper3de8d592018-09-10 23:48:21 +0000332define i64 @test8(i32 %V) {
333; CHECK-LABEL: @test8(
334; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[V:%.*]], 16
Sanjay Patel90a36342018-09-14 22:23:35 +0000335; CHECK-NEXT: [[NARROW:%.*]] = mul nsw i32 [[ASHR]], 32767
336; CHECK-NEXT: [[MUL:%.*]] = sext i32 [[NARROW]] to i64
Craig Topper3de8d592018-09-10 23:48:21 +0000337; CHECK-NEXT: ret i64 [[MUL]]
338;
339 %ashr = ashr i32 %V, 16
340 %sext = sext i32 %ashr to i64
341 %mul = mul i64 %sext, 32767
342 ret i64 %mul
343}
344
345define <2 x i64> @test8_splat(<2 x i32> %V) {
346; CHECK-LABEL: @test8_splat(
347; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 16, i32 16>
Sanjay Patel90a36342018-09-14 22:23:35 +0000348; CHECK-NEXT: [[NARROW:%.*]] = mul nsw <2 x i32> [[ASHR]], <i32 32767, i32 32767>
349; CHECK-NEXT: [[MUL:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Topper3de8d592018-09-10 23:48:21 +0000350; CHECK-NEXT: ret <2 x i64> [[MUL]]
351;
352 %ashr = ashr <2 x i32> %V, <i32 16, i32 16>
353 %sext = sext <2 x i32> %ashr to <2 x i64>
354 %mul = mul <2 x i64> %sext, <i64 32767, i64 32767>
355 ret <2 x i64> %mul
356}
357
358define <2 x i64> @test8_vec(<2 x i32> %V) {
359; CHECK-LABEL: @test8_vec(
360; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 16, i32 16>
Sanjay Patel90a36342018-09-14 22:23:35 +0000361; CHECK-NEXT: [[NARROW:%.*]] = mul nsw <2 x i32> [[ASHR]], <i32 32767, i32 16384>
362; CHECK-NEXT: [[MUL:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Topper3de8d592018-09-10 23:48:21 +0000363; CHECK-NEXT: ret <2 x i64> [[MUL]]
364;
365 %ashr = ashr <2 x i32> %V, <i32 16, i32 16>
366 %sext = sext <2 x i32> %ashr to <2 x i64>
367 %mul = mul <2 x i64> %sext, <i64 32767, i64 16384>
368 ret <2 x i64> %mul
369}
370
371define <2 x i64> @test8_vec2(<2 x i32> %V) {
372; CHECK-LABEL: @test8_vec2(
373; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 16, i32 16>
Sanjay Patel90a36342018-09-14 22:23:35 +0000374; CHECK-NEXT: [[NARROW:%.*]] = mul nsw <2 x i32> [[ASHR]], <i32 32767, i32 -32767>
375; CHECK-NEXT: [[MUL:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Topper3de8d592018-09-10 23:48:21 +0000376; CHECK-NEXT: ret <2 x i64> [[MUL]]
377;
378 %ashr = ashr <2 x i32> %V, <i32 16, i32 16>
379 %sext = sext <2 x i32> %ashr to <2 x i64>
380 %mul = mul <2 x i64> %sext, <i64 32767, i64 -32767>
381 ret <2 x i64> %mul
382}
383
384define i64 @test9(i32 %V) {
385; CHECK-LABEL: @test9(
386; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[V:%.*]], 16
Sanjay Patel90a36342018-09-14 22:23:35 +0000387; CHECK-NEXT: [[NARROW:%.*]] = mul nsw i32 [[ASHR]], -32767
388; CHECK-NEXT: [[MUL:%.*]] = sext i32 [[NARROW]] to i64
Craig Topper3de8d592018-09-10 23:48:21 +0000389; CHECK-NEXT: ret i64 [[MUL]]
390;
391 %ashr = ashr i32 %V, 16
392 %sext = sext i32 %ashr to i64
393 %mul = mul i64 %sext, -32767
394 ret i64 %mul
395}
396
397define <2 x i64> @test9_splat(<2 x i32> %V) {
398; CHECK-LABEL: @test9_splat(
399; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 16, i32 16>
Sanjay Patel90a36342018-09-14 22:23:35 +0000400; CHECK-NEXT: [[NARROW:%.*]] = mul nsw <2 x i32> [[ASHR]], <i32 -32767, i32 -32767>
401; CHECK-NEXT: [[MUL:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Topper3de8d592018-09-10 23:48:21 +0000402; CHECK-NEXT: ret <2 x i64> [[MUL]]
403;
404 %ashr = ashr <2 x i32> %V, <i32 16, i32 16>
405 %sext = sext <2 x i32> %ashr to <2 x i64>
406 %mul = mul <2 x i64> %sext, <i64 -32767, i64 -32767>
407 ret <2 x i64> %mul
408}
409
410define <2 x i64> @test9_vec(<2 x i32> %V) {
411; CHECK-LABEL: @test9_vec(
412; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 16, i32 16>
Sanjay Patel90a36342018-09-14 22:23:35 +0000413; CHECK-NEXT: [[NARROW:%.*]] = mul nsw <2 x i32> [[ASHR]], <i32 -32767, i32 -10>
414; CHECK-NEXT: [[MUL:%.*]] = sext <2 x i32> [[NARROW]] to <2 x i64>
Craig Topper3de8d592018-09-10 23:48:21 +0000415; CHECK-NEXT: ret <2 x i64> [[MUL]]
416;
417 %ashr = ashr <2 x i32> %V, <i32 16, i32 16>
418 %sext = sext <2 x i32> %ashr to <2 x i64>
419 %mul = mul <2 x i64> %sext, <i64 -32767, i64 -10>
420 ret <2 x i64> %mul
421}
422
423define i64 @test10(i32 %V) {
424; CHECK-LABEL: @test10(
425; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[V:%.*]], 16
Sanjay Patel90a36342018-09-14 22:23:35 +0000426; CHECK-NEXT: [[NARROW:%.*]] = mul nuw i32 [[LSHR]], 65535
427; CHECK-NEXT: [[MUL:%.*]] = zext i32 [[NARROW]] to i64
Craig Topper3de8d592018-09-10 23:48:21 +0000428; CHECK-NEXT: ret i64 [[MUL]]
429;
430 %lshr = lshr i32 %V, 16
431 %zext = zext i32 %lshr to i64
432 %mul = mul i64 %zext, 65535
433 ret i64 %mul
434}
435
436define <2 x i64> @test10_splat(<2 x i32> %V) {
437; CHECK-LABEL: @test10_splat(
438; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[V:%.*]], <i32 16, i32 16>
Sanjay Patel90a36342018-09-14 22:23:35 +0000439; CHECK-NEXT: [[NARROW:%.*]] = mul nuw <2 x i32> [[LSHR]], <i32 65535, i32 65535>
440; CHECK-NEXT: [[MUL:%.*]] = zext <2 x i32> [[NARROW]] to <2 x i64>
Craig Topper3de8d592018-09-10 23:48:21 +0000441; CHECK-NEXT: ret <2 x i64> [[MUL]]
442;
443 %lshr = lshr <2 x i32> %V, <i32 16, i32 16>
444 %zext = zext <2 x i32> %lshr to <2 x i64>
445 %mul = mul <2 x i64> %zext, <i64 65535, i64 65535>
446 ret <2 x i64> %mul
447}
448
449define <2 x i64> @test10_vec(<2 x i32> %V) {
450; CHECK-LABEL: @test10_vec(
451; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[V:%.*]], <i32 16, i32 16>
Sanjay Patel90a36342018-09-14 22:23:35 +0000452; CHECK-NEXT: [[NARROW:%.*]] = mul nuw <2 x i32> [[LSHR]], <i32 65535, i32 2>
453; CHECK-NEXT: [[MUL:%.*]] = zext <2 x i32> [[NARROW]] to <2 x i64>
Craig Topper3de8d592018-09-10 23:48:21 +0000454; CHECK-NEXT: ret <2 x i64> [[MUL]]
455;
456 %lshr = lshr <2 x i32> %V, <i32 16, i32 16>
457 %zext = zext <2 x i32> %lshr to <2 x i64>
458 %mul = mul <2 x i64> %zext, <i64 65535, i64 2>
459 ret <2 x i64> %mul
460}
461
Craig Toppere3853652018-09-14 05:16:58 +0000462define i64 @test11(i32 %V) {
463; CHECK-LABEL: @test11(
464; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !1
465; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !1
Sanjay Patel2426eb42018-09-14 20:40:46 +0000466; CHECK-NEXT: [[NARROW:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
467; CHECK-NEXT: [[ADD:%.*]] = sext i32 [[NARROW]] to i64
Craig Toppere3853652018-09-14 05:16:58 +0000468; CHECK-NEXT: ret i64 [[ADD]]
469;
470 %call1 = call i32 @callee(), !range !1
471 %call2 = call i32 @callee(), !range !1
472 %sext1 = sext i32 %call1 to i64
473 %sext2 = sext i32 %call2 to i64
474 %add = add i64 %sext1, %sext2
475 ret i64 %add
476}
477
478define i64 @test12(i32 %V) {
479; CHECK-LABEL: @test12(
480; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !1
481; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !1
Sanjay Patel90a36342018-09-14 22:23:35 +0000482; CHECK-NEXT: [[NARROW:%.*]] = mul nsw i32 [[CALL1]], [[CALL2]]
483; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[NARROW]] to i64
Craig Toppere3853652018-09-14 05:16:58 +0000484; CHECK-NEXT: ret i64 [[TMP1]]
485;
486 %call1 = call i32 @callee(), !range !1
487 %call2 = call i32 @callee(), !range !1
488 %sext1 = sext i32 %call1 to i64
489 %sext2 = sext i32 %call2 to i64
490 %add = mul i64 %sext1, %sext2
491 ret i64 %add
492}
493
Craig Topper2da73812018-09-15 18:54:10 +0000494define i64 @test13(i32 %V) {
495; CHECK-LABEL: @test13(
496; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !2
497; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !3
498; CHECK-NEXT: [[SUBCONV:%.*]] = sub nsw i32 [[CALL1]], [[CALL2]]
499; CHECK-NEXT: [[SUB:%.*]] = sext i32 [[SUBCONV]] to i64
500; CHECK-NEXT: ret i64 [[SUB]]
501;
502 %call1 = call i32 @callee(), !range !2
503 %call2 = call i32 @callee(), !range !3
504 %sext1 = sext i32 %call1 to i64
505 %sext2 = sext i32 %call2 to i64
506 %sub = sub i64 %sext1, %sext2
507 ret i64 %sub
508}
509
510define i64 @test14(i32 %V) {
511; CHECK-LABEL: @test14(
512; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !2
513; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !0
514; CHECK-NEXT: [[SUBCONV:%.*]] = sub nuw nsw i32 [[CALL1]], [[CALL2]]
515; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[SUBCONV]] to i64
516; CHECK-NEXT: ret i64 [[SUB]]
517;
518 %call1 = call i32 @callee(), !range !2
519 %call2 = call i32 @callee(), !range !0
520 %zext1 = zext i32 %call1 to i64
521 %zext2 = zext i32 %call2 to i64
522 %sub = sub i64 %zext1, %zext2
523 ret i64 %sub
524}
525
526define i64 @test15(i32 %V) {
527; CHECK-LABEL: @test15(
528; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[V:%.*]], 1
529; CHECK-NEXT: [[SUBCONV:%.*]] = sub nsw i32 8, [[ASHR]]
530; CHECK-NEXT: [[SUB:%.*]] = sext i32 [[SUBCONV]] to i64
531; CHECK-NEXT: ret i64 [[SUB]]
532;
533 %ashr = ashr i32 %V, 1
534 %sext = sext i32 %ashr to i64
535 %sub = sub i64 8, %sext
536 ret i64 %sub
537}
538
539define <2 x i64> @test15vec(<2 x i32> %V) {
540; CHECK-LABEL: @test15vec(
541; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i32> [[V:%.*]], <i32 1, i32 1>
542; CHECK-NEXT: [[SUBCONV:%.*]] = sub nsw <2 x i32> <i32 8, i32 8>, [[ASHR]]
543; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i32> [[SUBCONV]] to <2 x i64>
544; CHECK-NEXT: ret <2 x i64> [[SUB]]
545;
546 %ashr = ashr <2 x i32> %V, <i32 1, i32 1>
547 %sext = sext <2 x i32> %ashr to <2 x i64>
548 %sub = sub <2 x i64> <i64 8, i64 8>, %sext
549 ret <2 x i64> %sub
550}
551
552define i64 @test16(i32 %V) {
553; CHECK-LABEL: @test16(
554; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[V:%.*]], 1
555; CHECK-NEXT: [[SUBCONV:%.*]] = sub nuw i32 -2, [[LSHR]]
556; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[SUBCONV]] to i64
557; CHECK-NEXT: ret i64 [[SUB]]
558;
559 %lshr = lshr i32 %V, 1
560 %zext = zext i32 %lshr to i64
561 %sub = sub i64 4294967294, %zext
562 ret i64 %sub
563}
564
565define <2 x i64> @test16vec(<2 x i32> %V) {
566; CHECK-LABEL: @test16vec(
567; CHECK-NEXT: [[LSHR:%.*]] = lshr <2 x i32> [[V:%.*]], <i32 1, i32 1>
568; CHECK-NEXT: [[SUBCONV:%.*]] = sub nuw <2 x i32> <i32 -2, i32 -2>, [[LSHR]]
569; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i32> [[SUBCONV]] to <2 x i64>
570; CHECK-NEXT: ret <2 x i64> [[SUB]]
571;
572 %lshr = lshr <2 x i32> %V, <i32 1, i32 1>
573 %zext = zext <2 x i32> %lshr to <2 x i64>
574 %sub = sub <2 x i64> <i64 4294967294, i64 4294967294>, %zext
575 ret <2 x i64> %sub
576}
577
578; Negative test. Both have the same range so we can't guarantee the subtract
579; won't wrap.
580define i64 @test17(i32 %V) {
581; CHECK-LABEL: @test17(
582; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !0
583; CHECK-NEXT: [[CALL2:%.*]] = call i32 @callee(), !range !0
584; CHECK-NEXT: [[SEXT1:%.*]] = zext i32 [[CALL1]] to i64
585; CHECK-NEXT: [[SEXT2:%.*]] = zext i32 [[CALL2]] to i64
586; CHECK-NEXT: [[SUB:%.*]] = sub nsw i64 [[SEXT1]], [[SEXT2]]
587; CHECK-NEXT: ret i64 [[SUB]]
588;
589 %call1 = call i32 @callee(), !range !0
590 %call2 = call i32 @callee(), !range !0
591 %sext1 = zext i32 %call1 to i64
592 %sext2 = zext i32 %call2 to i64
593 %sub = sub i64 %sext1, %sext2
594 ret i64 %sub
595}
596
597; Negative test. LHS is large positive 32-bit number. Range of callee can
598; cause overflow.
599define i64 @test18(i32 %V) {
600; CHECK-LABEL: @test18(
601; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !1
602; CHECK-NEXT: [[SEXT1:%.*]] = sext i32 [[CALL1]] to i64
603; CHECK-NEXT: [[SUB:%.*]] = sub nsw i64 2147481648, [[SEXT1]]
604; CHECK-NEXT: ret i64 [[SUB]]
605;
606 %call1 = call i32 @callee(), !range !1
607 %sext1 = sext i32 %call1 to i64
608 %sub = sub i64 2147481648, %sext1
609 ret i64 %sub
610}
611
612; Negative test. LHS is large negative 32-bit number. Range of callee can
613; cause overflow.
614define i64 @test19(i32 %V) {
615; CHECK-LABEL: @test19(
616; CHECK-NEXT: [[CALL1:%.*]] = call i32 @callee(), !range !0
617; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[CALL1]] to i64
618; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i64 -2147481648, [[TMP1]]
619; CHECK-NEXT: ret i64 [[SUB]]
620;
621 %call1 = call i32 @callee(), !range !0
622 %sext1 = sext i32 %call1 to i64
623 %sub = sub i64 -2147481648, %sext1
624 ret i64 %sub
625}
626
David Majnemerb5e365c2017-01-04 02:21:37 +0000627!0 = !{ i32 0, i32 2000 }
Craig Toppere3853652018-09-14 05:16:58 +0000628!1 = !{ i32 -2000, i32 0 }
Craig Topper2da73812018-09-15 18:54:10 +0000629!2 = !{ i32 -512, i32 -255 }
630!3 = !{ i32 -128, i32 0 }