1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5
6; %a is negative, %b is positive
7define i16 @oppositesign(i16 %x, i16 %y) {
8; CHECK-LABEL: @oppositesign(
9; CHECK-NEXT:    [[A:%.*]] = or i16 [[X:%.*]], -32768
10; CHECK-NEXT:    [[B:%.*]] = and i16 [[Y:%.*]], 32767
11; CHECK-NEXT:    [[C:%.*]] = add nsw i16 [[A]], [[B]]
12; CHECK-NEXT:    ret i16 [[C]]
13;
14  %a = or i16 %x, 32768
15  %b = and i16 %y, 32767
16  %c = add i16 %a, %b
17  ret i16 %c
18}
19
20define i16 @zero_sign_bit(i16 %a) {
21; CHECK-LABEL: @zero_sign_bit(
22; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[A:%.*]], 32767
23; CHECK-NEXT:    [[TMP2:%.*]] = add nuw i16 [[TMP1]], 512
24; CHECK-NEXT:    ret i16 [[TMP2]]
25;
26  %1 = and i16 %a, 32767
27  %2 = add i16 %1, 512
28  ret i16 %2
29}
30
31define i16 @zero_sign_bit2(i16 %a, i16 %b) {
32; CHECK-LABEL: @zero_sign_bit2(
33; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[A:%.*]], 32767
34; CHECK-NEXT:    [[TMP2:%.*]] = and i16 [[B:%.*]], 32767
35; CHECK-NEXT:    [[TMP3:%.*]] = add nuw i16 [[TMP1]], [[TMP2]]
36; CHECK-NEXT:    ret i16 [[TMP3]]
37;
38  %1 = and i16 %a, 32767
39  %2 = and i16 %b, 32767
40  %3 = add i16 %1, %2
41  ret i16 %3
42}
43
44declare i16 @bounded(i16 %input);
45declare i32 @__gxx_personality_v0(...);
46!0 = !{i16 0, i16 32768} ; [0, 32767]
47!1 = !{i16 0, i16 32769} ; [0, 32768]
48
49define i16 @add_bounded_values(i16 %a, i16 %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
50; CHECK-LABEL: @add_bounded_values(
51; CHECK-NEXT:  entry:
52; CHECK-NEXT:    [[C:%.*]] = call i16 @bounded(i16 [[A:%.*]]), !range !0
53; CHECK-NEXT:    [[D:%.*]] = invoke i16 @bounded(i16 [[B:%.*]])
54; CHECK-NEXT:    to label [[CONT:%.*]] unwind label [[LPAD:%.*]], !range !0
55; CHECK:       cont:
56; CHECK-NEXT:    [[E:%.*]] = add nuw i16 [[C]], [[D]]
57; CHECK-NEXT:    ret i16 [[E]]
58; CHECK:       lpad:
59; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
60; CHECK-NEXT:    filter [0 x i8*] zeroinitializer
61; CHECK-NEXT:    ret i16 42
62;
63entry:
64  %c = call i16 @bounded(i16 %a), !range !0
65  %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0
66cont:
67; %c and %d are in [0, 32767]. Therefore, %c + %d doesn't unsigned overflow.
68  %e = add i16 %c, %d
69  ret i16 %e
70lpad:
71  %0 = landingpad { i8*, i32 }
72  filter [0 x i8*] zeroinitializer
73  ret i16 42
74}
75
76define i16 @add_bounded_values_2(i16 %a, i16 %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
77; CHECK-LABEL: @add_bounded_values_2(
78; CHECK-NEXT:  entry:
79; CHECK-NEXT:    [[C:%.*]] = call i16 @bounded(i16 [[A:%.*]]), !range !1
80; CHECK-NEXT:    [[D:%.*]] = invoke i16 @bounded(i16 [[B:%.*]])
81; CHECK-NEXT:    to label [[CONT:%.*]] unwind label [[LPAD:%.*]], !range !1
82; CHECK:       cont:
83; CHECK-NEXT:    [[E:%.*]] = add i16 [[C]], [[D]]
84; CHECK-NEXT:    ret i16 [[E]]
85; CHECK:       lpad:
86; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
87; CHECK-NEXT:    filter [0 x i8*] zeroinitializer
88; CHECK-NEXT:    ret i16 42
89;
90entry:
91  %c = call i16 @bounded(i16 %a), !range !1
92  %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1
93cont:
94; Similar to add_bounded_values, but %c and %d are in [0, 32768]. Therefore,
95; %c + %d may unsigned overflow and we cannot add NUW.
96  %e = add i16 %c, %d
97  ret i16 %e
98lpad:
99  %0 = landingpad { i8*, i32 }
100  filter [0 x i8*] zeroinitializer
101  ret i16 42
102}
103
104; %a has at most one bit set
105; %b has a 0 bit other than the sign bit
106define i16 @ripple_nsw1(i16 %x, i16 %y) {
107; CHECK-LABEL: @ripple_nsw1(
108; CHECK-NEXT:    [[A:%.*]] = and i16 [[Y:%.*]], 1
109; CHECK-NEXT:    [[B:%.*]] = and i16 [[X:%.*]], -16385
110; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i16 [[A]], [[B]]
111; CHECK-NEXT:    ret i16 [[C]]
112;
113  %a = and i16 %y, 1
114  %b = and i16 %x, 49151
115  %c = add i16 %a, %b
116  ret i16 %c
117}
118
119; Like the previous test, but flip %a and %b
120define i16 @ripple_nsw2(i16 %x, i16 %y) {
121; CHECK-LABEL: @ripple_nsw2(
122; CHECK-NEXT:    [[A:%.*]] = and i16 [[Y:%.*]], 1
123; CHECK-NEXT:    [[B:%.*]] = and i16 [[X:%.*]], -16385
124; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i16 [[B]], [[A]]
125; CHECK-NEXT:    ret i16 [[C]]
126;
127  %a = and i16 %y, 1
128  %b = and i16 %x, 49151
129  %c = add i16 %b, %a
130  ret i16 %c
131}
132
133define i16 @ripple_nsw3(i16 %x, i16 %y) {
134; CHECK-LABEL: @ripple_nsw3(
135; CHECK-NEXT:    [[A:%.*]] = and i16 [[Y:%.*]], -21845
136; CHECK-NEXT:    [[B:%.*]] = and i16 [[X:%.*]], 21843
137; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i16 [[A]], [[B]]
138; CHECK-NEXT:    ret i16 [[C]]
139;
140  %a = and i16 %y, 43691
141  %b = and i16 %x, 21843
142  %c = add i16 %a, %b
143  ret i16 %c
144}
145
146; Like the previous test, but flip %a and %b
147define i16 @ripple_nsw4(i16 %x, i16 %y) {
148; CHECK-LABEL: @ripple_nsw4(
149; CHECK-NEXT:    [[A:%.*]] = and i16 [[Y:%.*]], -21845
150; CHECK-NEXT:    [[B:%.*]] = and i16 [[X:%.*]], 21843
151; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i16 [[B]], [[A]]
152; CHECK-NEXT:    ret i16 [[C]]
153;
154  %a = and i16 %y, 43691
155  %b = and i16 %x, 21843
156  %c = add i16 %b, %a
157  ret i16 %c
158}
159
160define i16 @ripple_nsw5(i16 %x, i16 %y) {
161; CHECK-LABEL: @ripple_nsw5(
162; CHECK-NEXT:    [[A:%.*]] = or i16 [[Y:%.*]], -21845
163; CHECK-NEXT:    [[B:%.*]] = or i16 [[X:%.*]], -10923
164; CHECK-NEXT:    [[C:%.*]] = add nsw i16 [[A]], [[B]]
165; CHECK-NEXT:    ret i16 [[C]]
166;
167  %a = or i16 %y, 43691
168  %b = or i16 %x, 54613
169  %c = add i16 %a, %b
170  ret i16 %c
171}
172
173; Like the previous test, but flip %a and %b
174define i16 @ripple_nsw6(i16 %x, i16 %y) {
175; CHECK-LABEL: @ripple_nsw6(
176; CHECK-NEXT:    [[A:%.*]] = or i16 [[Y:%.*]], -21845
177; CHECK-NEXT:    [[B:%.*]] = or i16 [[X:%.*]], -10923
178; CHECK-NEXT:    [[C:%.*]] = add nsw i16 [[B]], [[A]]
179; CHECK-NEXT:    ret i16 [[C]]
180;
181  %a = or i16 %y, 43691
182  %b = or i16 %x, 54613
183  %c = add i16 %b, %a
184  ret i16 %c
185}
186
187; We know nothing about %x
188define i32 @ripple_no_nsw1(i32 %x, i32 %y) {
189; CHECK-LABEL: @ripple_no_nsw1(
190; CHECK-NEXT:    [[A:%.*]] = and i32 [[Y:%.*]], 1
191; CHECK-NEXT:    [[B:%.*]] = add i32 [[A]], [[X:%.*]]
192; CHECK-NEXT:    ret i32 [[B]]
193;
194  %a = and i32 %y, 1
195  %b = add i32 %a, %x
196  ret i32 %b
197}
198
199; %a has at most one bit set
200; %b has a 0 bit, but it is the sign bit
201define i16 @ripple_no_nsw2(i16 %x, i16 %y) {
202; CHECK-LABEL: @ripple_no_nsw2(
203; CHECK-NEXT:    [[A:%.*]] = and i16 [[Y:%.*]], 1
204; CHECK-NEXT:    [[B:%.*]] = and i16 [[X:%.*]], 32767
205; CHECK-NEXT:    [[C:%.*]] = add nuw i16 [[A]], [[B]]
206; CHECK-NEXT:    ret i16 [[C]]
207;
208  %a = and i16 %y, 1
209  %b = and i16 %x, 32767
210  %c = add i16 %a, %b
211  ret i16 %c
212}
213
214define i16 @ripple_no_nsw3(i16 %x, i16 %y) {
215; CHECK-LABEL: @ripple_no_nsw3(
216; CHECK-NEXT:    [[A:%.*]] = and i16 [[Y:%.*]], -21845
217; CHECK-NEXT:    [[B:%.*]] = and i16 [[X:%.*]], 21845
218; CHECK-NEXT:    [[C:%.*]] = add i16 [[A]], [[B]]
219; CHECK-NEXT:    ret i16 [[C]]
220;
221  %a = and i16 %y, 43691
222  %b = and i16 %x, 21845
223  %c = add i16 %a, %b
224  ret i16 %c
225}
226
227; Like the previous test, but flip %a and %b
228define i16 @ripple_no_nsw4(i16 %x, i16 %y) {
229; CHECK-LABEL: @ripple_no_nsw4(
230; CHECK-NEXT:    [[A:%.*]] = and i16 [[Y:%.*]], -21845
231; CHECK-NEXT:    [[B:%.*]] = and i16 [[X:%.*]], 21845
232; CHECK-NEXT:    [[C:%.*]] = add i16 [[B]], [[A]]
233; CHECK-NEXT:    ret i16 [[C]]
234;
235  %a = and i16 %y, 43691
236  %b = and i16 %x, 21845
237  %c = add i16 %b, %a
238  ret i16 %c
239}
240
241define i16 @ripple_no_nsw5(i16 %x, i16 %y) {
242; CHECK-LABEL: @ripple_no_nsw5(
243; CHECK-NEXT:    [[A:%.*]] = or i16 [[Y:%.*]], -21847
244; CHECK-NEXT:    [[B:%.*]] = or i16 [[X:%.*]], -10923
245; CHECK-NEXT:    [[C:%.*]] = add i16 [[A]], [[B]]
246; CHECK-NEXT:    ret i16 [[C]]
247;
248  %a = or i16 %y, 43689
249  %b = or i16 %x, 54613
250  %c = add i16 %a, %b
251  ret i16 %c
252}
253
254; Like the previous test, but flip %a and %b
255define i16 @ripple_no_nsw6(i16 %x, i16 %y) {
256; CHECK-LABEL: @ripple_no_nsw6(
257; CHECK-NEXT:    [[A:%.*]] = or i16 [[Y:%.*]], -21847
258; CHECK-NEXT:    [[B:%.*]] = or i16 [[X:%.*]], -10923
259; CHECK-NEXT:    [[C:%.*]] = add i16 [[B]], [[A]]
260; CHECK-NEXT:    ret i16 [[C]]
261;
262  %a = or i16 %y, 43689
263  %b = or i16 %x, 54613
264  %c = add i16 %b, %a
265  ret i16 %c
266}
267