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