• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4define i64 @rem_signed(i64 %x1, i64 %y2) {
5; CHECK-LABEL: @rem_signed(
6; CHECK-NEXT:    [[TMP1:%.*]] = srem i64 [[X1:%.*]], [[Y2:%.*]]
7; CHECK-NEXT:    ret i64 [[TMP1]]
8;
9  %r = sdiv i64 %x1, %y2
10  %r7 = mul i64 %r, %y2
11  %r8 = sub i64 %x1, %r7
12  ret i64 %r8
13}
14
15define <4 x i32> @rem_signed_vec(<4 x i32> %t, <4 x i32> %u) {
16; CHECK-LABEL: @rem_signed_vec(
17; CHECK-NEXT:    [[TMP1:%.*]] = srem <4 x i32> [[T:%.*]], [[U:%.*]]
18; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
19;
20  %k = sdiv <4 x i32> %t, %u
21  %l = mul <4 x i32> %k, %u
22  %m = sub <4 x i32> %t, %l
23  ret <4 x i32> %m
24}
25
26define i64 @rem_unsigned(i64 %x1, i64 %y2) {
27; CHECK-LABEL: @rem_unsigned(
28; CHECK-NEXT:    [[TMP1:%.*]] = urem i64 [[X1:%.*]], [[Y2:%.*]]
29; CHECK-NEXT:    ret i64 [[TMP1]]
30;
31  %r = udiv i64 %x1, %y2
32  %r7 = mul i64 %r, %y2
33  %r8 = sub i64 %x1, %r7
34  ret i64 %r8
35}
36
37; PR28672 - https://llvm.org/bugs/show_bug.cgi?id=28672
38
39define i8 @big_divisor(i8 %x) {
40; CHECK-LABEL: @big_divisor(
41; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i8 [[X:%.*]], -127
42; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[X]], 127
43; CHECK-NEXT:    [[REM:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[TMP2]]
44; CHECK-NEXT:    ret i8 [[REM]]
45;
46  %rem = urem i8 %x, 129
47  ret i8 %rem
48}
49
50define i5 @biggest_divisor(i5 %x) {
51; CHECK-LABEL: @biggest_divisor(
52; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i5 [[X:%.*]], -1
53; CHECK-NEXT:    [[REM:%.*]] = select i1 [[DOTNOT]], i5 0, i5 [[X]]
54; CHECK-NEXT:    ret i5 [[REM]]
55;
56  %rem = urem i5 %x, -1
57  ret i5 %rem
58}
59
60define i8 @urem_with_sext_bool_divisor(i1 %x, i8 %y) {
61; CHECK-LABEL: @urem_with_sext_bool_divisor(
62; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], -1
63; CHECK-NEXT:    [[REM:%.*]] = select i1 [[TMP1]], i8 0, i8 [[Y]]
64; CHECK-NEXT:    ret i8 [[REM]]
65;
66  %s = sext i1 %x to i8
67  %rem = urem i8 %y, %s
68  ret i8 %rem
69}
70
71define <2 x i8> @urem_with_sext_bool_divisor_vec(<2 x i1> %x, <2 x i8> %y) {
72; CHECK-LABEL: @urem_with_sext_bool_divisor_vec(
73; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[Y:%.*]], <i8 -1, i8 -1>
74; CHECK-NEXT:    [[REM:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> zeroinitializer, <2 x i8> [[Y]]
75; CHECK-NEXT:    ret <2 x i8> [[REM]]
76;
77  %s = sext <2 x i1> %x to <2 x i8>
78  %rem = urem <2 x i8> %y, %s
79  ret <2 x i8> %rem
80}
81
82define <2 x i4> @big_divisor_vec(<2 x i4> %x) {
83; CHECK-LABEL: @big_divisor_vec(
84; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult <2 x i4> [[X:%.*]], <i4 -3, i4 -3>
85; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i4> [[X]], <i4 3, i4 3>
86; CHECK-NEXT:    [[REM:%.*]] = select <2 x i1> [[TMP1]], <2 x i4> [[X]], <2 x i4> [[TMP2]]
87; CHECK-NEXT:    ret <2 x i4> [[REM]]
88;
89  %rem = urem <2 x i4> %x, <i4 13, i4 13>
90  ret <2 x i4> %rem
91}
92
93define i8 @urem1(i8 %x, i8 %y) {
94; CHECK-LABEL: @urem1(
95; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]]
96; CHECK-NEXT:    ret i8 [[TMP1]]
97;
98  %A = udiv i8 %x, %y
99  %B = mul i8 %A, %y
100  %C = sub i8 %x, %B
101  ret i8 %C
102}
103
104define i8 @srem1(i8 %x, i8 %y) {
105; CHECK-LABEL: @srem1(
106; CHECK-NEXT:    [[TMP1:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]]
107; CHECK-NEXT:    ret i8 [[TMP1]]
108;
109  %A = sdiv i8 %x, %y
110  %B = mul i8 %A, %y
111  %C = sub i8 %x, %B
112  ret i8 %C
113}
114
115define i8 @urem2(i8 %x, i8 %y) {
116; CHECK-LABEL: @urem2(
117; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]]
118; CHECK-NEXT:    [[C:%.*]] = sub i8 0, [[TMP1]]
119; CHECK-NEXT:    ret i8 [[C]]
120;
121  %A = udiv i8 %x, %y
122  %B = mul i8 %A, %y
123  %C = sub i8 %B, %x
124  ret i8 %C
125}
126
127define i8 @urem3(i8 %x) {
128; CHECK-LABEL: @urem3(
129; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 [[X:%.*]], 3
130; CHECK-NEXT:    [[B_NEG:%.*]] = sub i8 [[X]], [[TMP1]]
131; CHECK-NEXT:    [[C:%.*]] = add i8 [[B_NEG]], [[X]]
132; CHECK-NEXT:    ret i8 [[C]]
133;
134  %A = udiv i8 %x, 3
135  %B = mul i8 %A, -3
136  %C = sub i8 %x, %B
137  ret i8 %C
138}
139
140; (((X / Y) * Y) / Y) -> X / Y
141
142define i32 @sdiv_mul_sdiv(i32 %x, i32 %y) {
143; CHECK-LABEL: @sdiv_mul_sdiv(
144; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]]
145; CHECK-NEXT:    ret i32 [[R]]
146;
147  %div = sdiv i32 %x, %y
148  %mul = mul i32 %div, %y
149  %r = sdiv i32 %mul, %y
150  ret i32 %r
151}
152
153; (((X / Y) * Y) / Y) -> X / Y
154
155define i32 @udiv_mul_udiv(i32 %x, i32 %y) {
156; CHECK-LABEL: @udiv_mul_udiv(
157; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]]
158; CHECK-NEXT:    ret i32 [[R]]
159;
160  %div = udiv i32 %x, %y
161  %mul = mul i32 %div, %y
162  %r = udiv i32 %mul, %y
163  ret i32 %r
164}
165
166define i32 @test1(i32 %A) {
167; CHECK-LABEL: @test1(
168; CHECK-NEXT:    ret i32 0
169;
170  %B = srem i32 %A, 1	; ISA constant 0
171  ret i32 %B
172}
173
174define i32 @test3(i32 %A) {
175; CHECK-LABEL: @test3(
176; CHECK-NEXT:    [[B:%.*]] = and i32 [[A:%.*]], 7
177; CHECK-NEXT:    ret i32 [[B]]
178;
179  %B = urem i32 %A, 8
180  ret i32 %B
181}
182
183define <2 x i32> @vec_power_of_2_constant_splat_divisor(<2 x i32> %A) {
184; CHECK-LABEL: @vec_power_of_2_constant_splat_divisor(
185; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[A:%.*]], <i32 7, i32 7>
186; CHECK-NEXT:    ret <2 x i32> [[B]]
187;
188  %B = urem <2 x i32> %A, <i32 8, i32 8>
189  ret <2 x i32> %B
190}
191
192define <2 x i19> @weird_vec_power_of_2_constant_splat_divisor(<2 x i19> %A) {
193; CHECK-LABEL: @weird_vec_power_of_2_constant_splat_divisor(
194; CHECK-NEXT:    [[B:%.*]] = and <2 x i19> [[A:%.*]], <i19 7, i19 7>
195; CHECK-NEXT:    ret <2 x i19> [[B]]
196;
197  %B = urem <2 x i19> %A, <i19 8, i19 8>
198  ret <2 x i19> %B
199}
200
201define i1 @test3a(i32 %A) {
202; CHECK-LABEL: @test3a(
203; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 7
204; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
205; CHECK-NEXT:    ret i1 [[C]]
206;
207  %B = srem i32 %A, -8
208  %C = icmp ne i32 %B, 0
209  ret i1 %C
210}
211
212define <2 x i1> @test3a_vec(<2 x i32> %A) {
213; CHECK-LABEL: @test3a_vec(
214; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], <i32 7, i32 7>
215; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
216; CHECK-NEXT:    ret <2 x i1> [[C]]
217;
218  %B = srem <2 x i32> %A, <i32 -8, i32 -8>
219  %C = icmp ne <2 x i32> %B, zeroinitializer
220  ret <2 x i1> %C
221}
222
223define i32 @test4(i32 %X, i1 %C) {
224; CHECK-LABEL: @test4(
225; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i32 0, i32 7
226; CHECK-NEXT:    [[R:%.*]] = and i32 [[TMP1]], [[X:%.*]]
227; CHECK-NEXT:    ret i32 [[R]]
228;
229  %V = select i1 %C, i32 1, i32 8
230  %R = urem i32 %X, %V
231  ret i32 %R
232}
233
234define i32 @test5(i32 %X, i8 %B) {
235; CHECK-LABEL: @test5(
236; CHECK-NEXT:    [[SHIFT_UPGRD_1:%.*]] = zext i8 [[B:%.*]] to i32
237; CHECK-NEXT:    [[AMT:%.*]] = shl nuw i32 32, [[SHIFT_UPGRD_1]]
238; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[AMT]], -1
239; CHECK-NEXT:    [[V:%.*]] = and i32 [[TMP1]], [[X:%.*]]
240; CHECK-NEXT:    ret i32 [[V]]
241;
242  %shift.upgrd.1 = zext i8 %B to i32
243  %Amt = shl i32 32, %shift.upgrd.1
244  %V = urem i32 %X, %Amt
245  ret i32 %V
246}
247
248define i32 @test6(i32 %A) {
249; CHECK-LABEL: @test6(
250; CHECK-NEXT:    ret i32 undef
251;
252  %B = srem i32 %A, 0	;; undef
253  ret i32 %B
254}
255
256define i32 @test7(i32 %A) {
257; CHECK-LABEL: @test7(
258; CHECK-NEXT:    ret i32 0
259;
260  %B = mul i32 %A, 8
261  %C = srem i32 %B, 4
262  ret i32 %C
263}
264
265define i32 @test8(i32 %A) {
266; CHECK-LABEL: @test8(
267; CHECK-NEXT:    ret i32 0
268;
269  %B = shl i32 %A, 4
270  %C = srem i32 %B, 8
271  ret i32 %C
272}
273
274define i32 @test9(i32 %A) {
275; CHECK-LABEL: @test9(
276; CHECK-NEXT:    ret i32 0
277;
278  %B = mul i32 %A, 64
279  %C = urem i32 %B, 32
280  ret i32 %C
281}
282
283define i32 @test10(i8 %c) {
284; CHECK-LABEL: @test10(
285; CHECK-NEXT:    ret i32 0
286;
287  %tmp.1 = zext i8 %c to i32
288  %tmp.2 = mul i32 %tmp.1, 4
289  %tmp.3 = sext i32 %tmp.2 to i64
290  %tmp.5 = urem i64 %tmp.3, 4
291  %tmp.6 = trunc i64 %tmp.5 to i32
292  ret i32 %tmp.6
293}
294
295define i32 @test11(i32 %i) {
296; CHECK-LABEL: @test11(
297; CHECK-NEXT:    ret i32 0
298;
299  %tmp.1 = and i32 %i, -2
300  %tmp.3 = mul i32 %tmp.1, 2
301  %tmp.5 = urem i32 %tmp.3, 4
302  ret i32 %tmp.5
303}
304
305define i32 @test12(i32 %i) {
306; CHECK-LABEL: @test12(
307; CHECK-NEXT:    ret i32 0
308;
309  %tmp.1 = and i32 %i, -4
310  %tmp.5 = srem i32 %tmp.1, 2
311  ret i32 %tmp.5
312}
313
314define i32 @test13(i32 %i) {
315; CHECK-LABEL: @test13(
316; CHECK-NEXT:    ret i32 0
317;
318  %x = srem i32 %i, %i
319  ret i32 %x
320}
321
322define i64 @test14(i64 %x, i32 %y) {
323; CHECK-LABEL: @test14(
324; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[Y:%.*]]
325; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[SHL]] to i64
326; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[ZEXT]], -1
327; CHECK-NEXT:    [[UREM:%.*]] = and i64 [[TMP1]], [[X:%.*]]
328; CHECK-NEXT:    ret i64 [[UREM]]
329;
330  %shl = shl i32 1, %y
331  %zext = zext i32 %shl to i64
332  %urem = urem i64 %x, %zext
333  ret i64 %urem
334}
335
336define i64 @test15(i32 %x, i32 %y) {
337; CHECK-LABEL: @test15(
338; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[Y:%.*]]
339; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[NOTMASK]], -1
340; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]
341; CHECK-NEXT:    [[UREM:%.*]] = zext i32 [[TMP2]] to i64
342; CHECK-NEXT:    ret i64 [[UREM]]
343;
344  %shl = shl i32 1, %y
345  %zext0 = zext i32 %shl to i64
346  %zext1 = zext i32 %x to i64
347  %urem = urem i64 %zext1, %zext0
348  ret i64 %urem
349}
350
351define i32 @test16(i32 %x, i32 %y) {
352; CHECK-LABEL: @test16(
353; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[Y:%.*]], 11
354; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SHR]], 4
355; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[AND]], 3
356; CHECK-NEXT:    [[REM:%.*]] = and i32 [[TMP1]], [[X:%.*]]
357; CHECK-NEXT:    ret i32 [[REM]]
358;
359  %shr = lshr i32 %y, 11
360  %and = and i32 %shr, 4
361  %add = add i32 %and, 4
362  %rem = urem i32 %x, %add
363  ret i32 %rem
364}
365
366define i32 @test17(i32 %X) {
367; CHECK-LABEL: @test17(
368; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 1
369; CHECK-NEXT:    [[A:%.*]] = zext i1 [[TMP1]] to i32
370; CHECK-NEXT:    ret i32 [[A]]
371;
372  %A = urem i32 1, %X
373  ret i32 %A
374}
375
376define i32 @test18(i16 %x, i32 %y) {
377; CHECK-LABEL: @test18(
378; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[X:%.*]], 4
379; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i16 [[TMP1]], 0
380; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 63, i32 31
381; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], [[Y:%.*]]
382; CHECK-NEXT:    ret i32 [[TMP3]]
383;
384  %1 = and i16 %x, 4
385  %2 = icmp ne i16 %1, 0
386  %3 = select i1 %2, i32 32, i32 64
387  %4 = urem i32 %y, %3
388  ret i32 %4
389}
390
391define i32 @test19(i32 %x, i32 %y) {
392; CHECK-LABEL: @test19(
393; CHECK-NEXT:    [[A:%.*]] = shl i32 1, [[X:%.*]]
394; CHECK-NEXT:    [[B:%.*]] = shl i32 1, [[Y:%.*]]
395; CHECK-NEXT:    [[C:%.*]] = and i32 [[A]], [[B]]
396; CHECK-NEXT:    [[D:%.*]] = add i32 [[C]], [[A]]
397; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[D]], -1
398; CHECK-NEXT:    [[E:%.*]] = and i32 [[TMP1]], [[Y]]
399; CHECK-NEXT:    ret i32 [[E]]
400;
401  %A = shl i32 1, %x
402  %B = shl i32 1, %y
403  %C = and i32 %A, %B
404  %D = add i32 %C, %A
405  %E = urem i32 %y, %D
406  ret i32 %E
407}
408
409define i32 @test19_commutative0(i32 %x, i32 %y) {
410; CHECK-LABEL: @test19_commutative0(
411; CHECK-NEXT:    [[A:%.*]] = shl i32 1, [[X:%.*]]
412; CHECK-NEXT:    [[B:%.*]] = shl i32 1, [[Y:%.*]]
413; CHECK-NEXT:    [[C:%.*]] = and i32 [[B]], [[A]]
414; CHECK-NEXT:    [[D:%.*]] = add i32 [[C]], [[A]]
415; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[D]], -1
416; CHECK-NEXT:    [[E:%.*]] = and i32 [[TMP1]], [[Y]]
417; CHECK-NEXT:    ret i32 [[E]]
418;
419  %A = shl i32 1, %x
420  %B = shl i32 1, %y
421  %C = and i32 %B, %A ; swapped
422  %D = add i32 %C, %A
423  %E = urem i32 %y, %D
424  ret i32 %E
425}
426
427define i32 @test19_commutative1(i32 %x, i32 %y) {
428; CHECK-LABEL: @test19_commutative1(
429; CHECK-NEXT:    [[A:%.*]] = shl i32 1, [[X:%.*]]
430; CHECK-NEXT:    [[B:%.*]] = shl i32 1, [[Y:%.*]]
431; CHECK-NEXT:    [[C:%.*]] = and i32 [[A]], [[B]]
432; CHECK-NEXT:    [[D:%.*]] = add i32 [[A]], [[C]]
433; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[D]], -1
434; CHECK-NEXT:    [[E:%.*]] = and i32 [[TMP1]], [[Y]]
435; CHECK-NEXT:    ret i32 [[E]]
436;
437  %A = shl i32 1, %x
438  %B = shl i32 1, %y
439  %C = and i32 %A, %B
440  %D = add i32 %A, %C ; swapped
441  %E = urem i32 %y, %D
442  ret i32 %E
443}
444
445define i32 @test19_commutative2(i32 %x, i32 %y) {
446; CHECK-LABEL: @test19_commutative2(
447; CHECK-NEXT:    [[A:%.*]] = shl i32 1, [[X:%.*]]
448; CHECK-NEXT:    [[B:%.*]] = shl i32 1, [[Y:%.*]]
449; CHECK-NEXT:    [[C:%.*]] = and i32 [[B]], [[A]]
450; CHECK-NEXT:    [[D:%.*]] = add i32 [[A]], [[C]]
451; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[D]], -1
452; CHECK-NEXT:    [[E:%.*]] = and i32 [[TMP1]], [[Y]]
453; CHECK-NEXT:    ret i32 [[E]]
454;
455  %A = shl i32 1, %x
456  %B = shl i32 1, %y
457  %C = and i32 %B, %A ; swapped
458  %D = add i32 %A, %C ; swapped
459  %E = urem i32 %y, %D
460  ret i32 %E
461}
462
463define <2 x i64> @test20(<2 x i64> %X, <2 x i1> %C) {
464; CHECK-LABEL: @test20(
465; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer
466; CHECK-NEXT:    ret <2 x i64> [[R]]
467;
468  %V = select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8, i64 9>
469  %R = urem <2 x i64> %V, <i64 2, i64 3>
470  ret <2 x i64> %R
471}
472
473define i32 @test21(i1 %c0, i32* %p) {
474; CHECK-LABEL: @test21(
475; CHECK-NEXT:  entry:
476; CHECK-NEXT:    br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
477; CHECK:       if.then:
478; CHECK-NEXT:    [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
479; CHECK-NEXT:    [[PHI_BO:%.*]] = srem i32 [[V]], 5
480; CHECK-NEXT:    br label [[IF_END]]
481; CHECK:       if.end:
482; CHECK-NEXT:    [[LHS:%.*]] = phi i32 [ [[PHI_BO]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
483; CHECK-NEXT:    ret i32 [[LHS]]
484;
485entry:
486  br i1 %c0, label %if.then, label %if.end
487
488if.then:
489  %v = load volatile i32, i32* %p
490  br label %if.end
491
492if.end:
493  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
494  %rem = srem i32 %lhs, 5
495  ret i32 %rem
496}
497
498@a = common global [5 x i16] zeroinitializer, align 2
499@b = common global i16 0, align 2
500
501define i32 @pr27968_0(i1 %c0, i32* %p) {
502; CHECK-LABEL: @pr27968_0(
503; CHECK-NEXT:  entry:
504; CHECK-NEXT:    br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
505; CHECK:       if.then:
506; CHECK-NEXT:    [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
507; CHECK-NEXT:    br label [[IF_END]]
508; CHECK:       if.end:
509; CHECK-NEXT:    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:%.*]]
510; CHECK:       rem.is.safe:
511; CHECK-NEXT:    ret i32 0
512; CHECK:       rem.is.unsafe:
513; CHECK-NEXT:    ret i32 0
514;
515entry:
516  br i1 %c0, label %if.then, label %if.end
517
518if.then:
519  %v = load volatile i32, i32* %p
520  br label %if.end
521
522if.end:
523  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
524  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
525
526rem.is.safe:
527  %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)
528  ret i32 %rem
529
530rem.is.unsafe:
531  ret i32 0
532}
533
534define i32 @pr27968_1(i1 %c0, i1 %always_false, i32* %p) {
535; CHECK-LABEL: @pr27968_1(
536; CHECK-NEXT:  entry:
537; CHECK-NEXT:    br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
538; CHECK:       if.then:
539; CHECK-NEXT:    [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
540; CHECK-NEXT:    br label [[IF_END]]
541; CHECK:       if.end:
542; CHECK-NEXT:    [[LHS:%.*]] = phi i32 [ [[V]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ]
543; CHECK-NEXT:    br i1 [[ALWAYS_FALSE:%.*]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]]
544; CHECK:       rem.is.safe:
545; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[LHS]], -2147483648
546; CHECK-NEXT:    ret i32 [[REM]]
547; CHECK:       rem.is.unsafe:
548; CHECK-NEXT:    ret i32 0
549;
550entry:
551  br i1 %c0, label %if.then, label %if.end
552
553if.then:
554  %v = load volatile i32, i32* %p
555  br label %if.end
556
557if.end:
558  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
559  br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe
560
561rem.is.safe:
562  %rem = srem i32 %lhs, -2147483648
563  ret i32 %rem
564
565rem.is.unsafe:
566  ret i32 0
567}
568
569define i32 @pr27968_2(i1 %c0, i32* %p) {
570; CHECK-LABEL: @pr27968_2(
571; CHECK-NEXT:  entry:
572; CHECK-NEXT:    br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
573; CHECK:       if.then:
574; CHECK-NEXT:    [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
575; CHECK-NEXT:    br label [[IF_END]]
576; CHECK:       if.end:
577; CHECK-NEXT:    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:%.*]]
578; CHECK:       rem.is.safe:
579; CHECK-NEXT:    ret i32 0
580; CHECK:       rem.is.unsafe:
581; CHECK-NEXT:    ret i32 0
582;
583entry:
584  br i1 %c0, label %if.then, label %if.end
585
586if.then:
587  %v = load volatile i32, i32* %p
588  br label %if.end
589
590if.end:
591  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
592  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
593
594rem.is.safe:
595  %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)
596  ret i32 %rem
597
598rem.is.unsafe:
599  ret i32 0
600}
601
602define i32 @pr27968_3(i1 %c0, i1 %always_false, i32* %p) {
603; CHECK-LABEL: @pr27968_3(
604; CHECK-NEXT:  entry:
605; CHECK-NEXT:    br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
606; CHECK:       if.then:
607; CHECK-NEXT:    [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
608; CHECK-NEXT:    [[PHI_BO:%.*]] = and i32 [[V]], 2147483647
609; CHECK-NEXT:    br label [[IF_END]]
610; CHECK:       if.end:
611; CHECK-NEXT:    [[LHS:%.*]] = phi i32 [ [[PHI_BO]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ]
612; CHECK-NEXT:    br i1 [[ALWAYS_FALSE:%.*]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]]
613; CHECK:       rem.is.safe:
614; CHECK-NEXT:    ret i32 [[LHS]]
615; CHECK:       rem.is.unsafe:
616; CHECK-NEXT:    ret i32 0
617;
618entry:
619  br i1 %c0, label %if.then, label %if.end
620
621if.then:
622  %v = load volatile i32, i32* %p
623  br label %if.end
624
625if.end:
626  %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]
627  br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe
628
629rem.is.safe:
630  %rem = urem i32 %lhs, -2147483648
631  ret i32 %rem
632
633rem.is.unsafe:
634  ret i32 0
635}
636
637define i32 @test22(i32 %A) {
638; CHECK-LABEL: @test22(
639; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 2147483647
640; CHECK-NEXT:    [[MUL:%.*]] = urem i32 [[AND]], 2147483647
641; CHECK-NEXT:    ret i32 [[MUL]]
642;
643  %and = and i32 %A, 2147483647
644  %mul = srem i32 %and, 2147483647
645  ret i32 %mul
646}
647
648define <2 x i32> @test23(<2 x i32> %A) {
649; CHECK-LABEL: @test23(
650; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[A:%.*]], <i32 2147483647, i32 2147483647>
651; CHECK-NEXT:    [[MUL:%.*]] = urem <2 x i32> [[AND]], <i32 2147483647, i32 2147483647>
652; CHECK-NEXT:    ret <2 x i32> [[MUL]]
653;
654  %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647>
655  %mul = srem <2 x i32> %and, <i32 2147483647, i32 2147483647>
656  ret <2 x i32> %mul
657}
658
659define i1 @test24(i32 %A) {
660; CHECK-LABEL: @test24(
661; CHECK-NEXT:    [[B:%.*]] = and i32 [[A:%.*]], 2147483647
662; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[B]], 0
663; CHECK-NEXT:    ret i1 [[C]]
664;
665  %B = urem i32 %A, 2147483648 ; signbit
666  %C = icmp ne i32 %B, 0
667  ret i1 %C
668}
669
670define <2 x i1> @test24_vec(<2 x i32> %A) {
671; CHECK-LABEL: @test24_vec(
672; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[A:%.*]], <i32 2147483647, i32 2147483647>
673; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[B]], zeroinitializer
674; CHECK-NEXT:    ret <2 x i1> [[C]]
675;
676  %B = urem <2 x i32> %A, <i32 2147483648, i32 2147483648>
677  %C = icmp ne <2 x i32> %B, zeroinitializer
678  ret <2 x i1> %C
679}
680
681define i1 @test25(i32 %A) {
682; CHECK-LABEL: @test25(
683; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 2147483647
684; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
685; CHECK-NEXT:    ret i1 [[C]]
686;
687  %B = srem i32 %A, 2147483648 ; signbit
688  %C = icmp ne i32 %B, 0
689  ret i1 %C
690}
691
692define <2 x i1> @test25_vec(<2 x i32> %A) {
693; CHECK-LABEL: @test25_vec(
694; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], <i32 2147483647, i32 2147483647>
695; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
696; CHECK-NEXT:    ret <2 x i1> [[C]]
697;
698  %B = srem <2 x i32> %A, <i32 2147483648, i32 2147483648>
699  %C = icmp ne <2 x i32> %B, zeroinitializer
700  ret <2 x i1> %C
701}
702
703define i1 @test26(i32 %A, i32 %B) {
704; CHECK-LABEL: @test26(
705; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[B:%.*]]
706; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[NOTMASK]], -1
707; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
708; CHECK-NEXT:    [[E:%.*]] = icmp ne i32 [[TMP2]], 0
709; CHECK-NEXT:    ret i1 [[E]]
710;
711  %C = shl i32 1, %B ; not a constant
712  %D = srem i32 %A, %C
713  %E = icmp ne i32 %D, 0
714  ret i1 %E
715}
716
717define i1 @test27(i32 %A, i32* %remdst) {
718; CHECK-LABEL: @test27(
719; CHECK-NEXT:    [[B:%.*]] = srem i32 [[A:%.*]], -2147483648
720; CHECK-NEXT:    store i32 [[B]], i32* [[REMDST:%.*]], align 1
721; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[B]], 0
722; CHECK-NEXT:    ret i1 [[C]]
723;
724  %B = srem i32 %A, 2147483648 ; signbit
725  store i32 %B, i32* %remdst, align 1 ; extra use of rem
726  %C = icmp ne i32 %B, 0
727  ret i1 %C
728}
729
730define i1 @test28(i32 %A) {
731; CHECK-LABEL: @test28(
732; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 2147483647
733; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[TMP1]], 0
734; CHECK-NEXT:    ret i1 [[C]]
735;
736  %B = srem i32 %A, 2147483648 ; signbit
737  %C = icmp eq i32 %B, 0 ; another equality predicate
738  ret i1 %C
739}
740
741; FP division-by-zero is not UB.
742
743define double @PR34870(i1 %cond, double %x, double %y) {
744; CHECK-LABEL: @PR34870(
745; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], double [[Y:%.*]], double 0.000000e+00
746; CHECK-NEXT:    [[FMOD:%.*]] = frem double [[X:%.*]], [[SEL]]
747; CHECK-NEXT:    ret double [[FMOD]]
748;
749  %sel = select i1 %cond, double %y, double 0.0
750  %fmod = frem double %x, %sel
751  ret double %fmod
752}
753
754