1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4declare void @use8(i8)
5
6define i6 @add_shl_same_amount(i6 %x, i6 %y, i6 %z) {
7; CHECK-LABEL: @add_shl_same_amount(
8; CHECK-NEXT:    [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]]
9; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
10; CHECK-NEXT:    ret i6 [[DIFF]]
11;
12  %xs = shl i6 %x, %z
13  %ys = shl i6 %y, %z
14  %diff = add i6 %xs, %ys
15  ret i6 %diff
16}
17
18define <2 x i4> @add_shl_same_amount_nsw(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
19; CHECK-LABEL: @add_shl_same_amount_nsw(
20; CHECK-NEXT:    [[TMP1:%.*]] = add nsw <2 x i4> [[X:%.*]], [[Y:%.*]]
21; CHECK-NEXT:    [[DIFF:%.*]] = shl nsw <2 x i4> [[TMP1]], [[Z:%.*]]
22; CHECK-NEXT:    ret <2 x i4> [[DIFF]]
23;
24  %xs = shl nsw <2 x i4> %x, %z
25  %ys = shl nsw <2 x i4> %y, %z
26  %diff = add nsw <2 x i4> %xs, %ys
27  ret <2 x i4> %diff
28}
29
30define i64 @add_shl_same_amount_nuw(i64 %x, i64 %y, i64 %z) {
31; CHECK-LABEL: @add_shl_same_amount_nuw(
32; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i64 [[X:%.*]], [[Y:%.*]]
33; CHECK-NEXT:    [[DIFF:%.*]] = shl nuw i64 [[TMP1]], [[Z:%.*]]
34; CHECK-NEXT:    ret i64 [[DIFF]]
35;
36  %xs = shl nuw i64 %x, %z
37  %ys = shl nuw i64 %y, %z
38  %diff = add nuw i64 %xs, %ys
39  ret i64 %diff
40}
41
42define i8 @add_shl_same_amount_nsw_extra_use1(i8 %x, i8 %y, i8 %z) {
43; CHECK-LABEL: @add_shl_same_amount_nsw_extra_use1(
44; CHECK-NEXT:    [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]]
45; CHECK-NEXT:    call void @use8(i8 [[XS]])
46; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i8 [[X]], [[Y:%.*]]
47; CHECK-NEXT:    [[DIFF:%.*]] = shl nsw i8 [[TMP1]], [[Z]]
48; CHECK-NEXT:    ret i8 [[DIFF]]
49;
50  %xs = shl nsw nuw i8 %x, %z
51  call void @use8(i8 %xs)
52  %ys = shl nsw nuw i8 %y, %z
53  %diff = add nsw i8 %xs, %ys
54  ret i8 %diff
55}
56
57define i8 @add_shl_same_amount_nuw_extra_use2(i8 %x, i8 %y, i8 %z) {
58; CHECK-LABEL: @add_shl_same_amount_nuw_extra_use2(
59; CHECK-NEXT:    [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z:%.*]]
60; CHECK-NEXT:    call void @use8(i8 [[YS]])
61; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i8 [[X:%.*]], [[Y]]
62; CHECK-NEXT:    [[DIFF:%.*]] = shl nuw i8 [[TMP1]], [[Z]]
63; CHECK-NEXT:    ret i8 [[DIFF]]
64;
65  %xs = shl nuw i8 %x, %z
66  %ys = shl nsw nuw i8 %y, %z
67  call void @use8(i8 %ys)
68  %diff = add nsw nuw i8 %xs, %ys
69  ret i8 %diff
70}
71
72define i8 @add_shl_same_amount_nsw_nuw_extra_use3(i8 %x, i8 %y, i8 %z) {
73; CHECK-LABEL: @add_shl_same_amount_nsw_nuw_extra_use3(
74; CHECK-NEXT:    [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]]
75; CHECK-NEXT:    call void @use8(i8 [[XS]])
76; CHECK-NEXT:    [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z]]
77; CHECK-NEXT:    call void @use8(i8 [[YS]])
78; CHECK-NEXT:    [[DIFF:%.*]] = add nuw nsw i8 [[XS]], [[YS]]
79; CHECK-NEXT:    ret i8 [[DIFF]]
80;
81  %xs = shl nsw nuw i8 %x, %z
82  call void @use8(i8 %xs)
83  %ys = shl nsw nuw i8 %y, %z
84  call void @use8(i8 %ys)
85  %diff = add nsw nuw i8 %xs, %ys
86  ret i8 %diff
87}
88
89define i6 @add_shl_same_amount_partial_nsw1(i6 %x, i6 %y, i6 %z) {
90; CHECK-LABEL: @add_shl_same_amount_partial_nsw1(
91; CHECK-NEXT:    [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]]
92; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
93; CHECK-NEXT:    ret i6 [[DIFF]]
94;
95  %xs = shl nsw i6 %x, %z
96  %ys = shl nsw i6 %y, %z
97  %diff = add i6 %xs, %ys
98  ret i6 %diff
99}
100
101define i6 @add_shl_same_amount_partial_nsw2(i6 %x, i6 %y, i6 %z) {
102; CHECK-LABEL: @add_shl_same_amount_partial_nsw2(
103; CHECK-NEXT:    [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]]
104; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
105; CHECK-NEXT:    ret i6 [[DIFF]]
106;
107  %xs = shl i6 %x, %z
108  %ys = shl nsw i6 %y, %z
109  %diff = add nsw i6 %xs, %ys
110  ret i6 %diff
111}
112
113define i6 @add_shl_same_amount_partial_nuw1(i6 %x, i6 %y, i6 %z) {
114; CHECK-LABEL: @add_shl_same_amount_partial_nuw1(
115; CHECK-NEXT:    [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]]
116; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
117; CHECK-NEXT:    ret i6 [[DIFF]]
118;
119  %xs = shl nuw i6 %x, %z
120  %ys = shl nuw i6 %y, %z
121  %diff = add i6 %xs, %ys
122  ret i6 %diff
123}
124
125define i6 @add_shl_same_amount_partial_nuw2(i6 %x, i6 %y, i6 %z) {
126; CHECK-LABEL: @add_shl_same_amount_partial_nuw2(
127; CHECK-NEXT:    [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]]
128; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
129; CHECK-NEXT:    ret i6 [[DIFF]]
130;
131  %xs = shl nuw i6 %x, %z
132  %ys = shl i6 %y, %z
133  %diff = add nuw i6 %xs, %ys
134  ret i6 %diff
135}
136
137define i6 @sub_shl_same_amount(i6 %x, i6 %y, i6 %z) {
138; CHECK-LABEL: @sub_shl_same_amount(
139; CHECK-NEXT:    [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]]
140; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
141; CHECK-NEXT:    ret i6 [[DIFF]]
142;
143  %xs = shl i6 %x, %z
144  %ys = shl i6 %y, %z
145  %diff = sub i6 %xs, %ys
146  ret i6 %diff
147}
148
149define <2 x i4> @sub_shl_same_amount_nsw(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
150; CHECK-LABEL: @sub_shl_same_amount_nsw(
151; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw <2 x i4> [[X:%.*]], [[Y:%.*]]
152; CHECK-NEXT:    [[DIFF:%.*]] = shl nsw <2 x i4> [[TMP1]], [[Z:%.*]]
153; CHECK-NEXT:    ret <2 x i4> [[DIFF]]
154;
155  %xs = shl nsw <2 x i4> %x, %z
156  %ys = shl nsw <2 x i4> %y, %z
157  %diff = sub nsw <2 x i4> %xs, %ys
158  ret <2 x i4> %diff
159}
160
161define i64 @sub_shl_same_amount_nuw(i64 %x, i64 %y, i64 %z) {
162; CHECK-LABEL: @sub_shl_same_amount_nuw(
163; CHECK-NEXT:    [[TMP1:%.*]] = sub nuw i64 [[X:%.*]], [[Y:%.*]]
164; CHECK-NEXT:    [[DIFF:%.*]] = shl nuw i64 [[TMP1]], [[Z:%.*]]
165; CHECK-NEXT:    ret i64 [[DIFF]]
166;
167  %xs = shl nuw i64 %x, %z
168  %ys = shl nuw i64 %y, %z
169  %diff = sub nuw i64 %xs, %ys
170  ret i64 %diff
171}
172
173define i8 @sub_shl_same_amount_nsw_extra_use1(i8 %x, i8 %y, i8 %z) {
174; CHECK-LABEL: @sub_shl_same_amount_nsw_extra_use1(
175; CHECK-NEXT:    [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]]
176; CHECK-NEXT:    call void @use8(i8 [[XS]])
177; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i8 [[X]], [[Y:%.*]]
178; CHECK-NEXT:    [[DIFF:%.*]] = shl nsw i8 [[TMP1]], [[Z]]
179; CHECK-NEXT:    ret i8 [[DIFF]]
180;
181  %xs = shl nsw nuw i8 %x, %z
182  call void @use8(i8 %xs)
183  %ys = shl nsw nuw i8 %y, %z
184  %diff = sub nsw i8 %xs, %ys
185  ret i8 %diff
186}
187
188define i8 @sub_shl_same_amount_nuw_extra_use2(i8 %x, i8 %y, i8 %z) {
189; CHECK-LABEL: @sub_shl_same_amount_nuw_extra_use2(
190; CHECK-NEXT:    [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z:%.*]]
191; CHECK-NEXT:    call void @use8(i8 [[YS]])
192; CHECK-NEXT:    [[TMP1:%.*]] = sub nuw i8 [[X:%.*]], [[Y]]
193; CHECK-NEXT:    [[DIFF:%.*]] = shl nuw i8 [[TMP1]], [[Z]]
194; CHECK-NEXT:    ret i8 [[DIFF]]
195;
196  %xs = shl nuw i8 %x, %z
197  %ys = shl nsw nuw i8 %y, %z
198  call void @use8(i8 %ys)
199  %diff = sub nsw nuw i8 %xs, %ys
200  ret i8 %diff
201}
202
203define i8 @sub_shl_same_amount_nsw_nuw_extra_use3(i8 %x, i8 %y, i8 %z) {
204; CHECK-LABEL: @sub_shl_same_amount_nsw_nuw_extra_use3(
205; CHECK-NEXT:    [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]]
206; CHECK-NEXT:    call void @use8(i8 [[XS]])
207; CHECK-NEXT:    [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z]]
208; CHECK-NEXT:    call void @use8(i8 [[YS]])
209; CHECK-NEXT:    [[DIFF:%.*]] = sub nuw nsw i8 [[XS]], [[YS]]
210; CHECK-NEXT:    ret i8 [[DIFF]]
211;
212  %xs = shl nsw nuw i8 %x, %z
213  call void @use8(i8 %xs)
214  %ys = shl nsw nuw i8 %y, %z
215  call void @use8(i8 %ys)
216  %diff = sub nsw nuw i8 %xs, %ys
217  ret i8 %diff
218}
219
220define i6 @sub_shl_same_amount_partial_nsw1(i6 %x, i6 %y, i6 %z) {
221; CHECK-LABEL: @sub_shl_same_amount_partial_nsw1(
222; CHECK-NEXT:    [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]]
223; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
224; CHECK-NEXT:    ret i6 [[DIFF]]
225;
226  %xs = shl nsw i6 %x, %z
227  %ys = shl nsw i6 %y, %z
228  %diff = sub i6 %xs, %ys
229  ret i6 %diff
230}
231
232define i6 @sub_shl_same_amount_partial_nsw2(i6 %x, i6 %y, i6 %z) {
233; CHECK-LABEL: @sub_shl_same_amount_partial_nsw2(
234; CHECK-NEXT:    [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]]
235; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
236; CHECK-NEXT:    ret i6 [[DIFF]]
237;
238  %xs = shl i6 %x, %z
239  %ys = shl nsw i6 %y, %z
240  %diff = sub nsw i6 %xs, %ys
241  ret i6 %diff
242}
243
244define i6 @sub_shl_same_amount_partial_nuw1(i6 %x, i6 %y, i6 %z) {
245; CHECK-LABEL: @sub_shl_same_amount_partial_nuw1(
246; CHECK-NEXT:    [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]]
247; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
248; CHECK-NEXT:    ret i6 [[DIFF]]
249;
250  %xs = shl nuw i6 %x, %z
251  %ys = shl nuw i6 %y, %z
252  %diff = sub i6 %xs, %ys
253  ret i6 %diff
254}
255
256define i6 @sub_shl_same_amount_partial_nuw2(i6 %x, i6 %y, i6 %z) {
257; CHECK-LABEL: @sub_shl_same_amount_partial_nuw2(
258; CHECK-NEXT:    [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]]
259; CHECK-NEXT:    [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]]
260; CHECK-NEXT:    ret i6 [[DIFF]]
261;
262  %xs = shl nuw i6 %x, %z
263  %ys = shl i6 %y, %z
264  %diff = sub nuw i6 %xs, %ys
265  ret i6 %diff
266}
267
268