Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / add4.ll
blob0e97deb4d98ade4daa75262197e0d501d00d8740
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i32)
6 define i64 @match_unsigned(i64 %x) {
7 ; CHECK-LABEL: @match_unsigned(
8 ; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[X:%.*]], 19136
9 ; CHECK-NEXT:    ret i64 [[UREM]]
11   %t = urem i64 %x, 299
12   %t1 = udiv i64 %x, 299
13   %t2 = urem i64 %t1, 64
14   %t3 = mul i64 %t2, 299
15   %t4 = add i64 %t, %t3
16   ret i64 %t4
19 define <2 x i64> @match_unsigned_vector(<2 x i64> %x) {
20 ; CHECK-LABEL: @match_unsigned_vector(
21 ; CHECK-NEXT:  bb:
22 ; CHECK-NEXT:    [[UREM:%.*]] = urem <2 x i64> [[X:%.*]], splat (i64 19136)
23 ; CHECK-NEXT:    ret <2 x i64> [[UREM]]
25 bb:
26   %tmp = urem <2 x i64> %x, <i64 299, i64 299>
27   %tmp1 = udiv <2 x i64> %x, <i64 299, i64 299>
28   %tmp2 = urem <2 x i64> %tmp1, <i64 64, i64 64>
29   %tmp3 = mul <2 x i64> %tmp2, <i64 299, i64 299>
30   %tmp4 = add <2 x i64> %tmp, %tmp3
31   ret <2 x i64> %tmp4
33 define i64 @match_andAsRem_lshrAsDiv_shlAsMul(i64 %x) {
34 ; CHECK-LABEL: @match_andAsRem_lshrAsDiv_shlAsMul(
35 ; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[X:%.*]], 576
36 ; CHECK-NEXT:    ret i64 [[UREM]]
38   %t = and i64 %x, 63
39   %t1 = lshr i64 %x, 6
40   %t2 = urem i64 %t1, 9
41   %t3 = shl i64 %t2, 6
42   %t4 = add i64 %t, %t3
43   ret i64 %t4
46 define i64 @match_signed(i64 %x) {
47 ; CHECK-LABEL: @match_signed(
48 ; CHECK-NEXT:    [[SREM1:%.*]] = srem i64 [[X:%.*]], 172224
49 ; CHECK-NEXT:    ret i64 [[SREM1]]
51   %t = srem i64 %x, 299
52   %t1 = sdiv i64 %x, 299
53   %t2 = srem i64 %t1, 64
54   %t3 = sdiv i64 %x, 19136
55   %t4 = srem i64 %t3, 9
56   %t5 = mul i64 %t2, 299
57   %t6 = add i64 %t, %t5
58   %t7 = mul i64 %t4, 19136
59   %t8 = add i64 %t6, %t7
60   ret i64 %t8
63 define <2 x i64> @match_signed_vector(<2 x i64> %x) {
64 ; CHECK-LABEL: @match_signed_vector(
65 ; CHECK-NEXT:  bb:
66 ; CHECK-NEXT:    [[SREM1:%.*]] = srem <2 x i64> [[X:%.*]], splat (i64 172224)
67 ; CHECK-NEXT:    ret <2 x i64> [[SREM1]]
69 bb:
70   %tmp = srem <2 x i64> %x, <i64 299, i64 299>
71   %tmp1 = sdiv <2 x i64> %x, <i64 299, i64 299>
72   %tmp2 = srem <2 x i64> %tmp1, <i64 64, i64 64>
73   %tmp3 = sdiv <2 x i64> %x, <i64 19136, i64 19136>
74   %tmp4 = srem <2 x i64> %tmp3, <i64 9, i64 9>
75   %tmp5 = mul <2 x i64> %tmp2, <i64 299, i64 299>
76   %tmp6 = add <2 x i64> %tmp, %tmp5
77   %tmp7 = mul <2 x i64> %tmp4, <i64 19136, i64 19136>
78   %tmp8 = add <2 x i64> %tmp6, %tmp7
79   ret <2 x i64> %tmp8
82 define i64 @not_match_inconsistent_signs(i64 %x) {
83 ; CHECK-LABEL: @not_match_inconsistent_signs(
84 ; CHECK-NEXT:    [[T:%.*]] = urem i64 [[X:%.*]], 299
85 ; CHECK-NEXT:    [[T1:%.*]] = sdiv i64 [[X]], 299
86 ; CHECK-NEXT:    [[T2:%.*]] = and i64 [[T1]], 63
87 ; CHECK-NEXT:    [[T3:%.*]] = mul nuw nsw i64 [[T2]], 299
88 ; CHECK-NEXT:    [[T4:%.*]] = add nuw nsw i64 [[T]], [[T3]]
89 ; CHECK-NEXT:    ret i64 [[T4]]
91   %t = urem i64 %x, 299
92   %t1 = sdiv i64 %x, 299
93   %t2 = urem i64 %t1, 64
94   %t3 = mul i64 %t2, 299
95   %t4 = add i64 %t, %t3
96   ret i64 %t4
99 define i64 @not_match_inconsistent_values(i64 %x) {
100 ; CHECK-LABEL: @not_match_inconsistent_values(
101 ; CHECK-NEXT:    [[T:%.*]] = urem i64 [[X:%.*]], 299
102 ; CHECK-NEXT:    [[T1:%.*]] = udiv i64 [[X]], 29
103 ; CHECK-NEXT:    [[T2:%.*]] = and i64 [[T1]], 63
104 ; CHECK-NEXT:    [[T3:%.*]] = mul nuw nsw i64 [[T2]], 299
105 ; CHECK-NEXT:    [[T4:%.*]] = add nuw nsw i64 [[T]], [[T3]]
106 ; CHECK-NEXT:    ret i64 [[T4]]
108   %t = urem i64 %x, 299
109   %t1 = udiv i64 %x, 29
110   %t2 = urem i64 %t1, 64
111   %t3 = mul i64 %t2, 299
112   %t4 = add i64 %t, %t3
113   ret i64 %t4
116 define i32 @not_match_overflow(i32 %x) {
117 ; CHECK-LABEL: @not_match_overflow(
118 ; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]
119 ; CHECK-NEXT:    [[T:%.*]] = urem i32 [[X_FR]], 299
120 ; CHECK-NEXT:    [[TMP1:%.*]] = urem i32 [[X_FR]], 299
121 ; CHECK-NEXT:    [[T3:%.*]] = sub nuw i32 [[X_FR]], [[TMP1]]
122 ; CHECK-NEXT:    [[T4:%.*]] = add i32 [[T]], [[T3]]
123 ; CHECK-NEXT:    ret i32 [[T4]]
125   %t = urem i32 %x, 299
126   %t1 = udiv i32 %x, 299
127   %t2 = urem i32 %t1, 147483647
128   %t3 = mul i32 %t2, 299
129   %t4 = add i32 %t, %t3
130   ret i32 %t4
133 ; Tests from PR76128.
134 define i32 @fold_add_udiv_urem(i32 noundef %val) {
135 ; CHECK-LABEL: @fold_add_udiv_urem(
136 ; CHECK-NEXT:  entry:
137 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10
138 ; CHECK-NEXT:    [[TMP0:%.*]] = mul nuw i32 [[DIV]], 6
139 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[VAL]]
140 ; CHECK-NEXT:    ret i32 [[ADD]]
142 entry:
143   %div = udiv i32 %val, 10
144   %shl = shl i32 %div, 4
145   %rem = urem i32 %val, 10
146   %add = add i32 %shl, %rem
147   ret i32 %add
149 define i32 @fold_add_sdiv_srem(i32 noundef %val) {
150 ; CHECK-LABEL: @fold_add_sdiv_srem(
151 ; CHECK-NEXT:  entry:
152 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[VAL:%.*]], 10
153 ; CHECK-NEXT:    [[TMP0:%.*]] = mul nsw i32 [[DIV]], 6
154 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[VAL]]
155 ; CHECK-NEXT:    ret i32 [[ADD]]
157 entry:
158   %div = sdiv i32 %val, 10
159   %shl = shl i32 %div, 4
160   %rem = srem i32 %val, 10
161   %add = add i32 %shl, %rem
162   ret i32 %add
164 define i32 @fold_add_udiv_urem_to_mul(i32 noundef %val) {
165 ; CHECK-LABEL: @fold_add_udiv_urem_to_mul(
166 ; CHECK-NEXT:  entry:
167 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[VAL:%.*]], 3
168 ; CHECK-NEXT:    ret i32 [[ADD]]
170 entry:
171   %div = udiv i32 %val, 7
172   %mul1 = mul i32 %div, 21
173   %rem = urem i32 %val, 7
174   %mul2 = mul i32 %rem, 3
175   %add = add i32 %mul1, %mul2
176   ret i32 %add
178 define i32 @fold_add_udiv_urem_to_mul_multiuse(i32 noundef %val) {
179 ; CHECK-LABEL: @fold_add_udiv_urem_to_mul_multiuse(
180 ; CHECK-NEXT:  entry:
181 ; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[VAL:%.*]], 7
182 ; CHECK-NEXT:    call void @use(i32 [[REM]])
183 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[VAL]], 3
184 ; CHECK-NEXT:    ret i32 [[ADD]]
186 entry:
187   %div = udiv i32 %val, 7
188   %mul1 = mul i32 %div, 21
189   %rem = urem i32 %val, 7
190   call void @use(i32 %rem)
191   %mul2 = mul i32 %rem, 3
192   %add = add i32 %mul1, %mul2
193   ret i32 %add
195 define i32 @fold_add_udiv_urem_commuted(i32 noundef %val) {
196 ; CHECK-LABEL: @fold_add_udiv_urem_commuted(
197 ; CHECK-NEXT:  entry:
198 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10
199 ; CHECK-NEXT:    [[TMP0:%.*]] = mul nuw i32 [[DIV]], 6
200 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[VAL]]
201 ; CHECK-NEXT:    ret i32 [[ADD]]
203 entry:
204   %div = udiv i32 %val, 10
205   %shl = shl i32 %div, 4
206   %rem = urem i32 %val, 10
207   %add = add i32 %rem, %shl
208   ret i32 %add
210 define i32 @fold_add_udiv_urem_or_disjoint(i32 noundef %val) {
211 ; CHECK-LABEL: @fold_add_udiv_urem_or_disjoint(
212 ; CHECK-NEXT:  entry:
213 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10
214 ; CHECK-NEXT:    [[TMP0:%.*]] = mul nuw i32 [[DIV]], 6
215 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[VAL]]
216 ; CHECK-NEXT:    ret i32 [[ADD]]
218 entry:
219   %div = udiv i32 %val, 10
220   %shl = shl i32 %div, 4
221   %rem = urem i32 %val, 10
222   %add = or disjoint i32 %shl, %rem
223   ret i32 %add
225 ; Negative tests
226 define i32 @fold_add_udiv_urem_without_noundef(i32 %val) {
227 ; CHECK-LABEL: @fold_add_udiv_urem_without_noundef(
228 ; CHECK-NEXT:  entry:
229 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10
230 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[DIV]], 4
231 ; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[VAL]], 10
232 ; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i32 [[SHL]], [[REM]]
233 ; CHECK-NEXT:    ret i32 [[ADD]]
235 entry:
236   %div = udiv i32 %val, 10
237   %shl = shl i32 %div, 4
238   %rem = urem i32 %val, 10
239   %add = add i32 %shl, %rem
240   ret i32 %add
242 define i32 @fold_add_udiv_urem_multiuse_mul(i32 noundef %val) {
243 ; CHECK-LABEL: @fold_add_udiv_urem_multiuse_mul(
244 ; CHECK-NEXT:  entry:
245 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10
246 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[DIV]], 4
247 ; CHECK-NEXT:    call void @use(i32 [[SHL]])
248 ; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[VAL]], 10
249 ; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i32 [[SHL]], [[REM]]
250 ; CHECK-NEXT:    ret i32 [[ADD]]
252 entry:
253   %div = udiv i32 %val, 10
254   %shl = shl i32 %div, 4
255   call void @use(i32 %shl)
256   %rem = urem i32 %val, 10
257   %add = add i32 %shl, %rem
258   ret i32 %add
260 define i32 @fold_add_udiv_srem(i32 noundef %val) {
261 ; CHECK-LABEL: @fold_add_udiv_srem(
262 ; CHECK-NEXT:  entry:
263 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10
264 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[DIV]], 4
265 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[VAL]], 10
266 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SHL]], [[REM]]
267 ; CHECK-NEXT:    ret i32 [[ADD]]
269 entry:
270   %div = udiv i32 %val, 10
271   %shl = shl i32 %div, 4
272   %rem = srem i32 %val, 10
273   %add = add i32 %shl, %rem
274   ret i32 %add
276 define i32 @fold_add_udiv_urem_non_constant(i32 noundef %val, i32 noundef %c) {
277 ; CHECK-LABEL: @fold_add_udiv_urem_non_constant(
278 ; CHECK-NEXT:  entry:
279 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[VAL:%.*]], [[C:%.*]]
280 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[DIV]], 4
281 ; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[VAL]], [[C]]
282 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SHL]], [[REM]]
283 ; CHECK-NEXT:    ret i32 [[ADD]]
285 entry:
286   %div = udiv i32 %val, %c
287   %shl = shl i32 %div, 4
288   %rem = urem i32 %val, %c
289   %add = add i32 %shl, %rem
290   ret i32 %add