• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; This test makes sure that rem instructions are properly eliminated.
2;
3; RUN: opt < %s -instcombine -S | FileCheck %s
4; END.
5
6define i32 @test1(i32 %A) {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT: ret i32 0
9	%B = srem i32 %A, 1	; ISA constant 0
10	ret i32 %B
11}
12
13define i32 @test2(i32 %A) {	; 0 % X = 0, we don't need to preserve traps
14; CHECK-LABEL: @test2(
15; CHECK-NEXT: ret i32 0
16	%B = srem i32 0, %A
17	ret i32 %B
18}
19
20define i32 @test3(i32 %A) {
21; CHECK-LABEL: @test3(
22; CHECK-NEXT: [[AND:%.*]] = and i32 %A, 7
23; CHECK-NEXT: ret i32 [[AND]]
24	%B = urem i32 %A, 8
25	ret i32 %B
26}
27
28define <2 x i32> @vec_power_of_2_constant_splat_divisor(<2 x i32> %A) {
29; CHECK-LABEL: @vec_power_of_2_constant_splat_divisor(
30; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> %A, <i32 7, i32 7>
31; CHECK-NEXT:    ret <2 x i32> [[B]]
32;
33  %B = urem <2 x i32> %A, <i32 8, i32 8>
34  ret <2 x i32> %B
35}
36
37define <2 x i19> @weird_vec_power_of_2_constant_splat_divisor(<2 x i19> %A) {
38; CHECK-LABEL: @weird_vec_power_of_2_constant_splat_divisor(
39; CHECK-NEXT:    [[B:%.*]] = and <2 x i19> %A, <i19 7, i19 7>
40; CHECK-NEXT:    ret <2 x i19> [[B]]
41;
42  %B = urem <2 x i19> %A, <i19 8, i19 8>
43  ret <2 x i19> %B
44}
45
46define i1 @test3a(i32 %A) {
47; CHECK-LABEL: @test3a(
48; CHECK-NEXT: [[AND:%.*]] = and i32 %A, 7
49; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
50; CHECK-NEXT: ret i1 [[CMP]]
51	%B = srem i32 %A, -8
52	%C = icmp ne i32 %B, 0
53	ret i1 %C
54}
55
56define i32 @test4(i32 %X, i1 %C) {
57; CHECK-LABEL: @test4(
58; CHECK-NEXT: [[SEL:%.*]] = select i1 %C, i32 0, i32 7
59; CHECK-NEXT: [[AND:%.*]] = and i32 [[SEL]], %X
60	%V = select i1 %C, i32 1, i32 8
61	%R = urem i32 %X, %V
62	ret i32 %R
63}
64
65define i32 @test5(i32 %X, i8 %B) {
66; CHECK-LABEL: @test5(
67; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 %B to i32
68; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 32, [[ZEXT]]
69; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], -1
70; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], %X
71; CHECK-NEXT: ret i32 [[AND]]
72	%shift.upgrd.1 = zext i8 %B to i32
73	%Amt = shl i32 32, %shift.upgrd.1
74	%V = urem i32 %X, %Amt
75	ret i32 %V
76}
77
78define i32 @test6(i32 %A) {
79; CHECK-LABEL: @test6(
80; CHECK-NEXT: ret i32 undef
81	%B = srem i32 %A, 0	;; undef
82	ret i32 %B
83}
84
85define i32 @test7(i32 %A) {
86; CHECK-LABEL: @test7(
87; CHECK-NEXT: ret i32 0
88	%B = mul i32 %A, 8
89	%C = srem i32 %B, 4
90	ret i32 %C
91}
92
93define i32 @test8(i32 %A) {
94; CHECK-LABEL: @test8(
95; CHECK-NEXT: ret i32 0
96	%B = shl i32 %A, 4
97	%C = srem i32 %B, 8
98	ret i32 %C
99}
100
101define i32 @test9(i32 %A) {
102; CHECK-LABEL: @test9(
103; CHECK-NEXT: ret i32 0
104	%B = mul i32 %A, 64
105	%C = urem i32 %B, 32
106	ret i32 %C
107}
108
109define i32 @test10(i8 %c) {
110; CHECK-LABEL: @test10(
111; CHECK-NEXT: ret i32 0
112	%tmp.1 = zext i8 %c to i32
113	%tmp.2 = mul i32 %tmp.1, 4
114	%tmp.3 = sext i32 %tmp.2 to i64
115	%tmp.5 = urem i64 %tmp.3, 4
116	%tmp.6 = trunc i64 %tmp.5 to i32
117	ret i32 %tmp.6
118}
119
120define i32 @test11(i32 %i) {
121; CHECK-LABEL: @test11(
122; CHECK-NEXT: ret i32 0
123	%tmp.1 = and i32 %i, -2
124	%tmp.3 = mul i32 %tmp.1, 2
125	%tmp.5 = urem i32 %tmp.3, 4
126	ret i32 %tmp.5
127}
128
129define i32 @test12(i32 %i) {
130; CHECK-LABEL: @test12(
131; CHECK-NEXT: ret i32 0
132	%tmp.1 = and i32 %i, -4
133	%tmp.5 = srem i32 %tmp.1, 2
134	ret i32 %tmp.5
135}
136
137define i32 @test13(i32 %i) {
138; CHECK-LABEL: @test13(
139; CHECK-NEXT: ret i32 0
140	%x = srem i32 %i, %i
141	ret i32 %x
142}
143
144define i64 @test14(i64 %x, i32 %y) {
145; CHECK-LABEL: @test14(
146; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, %y
147; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL]] to i64
148; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[ZEXT]], -1
149; CHECK-NEXT: [[AND:%.*]] = and i64 [[ADD]], %x
150; CHECK-NEXT: ret i64 [[AND]]
151	%shl = shl i32 1, %y
152	%zext = zext i32 %shl to i64
153	%urem = urem i64 %x, %zext
154	ret i64 %urem
155}
156
157define i64 @test15(i32 %x, i32 %y) {
158; CHECK-LABEL: @test15(
159; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, %y
160; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], -1
161; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], %x
162; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[AND]] to i64
163; CHECK-NEXT: ret i64 [[ZEXT]]
164	%shl = shl i32 1, %y
165	%zext0 = zext i32 %shl to i64
166	%zext1 = zext i32 %x to i64
167	%urem = urem i64 %zext1, %zext0
168	ret i64 %urem
169}
170
171define i32 @test16(i32 %x, i32 %y) {
172; CHECK-LABEL: @test16(
173; CHECK-NEXT: [[SHR:%.*]] = lshr i32 %y, 11
174; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 4
175; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], 3
176; CHECK-NEXT: [[REM:%.*]] = and i32 [[OR]], %x
177; CHECK-NEXT: ret i32 [[REM]]
178	%shr = lshr i32 %y, 11
179	%and = and i32 %shr, 4
180	%add = add i32 %and, 4
181	%rem = urem i32 %x, %add
182	ret i32 %rem
183}
184
185define i32 @test17(i32 %X) {
186; CHECK-LABEL: @test17(
187; CHECK-NEXT: icmp ne i32 %X, 1
188; CHECK-NEXT: zext i1
189; CHECK-NEXT: ret
190  %A = urem i32 1, %X
191  ret i32 %A
192}
193
194define i32 @test18(i16 %x, i32 %y) {
195; CHECK: @test18
196; CHECK-NEXT: [[AND:%.*]] = and i16 %x, 4
197; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[AND]] to i32
198; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i32 [[EXT]], 3
199; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[SHL]], 63
200; CHECK-NEXT: [[REM:%.*]] = and i32 [[XOR]], %y
201; CHECK-NEXT: ret i32 [[REM]]
202	%1 = and i16 %x, 4
203	%2 = icmp ne i16 %1, 0
204	%3 = select i1 %2, i32 32, i32 64
205	%4 = urem i32 %y, %3
206	ret i32 %4
207}
208
209define i32 @test19(i32 %x, i32 %y) {
210; CHECK: @test19
211; CHECK-NEXT: [[SHL1:%.*]] = shl i32 1, %x
212; CHECK-NEXT: [[SHL2:%.*]] = shl i32 1, %y
213; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL1]], [[SHL2]]
214; CHECK-NEXT: [[ADD:%.*]] = add i32 [[AND]], [[SHL1]]
215; CHECK-NEXT: [[SUB:%.*]] = add i32 [[ADD]], -1
216; CHECK-NEXT: [[REM:%.*]] = and i32 [[SUB]], %y
217; CHECK-NEXT: ret i32 [[REM]]
218	%A = shl i32 1, %x
219	%B = shl i32 1, %y
220	%C = and i32 %A, %B
221	%D = add i32 %C, %A
222	%E = urem i32 %y, %D
223	ret i32 %E
224}
225
226define <2 x i64> @test20(<2 x i64> %X, <2 x i1> %C) {
227; CHECK-LABEL: @test20(
228; CHECK-NEXT: select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer
229; CHECK-NEXT: ret <2 x i64>
230	%V = select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8, i64 9>
231	%R = urem <2 x i64> %V, <i64 2, i64 3>
232	ret <2 x i64> %R
233}
234
235define i32 @test21(i1 %c0, i32* %val) {
236; CHECK-LABEL: @test21(
237entry:
238  br i1 %c0, label %if.then, label %if.end
239
240if.then:
241; CHECK: if.then:
242; CHECK-NEXT:  %v = load volatile i32, i32* %val, align 4
243; CHECK-NEXT:  %phitmp = srem i32 %v, 5
244
245  %v = load volatile i32, i32* %val
246  br label %if.end
247
248if.end:
249; CHECK: if.end:
250; CHECK-NEXT:  %lhs = phi i32 [ %phitmp, %if.then ], [ 0, %entry ]
251; CHECK-NEXT:  ret i32 %lhs
252
253  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
254  %rem = srem i32 %lhs, 5
255  ret i32 %rem
256}
257
258@a = common global [5 x i16] zeroinitializer, align 2
259@b = common global i16 0, align 2
260
261define i32 @pr27968_0(i1 %c0, i32* %val) {
262; CHECK-LABEL: @pr27968_0(
263entry:
264  br i1 %c0, label %if.then, label %if.end
265
266if.then:
267  %v = load volatile i32, i32* %val
268  br label %if.end
269
270; CHECK: if.then:
271; CHECK-NOT: srem
272; CHECK:  br label %if.end
273
274if.end:
275  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
276  br i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b), label %rem.is.safe, label %rem.is.unsafe
277
278rem.is.safe:
279; CHECK: rem.is.safe:
280; CHECK-NEXT:  %rem = srem i32 %lhs, zext (i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b) to i32)
281; CHECK-NEXT:  ret i32 %rem
282
283  %rem = srem i32 %lhs, zext (i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b) to i32)
284  ret i32 %rem
285
286rem.is.unsafe:
287  ret i32 0
288}
289
290define i32 @pr27968_1(i1 %c0, i1 %always_false, i32* %val) {
291; CHECK-LABEL: @pr27968_1(
292entry:
293  br i1 %c0, label %if.then, label %if.end
294
295if.then:
296  %v = load volatile i32, i32* %val
297  br label %if.end
298
299; CHECK: if.then:
300; CHECK-NOT: srem
301; CHECK:  br label %if.end
302
303if.end:
304  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
305  br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe
306
307rem.is.safe:
308  %rem = srem i32 %lhs, -2147483648
309  ret i32 %rem
310
311; CHECK: rem.is.safe:
312; CHECK-NEXT:  %rem = srem i32 %lhs, -2147483648
313; CHECK-NEXT:  ret i32 %rem
314
315rem.is.unsafe:
316  ret i32 0
317}
318
319define i32 @pr27968_2(i1 %c0, i32* %val) {
320; CHECK-LABEL: @pr27968_2(
321entry:
322  br i1 %c0, label %if.then, label %if.end
323
324if.then:
325  %v = load volatile i32, i32* %val
326  br label %if.end
327
328; CHECK: if.then:
329; CHECK-NOT: urem
330; CHECK:  br label %if.end
331
332if.end:
333  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
334  br i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b), label %rem.is.safe, label %rem.is.unsafe
335
336rem.is.safe:
337; CHECK: rem.is.safe:
338; CHECK-NEXT:  %rem = urem i32 %lhs, zext (i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b) to i32)
339; CHECK-NEXT:  ret i32 %rem
340
341  %rem = urem i32 %lhs, zext (i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b) to i32)
342  ret i32 %rem
343
344rem.is.unsafe:
345  ret i32 0
346}
347
348define i32 @pr27968_3(i1 %c0, i1 %always_false, i32* %val) {
349; CHECK-LABEL: @pr27968_3(
350entry:
351  br i1 %c0, label %if.then, label %if.end
352
353if.then:
354  %v = load volatile i32, i32* %val
355  br label %if.end
356
357; CHECK: if.then:
358; CHECK-NEXT:  %v = load volatile i32, i32* %val, align 4
359; CHECK-NEXT:  %phitmp = and i32 %v, 2147483647
360; CHECK-NEXT:  br label %if.end
361
362if.end:
363  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
364  br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe
365
366rem.is.safe:
367  %rem = urem i32 %lhs, -2147483648
368  ret i32 %rem
369
370rem.is.unsafe:
371  ret i32 0
372}
373