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