xref: /llvm-project/llvm/test/Transforms/InstCombine/add-shl-sdiv-to-srem.ll (revision 69ba565734a64bea91062bfd0c5988276b73eb87)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i8 @add-shl-sdiv-scalar0(i8 %x) {
5; CHECK-LABEL: @add-shl-sdiv-scalar0(
6; CHECK-NEXT:    [[RZ:%.*]] = srem i8 [[X:%.*]], 4
7; CHECK-NEXT:    ret i8 [[RZ]]
8;
9  %sd = sdiv i8 %x, -4
10  %sl = shl i8 %sd, 2
11  %rz = add i8 %sl, %x
12  ret i8 %rz
13}
14
15define i8 @add-shl-sdiv-scalar0_commuted(i8 %x) {
16; CHECK-LABEL: @add-shl-sdiv-scalar0_commuted(
17; CHECK-NEXT:    [[RZ:%.*]] = srem i8 [[X:%.*]], 4
18; CHECK-NEXT:    ret i8 [[RZ]]
19;
20  %sd = sdiv i8 %x, -4
21  %sl = shl i8 %sd, 2
22  %rz = add i8 %x, %sl
23  ret i8 %rz
24}
25
26define i8 @add-shl-sdiv-scalar1(i8 %x) {
27; CHECK-LABEL: @add-shl-sdiv-scalar1(
28; CHECK-NEXT:    [[RZ:%.*]] = srem i8 [[X:%.*]], 64
29; CHECK-NEXT:    ret i8 [[RZ]]
30;
31  %sd = sdiv i8 %x, -64
32  %sl = shl i8 %sd, 6
33  %rz = add i8 %sl, %x
34  ret i8 %rz
35}
36
37define i32 @add-shl-sdiv-scalar2(i32 %x) {
38; CHECK-LABEL: @add-shl-sdiv-scalar2(
39; CHECK-NEXT:    [[RZ:%.*]] = srem i32 [[X:%.*]], 1073741824
40; CHECK-NEXT:    ret i32 [[RZ]]
41;
42  %sd = sdiv i32 %x, -1073741824
43  %sl = shl i32 %sd, 30
44  %rz = add i32 %sl, %x
45  ret i32 %rz
46}
47
48; Splat vectors
49
50define <3 x i8> @add-shl-sdiv-splat0(<3 x i8> %x) {
51; CHECK-LABEL: @add-shl-sdiv-splat0(
52; CHECK-NEXT:    [[RZ:%.*]] = srem <3 x i8> [[X:%.*]], splat (i8 4)
53; CHECK-NEXT:    ret <3 x i8> [[RZ]]
54;
55  %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4>
56  %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2>
57  %rz = add <3 x i8> %sl, %x
58  ret <3 x i8> %rz
59}
60
61define <4 x i32> @add-shl-sdiv-splat1(<4 x i32> %x) {
62; CHECK-LABEL: @add-shl-sdiv-splat1(
63; CHECK-NEXT:    [[RZ:%.*]] = srem <4 x i32> [[X:%.*]], splat (i32 1073741824)
64; CHECK-NEXT:    ret <4 x i32> [[RZ]]
65;
66  %sd = sdiv <4 x i32> %x, <i32 -1073741824, i32 -1073741824, i32 -1073741824, i32 -1073741824>
67  %sl = shl <4 x i32> %sd, <i32 30, i32 30, i32 30, i32 30>
68  %rz = add <4 x i32> %sl, %x
69  ret <4 x i32> %rz
70}
71
72define <2 x i64> @add-shl-sdiv-splat2(<2 x i64> %x) {
73; CHECK-LABEL: @add-shl-sdiv-splat2(
74; CHECK-NEXT:    [[RZ:%.*]] = srem <2 x i64> [[X:%.*]], splat (i64 32)
75; CHECK-NEXT:    ret <2 x i64> [[RZ]]
76;
77  %sd = sdiv <2 x i64> %x, <i64 -32, i64 -32>
78  %sl = shl <2 x i64> %sd, <i64 5, i64 5>
79  %rz = add <2 x i64> %sl, %x
80  ret <2 x i64> %rz
81}
82
83; One-use tests
84
85declare void @use32(i32)
86define i32 @add-shl-sdiv-i32-4-use0(i32 %x) {
87; CHECK-LABEL: @add-shl-sdiv-i32-4-use0(
88; CHECK-NEXT:    call void @use32(i32 [[X:%.*]])
89; CHECK-NEXT:    [[RZ:%.*]] = srem i32 [[X]], 16
90; CHECK-NEXT:    ret i32 [[RZ]]
91;
92  call void @use32(i32 %x)
93  %sd = sdiv i32 %x, -16
94  %sl = shl i32 %sd, 4
95  %rz = add i32 %sl, %x
96  ret i32 %rz
97}
98
99define i32 @add-shl-sdiv-i32-use1(i32 %x) {
100; CHECK-LABEL: @add-shl-sdiv-i32-use1(
101; CHECK-NEXT:    [[SD:%.*]] = sdiv i32 [[X:%.*]], -16
102; CHECK-NEXT:    call void @use32(i32 [[SD]])
103; CHECK-NEXT:    [[RZ:%.*]] = srem i32 [[X]], 16
104; CHECK-NEXT:    ret i32 [[RZ]]
105;
106  %sd = sdiv i32 %x, -16
107  call void @use32(i32 %sd)
108  %sl = shl i32 %sd, 4
109  %rz = add i32 %sl, %x
110  ret i32 %rz
111}
112
113define i32 @add-shl-sdiv-i32-use2(i32 %x) {
114; CHECK-LABEL: @add-shl-sdiv-i32-use2(
115; CHECK-NEXT:    [[SD:%.*]] = sdiv i32 [[X:%.*]], -16
116; CHECK-NEXT:    [[SL:%.*]] = shl i32 [[SD]], 4
117; CHECK-NEXT:    call void @use32(i32 [[SL]])
118; CHECK-NEXT:    [[RZ:%.*]] = srem i32 [[X]], 16
119; CHECK-NEXT:    ret i32 [[RZ]]
120;
121  %sd = sdiv i32 %x, -16
122  %sl = shl i32 %sd, 4
123  call void @use32(i32 %sl)
124  %rz = add i32 %sl, %x
125  ret i32 %rz
126}
127
128define i32 @add-shl-sdiv-i32-use3(i32 %x) {
129; CHECK-LABEL: @add-shl-sdiv-i32-use3(
130; CHECK-NEXT:    [[SD:%.*]] = sdiv i32 [[X:%.*]], -16
131; CHECK-NEXT:    call void @use32(i32 [[SD]])
132; CHECK-NEXT:    [[SL:%.*]] = shl i32 [[SD]], 4
133; CHECK-NEXT:    call void @use32(i32 [[SL]])
134; CHECK-NEXT:    [[RZ:%.*]] = srem i32 [[X]], 16
135; CHECK-NEXT:    ret i32 [[RZ]]
136;
137  %sd = sdiv i32 %x, -16
138  call void @use32(i32 %sd)
139  %sl = shl i32 %sd, 4
140  call void @use32(i32 %sl)
141  %rz = add i32 %sl, %x
142  ret i32 %rz
143}
144
145declare void @use3xi8(<3 x i8>)
146define <3 x i8> @add-shl-sdiv-use4(<3 x i8> %x) {
147; CHECK-LABEL: @add-shl-sdiv-use4(
148; CHECK-NEXT:    [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], splat (i8 -4)
149; CHECK-NEXT:    call void @use3xi8(<3 x i8> [[SD]])
150; CHECK-NEXT:    [[RZ:%.*]] = srem <3 x i8> [[X]], splat (i8 4)
151; CHECK-NEXT:    ret <3 x i8> [[RZ]]
152;
153  %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4>
154  call void @use3xi8(<3 x i8> %sd)
155  %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2>
156  %rz = add <3 x i8> %sl, %x
157  ret <3 x i8> %rz
158}
159
160; Negative
161
162define i8 @add-shl-sdiv-negative0(i8 %x) {
163; CHECK-LABEL: @add-shl-sdiv-negative0(
164; CHECK-NEXT:    [[SD:%.*]] = sdiv i8 [[X:%.*]], 4
165; CHECK-NEXT:    [[SL:%.*]] = shl nsw i8 [[SD]], 2
166; CHECK-NEXT:    [[RZ:%.*]] = add i8 [[SL]], [[X]]
167; CHECK-NEXT:    ret i8 [[RZ]]
168;
169  %sd = sdiv i8 %x, 4
170  %sl = shl i8 %sd, 2
171  %rz = add i8 %sl, %x
172  ret i8 %rz
173}
174
175define i32 @add-shl-sdiv-negative1(i32 %x) {
176; CHECK-LABEL: @add-shl-sdiv-negative1(
177; CHECK-NEXT:    [[RZ:%.*]] = sub i32 0, [[X:%.*]]
178; CHECK-NEXT:    ret i32 [[RZ]]
179;
180  %sd = sdiv i32 %x, -1
181  %sl = shl i32 %sd, 1
182  %rz = add i32 %sl, %x
183  ret i32 %rz
184}
185
186define i32 @add-shl-sdiv-negative2(i32 %x) {
187; CHECK-LABEL: @add-shl-sdiv-negative2(
188; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
189; CHECK-NEXT:    [[SL:%.*]] = select i1 [[TMP1]], i32 -2147483648, i32 0
190; CHECK-NEXT:    [[RZ:%.*]] = add i32 [[SL]], [[X]]
191; CHECK-NEXT:    ret i32 [[RZ]]
192;
193  %sd = sdiv i32 %x, -2147483648
194  %sl = shl i32 %sd, 31
195  %rz = add i32 %sl, %x
196  ret i32 %rz
197}
198
199define <3 x i8> @add-shl-sdiv-negative3(<3 x i8> %x) {
200; CHECK-LABEL: @add-shl-sdiv-negative3(
201; CHECK-NEXT:    [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], splat (i8 -5)
202; CHECK-NEXT:    [[SL:%.*]] = shl <3 x i8> [[SD]], splat (i8 2)
203; CHECK-NEXT:    [[RZ:%.*]] = add <3 x i8> [[SL]], [[X]]
204; CHECK-NEXT:    ret <3 x i8> [[RZ]]
205;
206  %sd = sdiv <3 x i8> %x, <i8 -5, i8 -5, i8 -5>
207  %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2>
208  %rz = add <3 x i8> %sl, %x
209  ret <3 x i8> %rz
210}
211
212define <2 x i64> @add-shl-sdiv-negative4(<2 x i64> %x) {
213; CHECK-LABEL: @add-shl-sdiv-negative4(
214; CHECK-NEXT:    ret <2 x i64> poison
215;
216  %sd = sdiv <2 x i64> %x, <i64 32, i64 32>
217  %sl = shl <2 x i64> %sd, <i64 -5, i64 -5>
218  %rz = add <2 x i64> %sl, %x
219  ret <2 x i64> %rz
220}
221
222; Vectors with undef values
223
224define <3 x i8> @add-shl-sdiv-3xi8-undef0(<3 x i8> %x) {
225; CHECK-LABEL: @add-shl-sdiv-3xi8-undef0(
226; CHECK-NEXT:    ret <3 x i8> poison
227;
228  %sd = sdiv <3 x i8> %x, <i8 -4, i8 undef, i8 -4>
229  %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 2>
230  %rz = add <3 x i8> %sl, %x
231  ret <3 x i8> %rz
232}
233
234define <3 x i8> @add-shl-sdiv-3xi8-undef1(<3 x i8> %x) {
235; CHECK-LABEL: @add-shl-sdiv-3xi8-undef1(
236; CHECK-NEXT:    [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], splat (i8 -4)
237; CHECK-NEXT:    [[SL:%.*]] = shl <3 x i8> [[SD]], <i8 2, i8 undef, i8 2>
238; CHECK-NEXT:    [[RZ:%.*]] = add <3 x i8> [[SL]], [[X]]
239; CHECK-NEXT:    ret <3 x i8> [[RZ]]
240;
241  %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4>
242  %sl = shl <3 x i8> %sd, <i8 2, i8 undef, i8 2>
243  %rz = add <3 x i8> %sl, %x
244  ret <3 x i8> %rz
245}
246
247; Non-splat vectors
248
249define <2 x i64> @add-shl-sdiv-nonsplat0(<2 x i64> %x) {
250; CHECK-LABEL: @add-shl-sdiv-nonsplat0(
251; CHECK-NEXT:    [[SD:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 -32, i64 -64>
252; CHECK-NEXT:    [[SL:%.*]] = shl <2 x i64> [[SD]], <i64 5, i64 6>
253; CHECK-NEXT:    [[RZ:%.*]] = add <2 x i64> [[SL]], [[X]]
254; CHECK-NEXT:    ret <2 x i64> [[RZ]]
255;
256  %sd = sdiv <2 x i64> %x, <i64 -32, i64 -64>
257  %sl = shl <2 x i64> %sd, <i64 5, i64 6>
258  %rz = add <2 x i64> %sl, %x
259  ret <2 x i64> %rz
260}
261
262define <3 x i8> @add-shl-sdiv-nonsplat1(<3 x i8> %x) {
263; CHECK-LABEL: @add-shl-sdiv-nonsplat1(
264; CHECK-NEXT:    [[SD:%.*]] = sdiv <3 x i8> [[X:%.*]], splat (i8 -4)
265; CHECK-NEXT:    [[SL:%.*]] = shl <3 x i8> [[SD]], <i8 2, i8 2, i8 3>
266; CHECK-NEXT:    [[RZ:%.*]] = add <3 x i8> [[SL]], [[X]]
267; CHECK-NEXT:    ret <3 x i8> [[RZ]]
268;
269  %sd = sdiv <3 x i8> %x, <i8 -4, i8 -4, i8 -4>
270  %sl = shl <3 x i8> %sd, <i8 2, i8 2, i8 3>
271  %rz = add <3 x i8> %sl, %x
272  ret <3 x i8> %rz
273}
274