Skip to content

Commit 955f125

Browse files
committed
[instcombine] Fold overflow check using overflow intrinsic to comparison
This follows up to D104665 (which added umulo handling alongside the existing uaddo case), and generalizes for the remaining overflow intrinsics. I went to add analogous handling to LVI, and discovered that LVI already had a more general implementation. Instead, we can port was LVI does to instcombine. (For context, LVI uses makeExactNoWrapRegion to constrain the value 'x' in blocks reached after a branch on the condition `op.with.overflow(x, C).overflow`.) Differential Revision: https://reviews.llvm.org/D104932
1 parent bc7cc20 commit 955f125

File tree

5 files changed

+56
-80
lines changed

5 files changed

+56
-80
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,33 +3089,32 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
30893089
assert(*EV.idx_begin() == 1 &&
30903090
"unexpected extract index for overflow inst");
30913091

3092-
// If the normal result of the computation is dead, and the RHS is a
3093-
// constant, we can transform this into a range comparison for many cases.
3094-
// TODO: We can generalize these for non-constant rhs when the newly
3095-
// formed expressions are known to simplify. Constants are merely one
3096-
// such case.
3097-
// TODO: Handle vector splats.
3098-
switch (WO->getIntrinsicID()) {
3099-
default:
3100-
break;
3101-
case Intrinsic::uadd_with_overflow:
3102-
// overflow = uadd a, -4 --> overflow = icmp ugt a, 3
3103-
if (ConstantInt *CI = dyn_cast<ConstantInt>(WO->getRHS()))
3104-
return new ICmpInst(ICmpInst::ICMP_UGT, WO->getLHS(),
3105-
ConstantExpr::getNot(CI));
3106-
break;
3107-
case Intrinsic::umul_with_overflow:
3108-
// overflow for umul a, C --> a > UINT_MAX udiv C
3109-
// (unless C == 0, in which case no overflow ever occurs)
3110-
if (ConstantInt *CI = dyn_cast<ConstantInt>(WO->getRHS())) {
3111-
assert(!CI->isZero() && "handled by instruction simplify");
3112-
auto UMax = APInt::getMaxValue(CI->getType()->getBitWidth());
3113-
auto *Op =
3114-
ConstantExpr::getUDiv(ConstantInt::get(CI->getType(), UMax), CI);
3115-
return new ICmpInst(ICmpInst::ICMP_UGT, WO->getLHS(), Op);
3092+
// If only the overflow result is used, and the right hand side is a
3093+
// constant (or constant splat), we can remove the intrinsic by directly
3094+
// checking for overflow.
3095+
const APInt *C;
3096+
if (match(WO->getRHS(), m_APInt(C))) {
3097+
// Compute the no-wrap range [X,Y) for LHS given RHS=C, then
3098+
// check for the inverted range using range offset trick (i.e.
3099+
// use a subtract to shift the range to bottom of either the
3100+
// signed or unsigned domain and then use a single compare to
3101+
// check range membership).
3102+
ConstantRange NWR =
3103+
ConstantRange::makeExactNoWrapRegion(WO->getBinaryOp(), *C,
3104+
WO->getNoWrapKind());
3105+
APInt Min = WO->isSigned() ? NWR.getSignedMin() : NWR.getUnsignedMin();
3106+
NWR = NWR.subtract(Min);
3107+
3108+
CmpInst::Predicate Pred;
3109+
APInt NewRHSC;
3110+
if (NWR.getEquivalentICmp(Pred, NewRHSC)) {
3111+
auto *OpTy = WO->getRHS()->getType();
3112+
auto *NewLHS = Builder.CreateSub(WO->getLHS(),
3113+
ConstantInt::get(OpTy, Min));
3114+
return new ICmpInst(ICmpInst::getInversePredicate(Pred), NewLHS,
3115+
ConstantInt::get(OpTy, NewRHSC));
31163116
}
3117-
break;
3118-
};
3117+
}
31193118
}
31203119
}
31213120
if (LoadInst *L = dyn_cast<LoadInst>(Agg))

llvm/test/Transforms/InstCombine/saddo.ll

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ define i1 @test_constant0(i8 %a) {
2626

2727
define i1 @test_constant1(i8 %a) {
2828
; CHECK-LABEL: @test_constant1(
29-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 1)
30-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
29+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 127
3130
; CHECK-NEXT: ret i1 [[OVERFLOW]]
3231
;
3332
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 1)
@@ -37,8 +36,7 @@ define i1 @test_constant1(i8 %a) {
3736

3837
define i1 @test_constant2(i8 %a) {
3938
; CHECK-LABEL: @test_constant2(
40-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 2)
41-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
39+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 125
4240
; CHECK-NEXT: ret i1 [[OVERFLOW]]
4341
;
4442
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 2)
@@ -48,8 +46,7 @@ define i1 @test_constant2(i8 %a) {
4846

4947
define i1 @test_constant3(i8 %a) {
5048
; CHECK-LABEL: @test_constant3(
51-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 3)
52-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
49+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 124
5350
; CHECK-NEXT: ret i1 [[OVERFLOW]]
5451
;
5552
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 3)
@@ -59,8 +56,7 @@ define i1 @test_constant3(i8 %a) {
5956

6057
define i1 @test_constant4(i8 %a) {
6158
; CHECK-LABEL: @test_constant4(
62-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 4)
63-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
59+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 123
6460
; CHECK-NEXT: ret i1 [[OVERFLOW]]
6561
;
6662
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 4)
@@ -70,8 +66,7 @@ define i1 @test_constant4(i8 %a) {
7066

7167
define i1 @test_constant127(i8 %a) {
7268
; CHECK-LABEL: @test_constant127(
73-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 127)
74-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
69+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], 0
7570
; CHECK-NEXT: ret i1 [[OVERFLOW]]
7671
;
7772
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 127)
@@ -81,8 +76,7 @@ define i1 @test_constant127(i8 %a) {
8176

8277
define i1 @test_constant128(i8 %a) {
8378
; CHECK-LABEL: @test_constant128(
84-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -128)
85-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
79+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], 0
8680
; CHECK-NEXT: ret i1 [[OVERFLOW]]
8781
;
8882
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 128)
@@ -92,8 +86,7 @@ define i1 @test_constant128(i8 %a) {
9286

9387
define i1 @test_constant255(i8 %a) {
9488
; CHECK-LABEL: @test_constant255(
95-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -1)
96-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
89+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -128
9790
; CHECK-NEXT: ret i1 [[OVERFLOW]]
9891
;
9992
%res = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 255)

llvm/test/Transforms/InstCombine/smulo.ll

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ define i1 @test_constant1(i8 %a) {
3535

3636
define i1 @test_constant2(i8 %a) {
3737
; CHECK-LABEL: @test_constant2(
38-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 2)
39-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
38+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 64
39+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[TMP1]], 0
4040
; CHECK-NEXT: ret i1 [[OVERFLOW]]
4141
;
4242
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 2)
@@ -46,8 +46,8 @@ define i1 @test_constant2(i8 %a) {
4646

4747
define i1 @test_constant3(i8 %a) {
4848
; CHECK-LABEL: @test_constant3(
49-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 3)
50-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
49+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 42
50+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 84
5151
; CHECK-NEXT: ret i1 [[OVERFLOW]]
5252
;
5353
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 3)
@@ -57,8 +57,8 @@ define i1 @test_constant3(i8 %a) {
5757

5858
define i1 @test_constant4(i8 %a) {
5959
; CHECK-LABEL: @test_constant4(
60-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 4)
61-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
60+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 32
61+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 63
6262
; CHECK-NEXT: ret i1 [[OVERFLOW]]
6363
;
6464
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 4)
@@ -69,8 +69,8 @@ define i1 @test_constant4(i8 %a) {
6969

7070
define i1 @test_constant127(i8 %a) {
7171
; CHECK-LABEL: @test_constant127(
72-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 127)
73-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
72+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 1
73+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 2
7474
; CHECK-NEXT: ret i1 [[OVERFLOW]]
7575
;
7676
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 127)
@@ -80,8 +80,7 @@ define i1 @test_constant127(i8 %a) {
8080

8181
define i1 @test_constant128(i8 %a) {
8282
; CHECK-LABEL: @test_constant128(
83-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 -128)
84-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
83+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[A:%.*]], 1
8584
; CHECK-NEXT: ret i1 [[OVERFLOW]]
8685
;
8786
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 128)
@@ -91,8 +90,7 @@ define i1 @test_constant128(i8 %a) {
9190

9291
define i1 @test_constant255(i8 %a) {
9392
; CHECK-LABEL: @test_constant255(
94-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[A:%.*]], i8 -1)
95-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
93+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -128
9694
; CHECK-NEXT: ret i1 [[OVERFLOW]]
9795
;
9896
%res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 255)

llvm/test/Transforms/InstCombine/ssubo.ll

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ define i1 @test_constant0(i8 %a) {
2626

2727
define i1 @test_constant1(i8 %a) {
2828
; CHECK-LABEL: @test_constant1(
29-
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -1)
30-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
29+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], -128
3130
; CHECK-NEXT: ret i1 [[OVERFLOW]]
3231
;
3332
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 1)
@@ -37,8 +36,7 @@ define i1 @test_constant1(i8 %a) {
3736

3837
define i1 @test_constant2(i8 %a) {
3938
; CHECK-LABEL: @test_constant2(
40-
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -2)
41-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
39+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -126
4240
; CHECK-NEXT: ret i1 [[OVERFLOW]]
4341
;
4442
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 2)
@@ -48,8 +46,7 @@ define i1 @test_constant2(i8 %a) {
4846

4947
define i1 @test_constant3(i8 %a) {
5048
; CHECK-LABEL: @test_constant3(
51-
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -3)
52-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
49+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -125
5350
; CHECK-NEXT: ret i1 [[OVERFLOW]]
5451
;
5552
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 3)
@@ -59,8 +56,7 @@ define i1 @test_constant3(i8 %a) {
5956

6057
define i1 @test_constant4(i8 %a) {
6158
; CHECK-LABEL: @test_constant4(
62-
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -4)
63-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
59+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -124
6460
; CHECK-NEXT: ret i1 [[OVERFLOW]]
6561
;
6662
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 4)
@@ -71,8 +67,7 @@ define i1 @test_constant4(i8 %a) {
7167

7268
define i1 @test_constant127(i8 %a) {
7369
; CHECK-LABEL: @test_constant127(
74-
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 -127)
75-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
70+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp slt i8 [[A:%.*]], -1
7671
; CHECK-NEXT: ret i1 [[OVERFLOW]]
7772
;
7873
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 127)
@@ -82,8 +77,7 @@ define i1 @test_constant127(i8 %a) {
8277

8378
define i1 @test_constant128(i8 %a) {
8479
; CHECK-LABEL: @test_constant128(
85-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[A:%.*]], i8 -128)
86-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
80+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], -1
8781
; CHECK-NEXT: ret i1 [[OVERFLOW]]
8882
;
8983
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 128)
@@ -93,8 +87,7 @@ define i1 @test_constant128(i8 %a) {
9387

9488
define i1 @test_constant255(i8 %a) {
9589
; CHECK-LABEL: @test_constant255(
96-
; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A:%.*]], i8 1)
97-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1
90+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 127
9891
; CHECK-NEXT: ret i1 [[OVERFLOW]]
9992
;
10093
%res = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 255)

llvm/test/Transforms/InstCombine/usubo.ll

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ define i1 @test_constant0(i8 %a) {
2626

2727
define i1 @test_constant1(i8 %a) {
2828
; CHECK-LABEL: @test_constant1(
29-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 1)
30-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
29+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp eq i8 [[A:%.*]], 0
3130
; CHECK-NEXT: ret i1 [[OVERFLOW]]
3231
;
3332
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 1)
@@ -37,8 +36,7 @@ define i1 @test_constant1(i8 %a) {
3736

3837
define i1 @test_constant2(i8 %a) {
3938
; CHECK-LABEL: @test_constant2(
40-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 2)
41-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
39+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 2
4240
; CHECK-NEXT: ret i1 [[OVERFLOW]]
4341
;
4442
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 2)
@@ -48,8 +46,7 @@ define i1 @test_constant2(i8 %a) {
4846

4947
define i1 @test_constant3(i8 %a) {
5048
; CHECK-LABEL: @test_constant3(
51-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 3)
52-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
49+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 3
5350
; CHECK-NEXT: ret i1 [[OVERFLOW]]
5451
;
5552
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 3)
@@ -59,8 +56,7 @@ define i1 @test_constant3(i8 %a) {
5956

6057
define i1 @test_constant4(i8 %a) {
6158
; CHECK-LABEL: @test_constant4(
62-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 4)
63-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
59+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 4
6460
; CHECK-NEXT: ret i1 [[OVERFLOW]]
6561
;
6662
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 4)
@@ -71,8 +67,7 @@ define i1 @test_constant4(i8 %a) {
7167

7268
define i1 @test_constant127(i8 %a) {
7369
; CHECK-LABEL: @test_constant127(
74-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 127)
75-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
70+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[A:%.*]], 127
7671
; CHECK-NEXT: ret i1 [[OVERFLOW]]
7772
;
7873
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 127)
@@ -82,8 +77,7 @@ define i1 @test_constant127(i8 %a) {
8277

8378
define i1 @test_constant128(i8 %a) {
8479
; CHECK-LABEL: @test_constant128(
85-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 -128)
86-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
80+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp sgt i8 [[A:%.*]], -1
8781
; CHECK-NEXT: ret i1 [[OVERFLOW]]
8882
;
8983
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 128)
@@ -93,8 +87,7 @@ define i1 @test_constant128(i8 %a) {
9387

9488
define i1 @test_constant255(i8 %a) {
9589
; CHECK-LABEL: @test_constant255(
96-
; CHECK-NEXT: [[RES:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[A:%.*]], i8 -1)
97-
; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i8, i1 } [[RES]], 1
90+
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ne i8 [[A:%.*]], -1
9891
; CHECK-NEXT: ret i1 [[OVERFLOW]]
9992
;
10093
%res = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 255)

0 commit comments

Comments
 (0)