xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/ssub-with-overflow.ll (revision 61bb2e4ea82fc5499a271d70d4537383d1942208)
1*61bb2e4eSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2*61bb2e4eSFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3*61bb2e4eSFlorian Hahn
4*61bb2e4eSFlorian Hahndeclare { i8, i1 } @llvm.ssub.with.overflow.i8(i8, i8)
5*61bb2e4eSFlorian Hahn
6*61bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_or_conds(i8 %a, i8 %b) {
7*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_or_conds(
8*61bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
9*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sle i8 [[B:%.*]], [[A:%.*]]
10*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[A]], 0
11*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]]
12*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
13*61bb2e4eSFlorian Hahn; CHECK:       math:
14*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
15*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
16*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
17*61bb2e4eSFlorian Hahn; CHECK:       exit.ok:
18*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
19*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
20*61bb2e4eSFlorian Hahn; CHECK:       exit.fail:
21*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
22*61bb2e4eSFlorian Hahn;
23*61bb2e4eSFlorian Hahnentry:
24*61bb2e4eSFlorian Hahn  %c.1 = icmp sle i8 %b, %a
25*61bb2e4eSFlorian Hahn  %c.2 = icmp slt i8 %a, 0
26*61bb2e4eSFlorian Hahn  %or.cond = or i1 %c.2, %c.1
27*61bb2e4eSFlorian Hahn  br i1 %or.cond, label %exit.fail, label %math
28*61bb2e4eSFlorian Hahn
29*61bb2e4eSFlorian Hahnmath:
30*61bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
31*61bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
32*61bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
33*61bb2e4eSFlorian Hahn
34*61bb2e4eSFlorian Hahnexit.ok:
35*61bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
36*61bb2e4eSFlorian Hahn  ret i8 %res
37*61bb2e4eSFlorian Hahn
38*61bb2e4eSFlorian Hahnexit.fail:
39*61bb2e4eSFlorian Hahn  ret i8 0
40*61bb2e4eSFlorian Hahn}
41*61bb2e4eSFlorian Hahn
42*61bb2e4eSFlorian Hahndefine i8 @ssub_no_overflow_due_to_and_conds(i8 %a, i8 %b) {
43*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_no_overflow_due_to_and_conds(
44*61bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
45*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
46*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
47*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
48*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
49*61bb2e4eSFlorian Hahn; CHECK:       math:
50*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
51*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
52*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
53*61bb2e4eSFlorian Hahn; CHECK:       exit.ok:
54*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
55*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
56*61bb2e4eSFlorian Hahn; CHECK:       exit.fail:
57*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
58*61bb2e4eSFlorian Hahn;
59*61bb2e4eSFlorian Hahnentry:
60*61bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %b, %a
61*61bb2e4eSFlorian Hahn  %c.2 = icmp sge i8 %a, 0
62*61bb2e4eSFlorian Hahn  %and = and i1 %c.2, %c.1
63*61bb2e4eSFlorian Hahn  br i1 %and, label %math, label %exit.fail
64*61bb2e4eSFlorian Hahn
65*61bb2e4eSFlorian Hahnmath:
66*61bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
67*61bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
68*61bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
69*61bb2e4eSFlorian Hahn
70*61bb2e4eSFlorian Hahnexit.ok:
71*61bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
72*61bb2e4eSFlorian Hahn  ret i8 %res
73*61bb2e4eSFlorian Hahn
74*61bb2e4eSFlorian Hahnexit.fail:
75*61bb2e4eSFlorian Hahn  ret i8 0
76*61bb2e4eSFlorian Hahn}
77*61bb2e4eSFlorian Hahn
78*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow1(i8 %a, i8 %b) {
79*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow1(
80*61bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
81*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
82*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
83*61bb2e4eSFlorian Hahn; CHECK:       math:
84*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
85*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
86*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
87*61bb2e4eSFlorian Hahn; CHECK:       exit.ok:
88*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
89*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
90*61bb2e4eSFlorian Hahn; CHECK:       exit.fail:
91*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
92*61bb2e4eSFlorian Hahn;
93*61bb2e4eSFlorian Hahnentry:
94*61bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %b, %a
95*61bb2e4eSFlorian Hahn  br i1 %c.1, label %math, label %exit.fail
96*61bb2e4eSFlorian Hahn
97*61bb2e4eSFlorian Hahnmath:
98*61bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
99*61bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
100*61bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
101*61bb2e4eSFlorian Hahn
102*61bb2e4eSFlorian Hahnexit.ok:
103*61bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
104*61bb2e4eSFlorian Hahn  ret i8 %res
105*61bb2e4eSFlorian Hahn
106*61bb2e4eSFlorian Hahnexit.fail:
107*61bb2e4eSFlorian Hahn  ret i8 0
108*61bb2e4eSFlorian Hahn}
109*61bb2e4eSFlorian Hahn
110*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow2(i8 %a, i8 %b) {
111*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow2(
112*61bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
113*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[A:%.*]], 0
114*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
115*61bb2e4eSFlorian Hahn; CHECK:       math:
116*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B:%.*]], i8 [[A]])
117*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
118*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
119*61bb2e4eSFlorian Hahn; CHECK:       exit.ok:
120*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
121*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
122*61bb2e4eSFlorian Hahn; CHECK:       exit.fail:
123*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
124*61bb2e4eSFlorian Hahn;
125*61bb2e4eSFlorian Hahnentry:
126*61bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %a, 0
127*61bb2e4eSFlorian Hahn  br i1 %c.1, label %math, label %exit.fail
128*61bb2e4eSFlorian Hahn
129*61bb2e4eSFlorian Hahnmath:
130*61bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
131*61bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
132*61bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
133*61bb2e4eSFlorian Hahn
134*61bb2e4eSFlorian Hahnexit.ok:
135*61bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
136*61bb2e4eSFlorian Hahn  ret i8 %res
137*61bb2e4eSFlorian Hahn
138*61bb2e4eSFlorian Hahnexit.fail:
139*61bb2e4eSFlorian Hahn  ret i8 0
140*61bb2e4eSFlorian Hahn}
141*61bb2e4eSFlorian Hahn
142*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow3(i8 %a, i8 %b) {
143*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow3(
144*61bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
145*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[A:%.*]]
146*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], -1
147*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
148*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
149*61bb2e4eSFlorian Hahn; CHECK:       math:
150*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
151*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
152*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
153*61bb2e4eSFlorian Hahn; CHECK:       exit.ok:
154*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
155*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
156*61bb2e4eSFlorian Hahn; CHECK:       exit.fail:
157*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
158*61bb2e4eSFlorian Hahn;
159*61bb2e4eSFlorian Hahnentry:
160*61bb2e4eSFlorian Hahn  %c.1 = icmp sge i8 %b, %a
161*61bb2e4eSFlorian Hahn  %c.2 = icmp sge i8 %a, -1
162*61bb2e4eSFlorian Hahn  %and = and i1 %c.2, %c.1
163*61bb2e4eSFlorian Hahn  br i1 %and, label %math, label %exit.fail
164*61bb2e4eSFlorian Hahn
165*61bb2e4eSFlorian Hahnmath:
166*61bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
167*61bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
168*61bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
169*61bb2e4eSFlorian Hahn
170*61bb2e4eSFlorian Hahnexit.ok:
171*61bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
172*61bb2e4eSFlorian Hahn  ret i8 %res
173*61bb2e4eSFlorian Hahn
174*61bb2e4eSFlorian Hahnexit.fail:
175*61bb2e4eSFlorian Hahn  ret i8 0
176*61bb2e4eSFlorian Hahn}
177*61bb2e4eSFlorian Hahn
178*61bb2e4eSFlorian Hahndefine i8 @ssub_may_overflow4(i8 %a, i8 %b) {
179*61bb2e4eSFlorian Hahn; CHECK-LABEL: @ssub_may_overflow4(
180*61bb2e4eSFlorian Hahn; CHECK-NEXT:  entry:
181*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]]
182*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
183*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
184*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
185*61bb2e4eSFlorian Hahn; CHECK:       math:
186*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
187*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
188*61bb2e4eSFlorian Hahn; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
189*61bb2e4eSFlorian Hahn; CHECK:       exit.ok:
190*61bb2e4eSFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
191*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 [[RES]]
192*61bb2e4eSFlorian Hahn; CHECK:       exit.fail:
193*61bb2e4eSFlorian Hahn; CHECK-NEXT:    ret i8 0
194*61bb2e4eSFlorian Hahn;
195*61bb2e4eSFlorian Hahnentry:
196*61bb2e4eSFlorian Hahn  %c.1 = icmp uge i8 %b, %a
197*61bb2e4eSFlorian Hahn  %c.2 = icmp sge i8 %a, 0
198*61bb2e4eSFlorian Hahn  %and = and i1 %c.2, %c.1
199*61bb2e4eSFlorian Hahn  br i1 %and, label %math, label %exit.fail
200*61bb2e4eSFlorian Hahn
201*61bb2e4eSFlorian Hahnmath:
202*61bb2e4eSFlorian Hahn  %op = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %b, i8 %a)
203*61bb2e4eSFlorian Hahn  %status = extractvalue { i8, i1 } %op, 1
204*61bb2e4eSFlorian Hahn  br i1 %status, label %exit.fail, label %exit.ok
205*61bb2e4eSFlorian Hahn
206*61bb2e4eSFlorian Hahnexit.ok:
207*61bb2e4eSFlorian Hahn  %res = extractvalue { i8, i1 } %op, 0
208*61bb2e4eSFlorian Hahn  ret i8 %res
209*61bb2e4eSFlorian Hahn
210*61bb2e4eSFlorian Hahnexit.fail:
211*61bb2e4eSFlorian Hahn  ret i8 0
212*61bb2e4eSFlorian Hahn}
213