1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine -S < %s | FileCheck %s
3
4; Given:
5;   icmp eq/ne (urem %x, C), 0
6; Iff C is not a power of two (those should not get to here though),
7; and %x may have at most one bit set, omit the 'urem':
8;   icmp eq/ne %x, 0
9
10;------------------------------------------------------------------------------;
11; Basic scalar tests
12;------------------------------------------------------------------------------;
13
14define i1 @p0_scalar_urem_by_const(i32 %x, i32 %y) {
15; CHECK-LABEL: @p0_scalar_urem_by_const(
16; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 128
17; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T0]], 0
18; CHECK-NEXT:    ret i1 [[T2]]
19;
20  %t0 = and i32 %x, 128 ; clearly a power-of-two or zero
21  %t1 = urem i32 %t0, 6 ; '6' is clearly not a power of two
22  %t2 = icmp eq i32 %t1, 0
23  ret i1 %t2
24}
25
26define i1 @p1_scalar_urem_by_nonconst(i32 %x, i32 %y) {
27; CHECK-LABEL: @p1_scalar_urem_by_nonconst(
28; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 128
29; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T0]], 0
30; CHECK-NEXT:    ret i1 [[T3]]
31;
32  %t0 = and i32 %x, 128 ; clearly a power-of-two or zero
33  %t1 = or i32 %y, 6 ; two bits set, clearly not a power of two
34  %t2 = urem i32 %t0, %t1
35  %t3 = icmp eq i32 %t2, 0
36  ret i1 %t3
37}
38
39define i1 @p2_scalar_shifted_urem_by_const(i32 %x, i32 %y) {
40; CHECK-LABEL: @p2_scalar_shifted_urem_by_const(
41; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 1
42; CHECK-NEXT:    [[T1:%.*]] = shl nuw i32 [[T0]], [[Y:%.*]]
43; CHECK-NEXT:    [[T2:%.*]] = urem i32 [[T1]], 3
44; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T2]], 0
45; CHECK-NEXT:    ret i1 [[T3]]
46;
47  %t0 = and i32 %x, 1 ; clearly a power-of-two or zero
48  %t1 = shl i32 %t0, %y ; will still be a power-of-two or zero with any %y
49  %t2 = urem i32 %t1, 3 ; '3' is clearly not a power of two
50  %t3 = icmp eq i32 %t2, 0
51  ret i1 %t3
52}
53
54define i1 @p3_scalar_shifted2_urem_by_const(i32 %x, i32 %y) {
55; CHECK-LABEL: @p3_scalar_shifted2_urem_by_const(
56; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 2
57; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[T0]], [[Y:%.*]]
58; CHECK-NEXT:    [[T2:%.*]] = urem i32 [[T1]], 3
59; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T2]], 0
60; CHECK-NEXT:    ret i1 [[T3]]
61;
62  %t0 = and i32 %x, 2 ; clearly a power-of-two or zero
63  %t1 = shl i32 %t0, %y ; will still be a power-of-two or zero with any %y
64  %t2 = urem i32 %t1, 3 ; '3' is clearly not a power of two
65  %t3 = icmp eq i32 %t2, 0
66  ret i1 %t3
67}
68
69;------------------------------------------------------------------------------;
70; Basic vector tests
71;------------------------------------------------------------------------------;
72
73define <4 x i1> @p4_vector_urem_by_const__splat(<4 x i32> %x, <4 x i32> %y) {
74; CHECK-LABEL: @p4_vector_urem_by_const__splat(
75; CHECK-NEXT:    [[T0:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 128)
76; CHECK-NEXT:    [[T2:%.*]] = icmp eq <4 x i32> [[T0]], zeroinitializer
77; CHECK-NEXT:    ret <4 x i1> [[T2]]
78;
79  %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 128, i32 128> ; clearly a power-of-two or zero
80  %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two
81  %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>
82  ret <4 x i1> %t2
83}
84
85define <4 x i1> @p5_vector_urem_by_const__nonsplat(<4 x i32> %x, <4 x i32> %y) {
86; CHECK-LABEL: @p5_vector_urem_by_const__nonsplat(
87; CHECK-NEXT:    [[T0:%.*]] = and <4 x i32> [[X:%.*]], <i32 128, i32 2, i32 4, i32 8>
88; CHECK-NEXT:    [[T1:%.*]] = urem <4 x i32> [[T0]], <i32 3, i32 5, i32 6, i32 9>
89; CHECK-NEXT:    [[T2:%.*]] = icmp eq <4 x i32> [[T1]], zeroinitializer
90; CHECK-NEXT:    ret <4 x i1> [[T2]]
91;
92  %t0 = and <4 x i32> %x, <i32 128, i32 2, i32 4, i32 8>
93  %t1 = urem <4 x i32> %t0, <i32 3, i32 5, i32 6, i32 9>
94  %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>
95  ret <4 x i1> %t2
96}
97
98; The poison value in the vector makes the whole function UB.
99
100define <4 x i1> @p6_vector_urem_by_const__nonsplat_poison0(<4 x i32> %x, <4 x i32> %y) {
101; CHECK-LABEL: @p6_vector_urem_by_const__nonsplat_poison0(
102; CHECK-NEXT:    [[T0:%.*]] = and <4 x i32> [[X:%.*]], <i32 128, i32 128, i32 poison, i32 128>
103; CHECK-NEXT:    [[T2:%.*]] = icmp eq <4 x i32> [[T0]], zeroinitializer
104; CHECK-NEXT:    ret <4 x i1> [[T2]]
105;
106  %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 poison, i32 128>
107  %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two
108  %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>
109  ret <4 x i1> %t2
110}
111
112define <4 x i1> @p7_vector_urem_by_const__nonsplat_poison2(<4 x i32> %x, <4 x i32> %y) {
113; CHECK-LABEL: @p7_vector_urem_by_const__nonsplat_poison2(
114; CHECK-NEXT:    [[T0:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 128)
115; CHECK-NEXT:    [[T2:%.*]] = icmp eq <4 x i32> [[T0]], <i32 0, i32 0, i32 poison, i32 0>
116; CHECK-NEXT:    ret <4 x i1> [[T2]]
117;
118  %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 128, i32 128> ; clearly a power-of-two or zero
119  %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two
120  %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 poison, i32 0>
121  ret <4 x i1> %t2
122}
123
124define <4 x i1> @p8_vector_urem_by_const__nonsplat_poison3(<4 x i32> %x, <4 x i32> %y) {
125; CHECK-LABEL: @p8_vector_urem_by_const__nonsplat_poison3(
126; CHECK-NEXT:    [[T0:%.*]] = and <4 x i32> [[X:%.*]], <i32 128, i32 128, i32 poison, i32 128>
127; CHECK-NEXT:    [[T2:%.*]] = icmp eq <4 x i32> [[T0]], <i32 0, i32 0, i32 poison, i32 0>
128; CHECK-NEXT:    ret <4 x i1> [[T2]]
129;
130  %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 poison, i32 128>
131  %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two
132  %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 poison, i32 0>
133  ret <4 x i1> %t2
134}
135
136;------------------------------------------------------------------------------;
137; Basic negative tests
138;------------------------------------------------------------------------------;
139
140define i1 @n0_urem_of_maybe_not_power_of_two(i32 %x, i32 %y) {
141; CHECK-LABEL: @n0_urem_of_maybe_not_power_of_two(
142; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 3
143; CHECK-NEXT:    [[T1:%.*]] = urem i32 [[T0]], 3
144; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
145; CHECK-NEXT:    ret i1 [[T2]]
146;
147  %t0 = and i32 %x, 3 ; up to two bits set, not power-of-two
148  %t1 = urem i32 %t0, 3
149  %t2 = icmp eq i32 %t1, 0
150  ret i1 %t2
151}
152
153define i1 @n1_urem_by_maybe_power_of_two(i32 %x, i32 %y) {
154; CHECK-LABEL: @n1_urem_by_maybe_power_of_two(
155; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 128
156; CHECK-NEXT:    [[T1:%.*]] = or i32 [[Y:%.*]], 1
157; CHECK-NEXT:    [[T2:%.*]] = urem i32 [[T0]], [[T1]]
158; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T2]], 0
159; CHECK-NEXT:    ret i1 [[T3]]
160;
161  %t0 = and i32 %x, 128 ; clearly a power-of-two or zero
162  %t1 = or i32 %y, 1 ; one low bit set, may be a power of two
163  %t2 = urem i32 %t0, %t1
164  %t3 = icmp eq i32 %t2, 0
165  ret i1 %t3
166}
167