[llvm] [ConstraintElim] Fold sadd.with.overflow with a constant op. (PR #223239)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 07:45:59 PDT 2026
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/223239
>From fc2ce067df6534634e5facfd63d3cdfc259c86e9 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 9 Sep 2026 12:32:04 +0100
Subject: [PATCH 1/2] [ConstraintElim] Add tests for folding sadd.with.overflow
(NFC).
Pre-commit tests for folding sadd.with.overflow with a constant addend via the
constraint solver: the SMIN/SMAX boundary constants, off-by-one bounds that must
not fold, a bound only known in the unsigned system, a variable addend and an
escaping aggregate.
---
.../sadd-with-overflow.ll | 226 ++++++++++++++++++
1 file changed, 226 insertions(+)
diff --git a/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll b/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll
index 7dbbf29b5a9d3c..3f559e0cda8259 100644
--- a/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll
+++ b/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll
@@ -2,6 +2,7 @@
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
declare void @use(i1)
+declare void @use.agg({ i8, i1 })
; A is in [0, 100), so A + 1 does not signed-overflow (A s<= SMAX - 1).
define i8 @sadd_no_overflow_pos_const(i8 %a) {
@@ -103,3 +104,228 @@ then:
else:
ret i8 0
}
+
+; C == SMIN, so A + C does not signed-overflow iff A s>= 0.
+define i8 @sadd_c_smin(i8 %a) {
+; CHECK-LABEL: define i8 @sadd_c_smin(
+; CHECK-SAME: i8 [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[LO:%.*]] = icmp sge i8 [[A]], 0
+; CHECK-NEXT: br i1 [[LO]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 -128)
+; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
+; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
+; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: ret i8 [[V]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: ret i8 0
+;
+entry:
+ %lo = icmp sge i8 %a, 0
+ br i1 %lo, label %then, label %else
+
+then:
+ %s = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 -128)
+ %v = extractvalue { i8, i1 } %s, 0
+ %o = extractvalue { i8, i1 } %s, 1
+ call void @use(i1 %o)
+ ret i8 %v
+
+else:
+ ret i8 0
+}
+
+; C == SMAX, so A + C does not signed-overflow iff A s<= 0.
+define i8 @sadd_c_smax(i8 %a) {
+; CHECK-LABEL: define i8 @sadd_c_smax(
+; CHECK-SAME: i8 [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[HI:%.*]] = icmp sle i8 [[A]], 0
+; CHECK-NEXT: br i1 [[HI]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 127)
+; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
+; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
+; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: ret i8 [[V]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: ret i8 0
+;
+entry:
+ %hi = icmp sle i8 %a, 0
+ br i1 %hi, label %then, label %else
+
+then:
+ %s = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 127)
+ %v = extractvalue { i8, i1 } %s, 0
+ %o = extractvalue { i8, i1 } %s, 1
+ call void @use(i1 %o)
+ ret i8 %v
+
+else:
+ ret i8 0
+}
+
+; The upper bound is one too large.
+define i8 @sadd_pos_const_bound_too_large(i8 %a) {
+; CHECK-LABEL: define i8 @sadd_pos_const_bound_too_large(
+; CHECK-SAME: i8 [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[HI:%.*]] = icmp sle i8 [[A]], 127
+; CHECK-NEXT: br i1 [[HI]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 1)
+; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
+; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
+; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: ret i8 [[V]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: ret i8 0
+;
+entry:
+ %hi = icmp sle i8 %a, 127
+ br i1 %hi, label %then, label %else
+
+then:
+ %s = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 1)
+ %v = extractvalue { i8, i1 } %s, 0
+ %o = extractvalue { i8, i1 } %s, 1
+ call void @use(i1 %o)
+ ret i8 %v
+
+else:
+ ret i8 0
+}
+
+; The lower bound is one too small.
+define i8 @sadd_neg_const_bound_too_small(i8 %a) {
+; CHECK-LABEL: define i8 @sadd_neg_const_bound_too_small(
+; CHECK-SAME: i8 [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[LO:%.*]] = icmp sge i8 [[A]], -128
+; CHECK-NEXT: br i1 [[LO]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 -1)
+; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
+; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
+; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: ret i8 [[V]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: ret i8 0
+;
+entry:
+ %lo = icmp sge i8 %a, -128
+ br i1 %lo, label %then, label %else
+
+then:
+ %s = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 -1)
+ %v = extractvalue { i8, i1 } %s, 0
+ %o = extractvalue { i8, i1 } %s, 1
+ call void @use(i1 %o)
+ ret i8 %v
+
+else:
+ ret i8 0
+}
+
+define i8 @sadd_unsigned_bound(i8 %a) {
+; CHECK-LABEL: define i8 @sadd_unsigned_bound(
+; CHECK-SAME: i8 [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[HI:%.*]] = icmp ult i8 [[A]], 100
+; CHECK-NEXT: br i1 [[HI]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 1)
+; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
+; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
+; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: ret i8 [[V]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: ret i8 0
+;
+entry:
+ %hi = icmp ult i8 %a, 100
+ br i1 %hi, label %then, label %else
+
+then:
+ %s = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 1)
+ %v = extractvalue { i8, i1 } %s, 0
+ %o = extractvalue { i8, i1 } %s, 1
+ call void @use(i1 %o)
+ ret i8 %v
+
+else:
+ ret i8 0
+}
+
+; The second operand is not a constant.
+define i8 @sadd_variable_ops(i8 %a, i8 %b) {
+; CHECK-LABEL: define i8 @sadd_variable_ops(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[LO:%.*]] = icmp sge i8 [[A]], 0
+; CHECK-NEXT: [[HI:%.*]] = icmp slt i8 [[A]], 100
+; CHECK-NEXT: [[OK:%.*]] = and i1 [[LO]], [[HI]]
+; CHECK-NEXT: br i1 [[OK]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 [[B]])
+; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
+; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
+; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: ret i8 [[V]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: ret i8 0
+;
+entry:
+ %lo = icmp sge i8 %a, 0
+ %hi = icmp slt i8 %a, 100
+ %ok = and i1 %lo, %hi
+ br i1 %ok, label %then, label %else
+
+then:
+ %s = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
+ %v = extractvalue { i8, i1 } %s, 0
+ %o = extractvalue { i8, i1 } %s, 1
+ call void @use(i1 %o)
+ ret i8 %v
+
+else:
+ ret i8 0
+}
+
+define i8 @sadd_aggregate_escapes(i8 %a) {
+; CHECK-LABEL: define i8 @sadd_aggregate_escapes(
+; CHECK-SAME: i8 [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[LO:%.*]] = icmp sge i8 [[A]], 0
+; CHECK-NEXT: [[HI:%.*]] = icmp slt i8 [[A]], 100
+; CHECK-NEXT: [[OK:%.*]] = and i1 [[LO]], [[HI]]
+; CHECK-NEXT: br i1 [[OK]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 1)
+; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
+; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
+; CHECK-NEXT: call void @use.agg({ i8, i1 } [[S]])
+; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: ret i8 [[V]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: ret i8 0
+;
+entry:
+ %lo = icmp sge i8 %a, 0
+ %hi = icmp slt i8 %a, 100
+ %ok = and i1 %lo, %hi
+ br i1 %ok, label %then, label %else
+
+then:
+ %s = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 1)
+ %v = extractvalue { i8, i1 } %s, 0
+ %o = extractvalue { i8, i1 } %s, 1
+ call void @use.agg({ i8, i1 } %s)
+ call void @use(i1 %o)
+ ret i8 %v
+
+else:
+ ret i8 0
+}
>From 61f79c941dca11d7229156c4bdab1e8563d27dbc Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 9 Sep 2026 12:37:29 +0100
Subject: [PATCH 2/2] [ConstraintElim] Fold sadd.with.overflow with a constant
op.
Generalize the overflow-math simplification to also allow simplifying
sadd.with.overflow if the second operand is constant, using
makeGuaranteedNoWrapRegion.
Note that this partially overlaps with the flag strengthening logic.
I'll share a patch soon to try to unify the code more.
No improvements in llvm-opt-benchmarks-nightly. It improves end-to-end
optimizations for Swift (which emits a lot of checked arithmetic) and
also Clang + UBsan.
An end-to-end improvement with overflow intrinsics is
https://llvm.godbolt.org/z/6nrj7aodd.
---
.../Scalar/ConstraintElimination.cpp | 43 ++++++++++++++-----
.../sadd-with-overflow.ll | 35 ++++++---------
2 files changed, 44 insertions(+), 34 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index ed95686e9e5d9c..da2d61e1c6e27b 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1544,7 +1544,8 @@ void State::addInfoFor(BasicBlock &BB) {
}
break;
}
- // Enqueue ssub_with_overflow for simplification.
+ // Enqueue intrinsics for simplification.
+ case Intrinsic::sadd_with_overflow:
case Intrinsic::ssub_with_overflow:
case Intrinsic::ucmp:
case Intrinsic::scmp:
@@ -2217,16 +2218,21 @@ void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
}
}
-static bool replaceSubOverflowUses(IntrinsicInst *II, Value *A, Value *B,
- SmallVectorImpl<Instruction *> &ToRemove) {
+/// Replace the uses of the overflow intrinsic \p II, which has been proven not
+/// to signed-overflow, by (Opcode A, B).
+static bool replaceOverflowUses(IntrinsicInst *II,
+ Instruction::BinaryOps Opcode, Value *A,
+ Value *B,
+ SmallVectorImpl<Instruction *> &ToRemove) {
bool Changed = false;
IRBuilder<> Builder(II->getParent(), II->getIterator());
- Value *Sub = nullptr;
+ Value *Res = nullptr;
for (User *U : make_early_inc_range(II->users())) {
if (match(U, m_ExtractValue<0>(m_Value()))) {
- if (!Sub)
- Sub = Builder.CreateNSWSub(A, B);
- U->replaceAllUsesWith(Sub);
+ if (!Res)
+ Res = Builder.CreateNoWrapBinOp(Opcode, A, B, /*IsNUW=*/false,
+ /*IsNSW=*/true);
+ U->replaceAllUsesWith(Res);
Changed = true;
} else if (match(U, m_ExtractValue<1>(m_Value()))) {
U->replaceAllUsesWith(Builder.getFalse());
@@ -2267,8 +2273,8 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info,
return CSToUse.isConditionImpliedInSubSystem(R.Coefficients);
};
- bool Changed = false;
- if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::ssub_with_overflow: {
// If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
// can be simplified to a regular sub.
Value *A = II->getArgOperand(0);
@@ -2277,9 +2283,24 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info,
!DoesConditionHold(CmpInst::ICMP_SGE, B,
ConstantInt::get(A->getType(), 0), Info))
return false;
- Changed = replaceSubOverflowUses(II, A, B, ToRemove);
+ return replaceOverflowUses(II, Instruction::Sub, A, B, ToRemove);
+ }
+ case Intrinsic::sadd_with_overflow: {
+ Value *A = II->getArgOperand(0);
+ Value *B = II->getArgOperand(1);
+ auto *C = dyn_cast<ConstantInt>(B);
+ if (!C ||
+ !doesHoldInRange(Info, A,
+ ConstantRange::makeGuaranteedNoWrapRegion(
+ Instruction::Add, ConstantRange(C->getValue()),
+ OverflowingBinaryOperator::NoSignedWrap),
+ /*Signed=*/true))
+ return false;
+ return replaceOverflowUses(II, Instruction::Add, A, B, ToRemove);
+ }
+ default:
+ return false;
}
- return Changed;
}
static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
diff --git a/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll b/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll
index 3f559e0cda8259..4194797fa5ea05 100644
--- a/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll
+++ b/llvm/test/Transforms/ConstraintElimination/sadd-with-overflow.ll
@@ -14,10 +14,8 @@ define i8 @sadd_no_overflow_pos_const(i8 %a) {
; CHECK-NEXT: [[OK:%.*]] = and i1 [[LO]], [[HI]]
; CHECK-NEXT: br i1 [[OK]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
-; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 1)
-; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
-; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
-; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: [[V:%.*]] = add nsw i8 [[A]], 1
+; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: ret i8 [[V]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: ret i8 0
@@ -49,10 +47,8 @@ define i8 @sadd_no_overflow_neg_const(i8 %a) {
; CHECK-NEXT: [[OK:%.*]] = and i1 [[LO]], [[HI]]
; CHECK-NEXT: br i1 [[OK]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
-; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 -1)
-; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
-; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
-; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: [[V:%.*]] = add nsw i8 [[A]], -1
+; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: ret i8 [[V]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: ret i8 0
@@ -113,10 +109,8 @@ define i8 @sadd_c_smin(i8 %a) {
; CHECK-NEXT: [[LO:%.*]] = icmp sge i8 [[A]], 0
; CHECK-NEXT: br i1 [[LO]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
-; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 -128)
-; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
-; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
-; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: [[V:%.*]] = add nsw i8 [[A]], -128
+; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: ret i8 [[V]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: ret i8 0
@@ -144,10 +138,8 @@ define i8 @sadd_c_smax(i8 %a) {
; CHECK-NEXT: [[HI:%.*]] = icmp sle i8 [[A]], 0
; CHECK-NEXT: br i1 [[HI]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
-; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 127)
-; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
-; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
-; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: [[V:%.*]] = add nsw i8 [[A]], 127
+; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: ret i8 [[V]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: ret i8 0
@@ -236,10 +228,8 @@ define i8 @sadd_unsigned_bound(i8 %a) {
; CHECK-NEXT: [[HI:%.*]] = icmp ult i8 [[A]], 100
; CHECK-NEXT: br i1 [[HI]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
-; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 1)
-; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
-; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
-; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: [[V:%.*]] = add nsw i8 [[A]], 1
+; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: ret i8 [[V]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: ret i8 0
@@ -303,11 +293,10 @@ define i8 @sadd_aggregate_escapes(i8 %a) {
; CHECK-NEXT: [[OK:%.*]] = and i1 [[LO]], [[HI]]
; CHECK-NEXT: br i1 [[OK]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
+; CHECK-NEXT: [[V:%.*]] = add nsw i8 [[A]], 1
; CHECK-NEXT: [[S:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 1)
-; CHECK-NEXT: [[V:%.*]] = extractvalue { i8, i1 } [[S]], 0
-; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[S]], 1
; CHECK-NEXT: call void @use.agg({ i8, i1 } [[S]])
-; CHECK-NEXT: call void @use(i1 [[O]])
+; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: ret i8 [[V]]
; CHECK: [[ELSE]]:
; CHECK-NEXT: ret i8 0
More information about the llvm-commits
mailing list