xref: /llvm-project/llvm/test/Transforms/SCCP/divrem.ll (revision 85b289377bff14790f402e5ea84bb24168a68fc6)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=ipsccp -S < %s | FileCheck %s
3
4define i8 @sdiv_nonneg0_nonneg1(i8 %x, i8 %y) {
5; CHECK-LABEL: @sdiv_nonneg0_nonneg1(
6; CHECK-NEXT:    [[PX:%.*]] = and i8 [[X:%.*]], 127
7; CHECK-NEXT:    [[PY:%.*]] = lshr i8 [[Y:%.*]], 1
8; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[PX]], [[PY]]
9; CHECK-NEXT:    ret i8 [[R]]
10;
11  %px = and i8 %x, 127
12  %py = lshr i8 %y, 1
13  %r = sdiv i8 %px, %py
14  ret i8 %r
15}
16
17define i8 @sdiv_nonnegconst0_nonneg1(i7 %y) {
18; CHECK-LABEL: @sdiv_nonnegconst0_nonneg1(
19; CHECK-NEXT:    [[PY:%.*]] = zext i7 [[Y:%.*]] to i8
20; CHECK-NEXT:    [[R:%.*]] = udiv i8 42, [[PY]]
21; CHECK-NEXT:    ret i8 [[R]]
22;
23  %py = zext i7 %y to i8
24  %r = sdiv i8 42, %py
25  ret i8 %r
26}
27
28; TODO: This can be converted to udiv.
29
30define i8 @sdiv_nonneg0_nonnegconst1(i8 %x) {
31; CHECK-LABEL: @sdiv_nonneg0_nonnegconst1(
32; CHECK-NEXT:    [[PX:%.*]] = mul nsw i8 [[X:%.*]], [[X]]
33; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[PX]], 42
34; CHECK-NEXT:    ret i8 [[R]]
35;
36  %px = mul nsw i8 %x, %x
37  %r = sdiv i8 %px, 42
38  ret i8 %r
39}
40
41; negative test
42
43define i8 @sdiv_unknown0_nonneg1(i8 %x, i8 %y) {
44; CHECK-LABEL: @sdiv_unknown0_nonneg1(
45; CHECK-NEXT:    [[PY:%.*]] = lshr i8 [[Y:%.*]], 1
46; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[X:%.*]], [[PY]]
47; CHECK-NEXT:    ret i8 [[R]]
48;
49  %py = lshr i8 %y, 1
50  %r = sdiv i8 %x, %py
51  ret i8 %r
52}
53
54; negative test
55
56define i8 @sdiv_nonnegconst0_unknown1(i7 %y) {
57; CHECK-LABEL: @sdiv_nonnegconst0_unknown1(
58; CHECK-NEXT:    [[SY:%.*]] = sext i7 [[Y:%.*]] to i8
59; CHECK-NEXT:    [[R:%.*]] = sdiv i8 42, [[SY]]
60; CHECK-NEXT:    ret i8 [[R]]
61;
62  %sy = sext i7 %y to i8
63  %r = sdiv i8 42, %sy
64  ret i8 %r
65}
66
67; negative test - mul must be 'nsw' to be known non-negative
68
69define i8 @sdiv_unknown0_nonnegconst1(i8 %x) {
70; CHECK-LABEL: @sdiv_unknown0_nonnegconst1(
71; CHECK-NEXT:    [[SX:%.*]] = mul i8 [[X:%.*]], [[X]]
72; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[SX]], 42
73; CHECK-NEXT:    ret i8 [[R]]
74;
75  %sx = mul i8 %x, %x
76  %r = sdiv i8 %sx, 42
77  ret i8 %r
78}
79
80define i8 @srem_nonneg0_nonneg1(i8 %x, i8 %y) {
81; CHECK-LABEL: @srem_nonneg0_nonneg1(
82; CHECK-NEXT:    [[PX:%.*]] = and i8 [[X:%.*]], 127
83; CHECK-NEXT:    [[PY:%.*]] = lshr i8 [[Y:%.*]], 1
84; CHECK-NEXT:    [[R:%.*]] = urem i8 [[PX]], [[PY]]
85; CHECK-NEXT:    ret i8 [[R]]
86;
87  %px = and i8 %x, 127
88  %py = lshr i8 %y, 1
89  %r = srem i8 %px, %py
90  ret i8 %r
91}
92
93define i8 @srem_nonnegconst0_nonneg1(i8 %y) {
94; CHECK-LABEL: @srem_nonnegconst0_nonneg1(
95; CHECK-NEXT:    [[PY:%.*]] = and i8 [[Y:%.*]], 127
96; CHECK-NEXT:    [[R:%.*]] = urem i8 42, [[PY]]
97; CHECK-NEXT:    ret i8 [[R]]
98;
99  %py = and i8 %y, 127
100  %r = srem i8 42, %py
101  ret i8 %r
102}
103
104define i8 @srem_nonneg0_nonnegconst1(i7 %x) {
105; CHECK-LABEL: @srem_nonneg0_nonnegconst1(
106; CHECK-NEXT:    [[PX:%.*]] = zext i7 [[X:%.*]] to i8
107; CHECK-NEXT:    [[R:%.*]] = urem i8 [[PX]], 42
108; CHECK-NEXT:    ret i8 [[R]]
109;
110  %px = zext i7 %x to i8
111  %r = srem i8 %px, 42
112  ret i8 %r
113}
114
115; negative test
116
117define i8 @srem_unknown0_nonneg1(i8 %x, i8 %y) {
118; CHECK-LABEL: @srem_unknown0_nonneg1(
119; CHECK-NEXT:    [[PY:%.*]] = lshr i8 [[Y:%.*]], 1
120; CHECK-NEXT:    [[R:%.*]] = srem i8 [[X:%.*]], [[PY]]
121; CHECK-NEXT:    ret i8 [[R]]
122;
123  %py = lshr i8 %y, 1
124  %r = srem i8 %x, %py
125  ret i8 %r
126}
127
128; negative test
129
130define i8 @srem_nonnegconst0_unknown1(i7 %y) {
131; CHECK-LABEL: @srem_nonnegconst0_unknown1(
132; CHECK-NEXT:    [[SY:%.*]] = sext i7 [[Y:%.*]] to i8
133; CHECK-NEXT:    [[R:%.*]] = srem i8 42, [[SY]]
134; CHECK-NEXT:    ret i8 [[R]]
135;
136  %sy = sext i7 %y to i8
137  %r = srem i8 42, %sy
138  ret i8 %r
139}
140
141; negative test - mul must be 'nsw' to be known non-negative
142
143define i8 @srem_unknown0_nonnegconst1(i8 %x) {
144; CHECK-LABEL: @srem_unknown0_nonnegconst1(
145; CHECK-NEXT:    [[SX:%.*]] = mul i8 [[X:%.*]], [[X]]
146; CHECK-NEXT:    [[R:%.*]] = srem i8 [[SX]], 42
147; CHECK-NEXT:    ret i8 [[R]]
148;
149  %sx = mul i8 %x, %x
150  %r = srem i8 %sx, 42
151  ret i8 %r
152}
153
154; x is known non-negative in t block
155
156define i32 @PR57472(i32 %x) {
157; CHECK-LABEL: @PR57472(
158; CHECK-NEXT:  entry:
159; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], 0
160; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
161; CHECK:       t:
162; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[X]], 16
163; CHECK-NEXT:    br label [[EXIT:%.*]]
164; CHECK:       f:
165; CHECK-NEXT:    br label [[EXIT]]
166; CHECK:       exit:
167; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[REM]], [[T]] ], [ 42, [[F]] ]
168; CHECK-NEXT:    ret i32 [[COND]]
169;
170entry:
171  %cmp = icmp sge i32 %x, 0
172  br i1 %cmp, label %t, label %f
173
174t:
175  %rem = srem i32 %x, 16
176  br label %exit
177
178f:
179  br label %exit
180
181exit:
182  %cond = phi i32 [ %rem, %t ], [ 42, %f ]
183  ret i32 %cond
184}
185
186; x is known non-negative in f block
187
188define i32 @PR57472_alt(i32 %x) {
189; CHECK-LABEL: @PR57472_alt(
190; CHECK-NEXT:  entry:
191; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2000000000
192; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
193; CHECK:       t:
194; CHECK-NEXT:    br label [[EXIT:%.*]]
195; CHECK:       f:
196; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 16, [[X]]
197; CHECK-NEXT:    br label [[EXIT]]
198; CHECK:       exit:
199; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ -42, [[T]] ], [ [[DIV]], [[F]] ]
200; CHECK-NEXT:    ret i32 [[COND]]
201;
202entry:
203  %cmp = icmp ugt i32 %x, 2000000000
204  br i1 %cmp, label %t, label %f
205
206t:
207  br label %exit
208
209f:
210  %div = sdiv i32 16, %x
211  br label %exit
212
213exit:
214  %cond = phi i32 [ -42, %t ], [ %div, %f ]
215  ret i32 %cond
216}
217