[llvm] 27392a3 - [SCCP] Don't allow undef ranges when performing operations (#93163)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 23 06:14:38 PDT 2024
Author: Nikita Popov
Date: 2024-05-23T15:14:34+02:00
New Revision: 27392a35ef052aa515f38359de89aced11a4363d
URL: https://github.com/llvm/llvm-project/commit/27392a35ef052aa515f38359de89aced11a4363d
DIFF: https://github.com/llvm/llvm-project/commit/27392a35ef052aa515f38359de89aced11a4363d.diff
LOG: [SCCP] Don't allow undef ranges when performing operations (#93163)
When performing some range operation (e.g. and) on a constant range that
includes undef, we currently just ignore the undef value, which is
obviously incorrect. Instead, we can do one of two things:
* Say that the result range also includes undef.
* Treat undef as a full range.
This patch goes with the second approach -- I'd expect it to be a bit
better overall, e.g. it allows preserving the fact that a zext of a
range with undef isn't a full range.
Fixes https://github.com/llvm/llvm-project/issues/93096.
Added:
Modified:
llvm/lib/Transforms/Utils/SCCPSolver.cpp
llvm/test/Transforms/SCCP/ip-add-range-to-call.ll
llvm/test/Transforms/SCCP/range-with-undef.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index ce40e8b31b767..4f36bac11e34b 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -43,7 +43,7 @@ static ValueLatticeElement::MergeOptions getMaxWidenStepsOpts() {
}
static ConstantRange getConstantRange(const ValueLatticeElement &LV, Type *Ty,
- bool UndefAllowed = true) {
+ bool UndefAllowed) {
assert(Ty->isIntOrIntVectorTy() && "Should be int or int vector");
if (LV.isConstantRange(UndefAllowed))
return LV.getConstantRange();
@@ -1297,7 +1297,8 @@ void SCCPInstVisitor::visitCastInst(CastInst &I) {
if (I.getDestTy()->isIntegerTy() && I.getSrcTy()->isIntOrIntVectorTy()) {
auto &LV = getValueState(&I);
- ConstantRange OpRange = getConstantRange(OpSt, I.getSrcTy());
+ ConstantRange OpRange =
+ getConstantRange(OpSt, I.getSrcTy(), /*UndefAllowed=*/false);
Type *DestTy = I.getDestTy();
// Vectors where all elements have the same known constant range are treated
@@ -1329,8 +1330,8 @@ void SCCPInstVisitor::handleExtractOfWithOverflow(ExtractValueInst &EVI,
return; // Wait to resolve.
Type *Ty = LHS->getType();
- ConstantRange LR = getConstantRange(L, Ty);
- ConstantRange RR = getConstantRange(R, Ty);
+ ConstantRange LR = getConstantRange(L, Ty, /*UndefAllowed=*/false);
+ ConstantRange RR = getConstantRange(R, Ty, /*UndefAllowed=*/false);
if (Idx == 0) {
ConstantRange Res = LR.binaryOp(WO->getBinaryOp(), RR);
mergeInValue(&EVI, ValueLatticeElement::getRange(Res));
@@ -1534,8 +1535,10 @@ void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
return markOverdefined(&I);
// Try to simplify to a constant range.
- ConstantRange A = getConstantRange(V1State, I.getType());
- ConstantRange B = getConstantRange(V2State, I.getType());
+ ConstantRange A =
+ getConstantRange(V1State, I.getType(), /*UndefAllowed=*/false);
+ ConstantRange B =
+ getConstantRange(V2State, I.getType(), /*UndefAllowed=*/false);
auto *BO = cast<BinaryOperator>(&I);
ConstantRange R = ConstantRange::getEmpty(I.getType()->getScalarSizeInBits());
@@ -1818,7 +1821,8 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
// Combine range info for the original value with the new range from the
// condition.
- auto CopyOfCR = getConstantRange(CopyOfVal, CopyOf->getType());
+ auto CopyOfCR = getConstantRange(CopyOfVal, CopyOf->getType(),
+ /*UndefAllowed=*/true);
auto NewCR = ImposedCR.intersectWith(CopyOfCR);
// If the existing information is != x, do not use the information from
// a chained predicate, as the != x information is more likely to be
@@ -1863,7 +1867,8 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
const ValueLatticeElement &State = getValueState(Op);
if (State.isUnknownOrUndef())
return;
- OpRanges.push_back(getConstantRange(State, Op->getType()));
+ OpRanges.push_back(
+ getConstantRange(State, Op->getType(), /*UndefAllowed=*/false));
}
ConstantRange Result =
diff --git a/llvm/test/Transforms/SCCP/ip-add-range-to-call.ll b/llvm/test/Transforms/SCCP/ip-add-range-to-call.ll
index c24c554102ddf..91efbcc4ee382 100644
--- a/llvm/test/Transforms/SCCP/ip-add-range-to-call.ll
+++ b/llvm/test/Transforms/SCCP/ip-add-range-to-call.ll
@@ -159,7 +159,7 @@ exit:
}
define i32 @caller5() {
-; CHECK-LABEL: define range(i32 200, 401) i32 @caller5() {
+; CHECK-LABEL: define i32 @caller5() {
; CHECK-NEXT: [[C1:%.*]] = call i32 @callee5(i32 10, i32 100)
; CHECK-NEXT: [[C2:%.*]] = call i32 @callee5(i32 20, i32 200)
; CHECK-NEXT: [[A:%.*]] = add i32 [[C1]], [[C2]]
diff --git a/llvm/test/Transforms/SCCP/range-with-undef.ll b/llvm/test/Transforms/SCCP/range-with-undef.ll
index 444b47df55697..9b8d415171140 100644
--- a/llvm/test/Transforms/SCCP/range-with-undef.ll
+++ b/llvm/test/Transforms/SCCP/range-with-undef.ll
@@ -2,7 +2,6 @@
; RUN: opt -S -passes=ipsccp < %s | FileCheck %s
; Make sure that constant ranges including undef are propagated correctly.
-; FIXME: All of the following are currently miscompiled.
define i8 @test_binop(i1 %cond, i8 %a) {
; CHECK-LABEL: define i8 @test_binop(
@@ -15,7 +14,7 @@ define i8 @test_binop(i1 %cond, i8 %a) {
; CHECK: [[JOIN]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
; CHECK-NEXT: [[AND:%.*]] = and i16 [[PHI]], -1
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i16 [[AND]] to i8
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[AND]] to i8
; CHECK-NEXT: ret i8 [[TRUNC]]
;
entry:
@@ -43,7 +42,7 @@ define i8 @test_cast(i1 %cond, i8 %a) {
; CHECK: [[JOIN]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
; CHECK-NEXT: [[ZEXT:%.*]] = zext i16 [[PHI]] to i32
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 [[ZEXT]] to i8
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ZEXT]] to i8
; CHECK-NEXT: ret i8 [[TRUNC]]
;
entry:
@@ -61,7 +60,7 @@ join:
}
define i8 @test_intrin(i1 %cond, i8 %a) {
-; CHECK-LABEL: define range(i8 42, 0) i8 @test_intrin(
+; CHECK-LABEL: define i8 @test_intrin(
; CHECK-SAME: i1 [[COND:%.*]], i8 [[A:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br i1 [[COND]], label %[[IF:.*]], label %[[JOIN:.*]]
@@ -71,7 +70,7 @@ define i8 @test_intrin(i1 %cond, i8 %a) {
; CHECK: [[JOIN]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
; CHECK-NEXT: [[UMAX:%.*]] = call i16 @llvm.umax.i16(i16 [[PHI]], i16 42)
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i16 [[UMAX]] to i8
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[UMAX]] to i8
; CHECK-NEXT: ret i8 [[TRUNC]]
;
entry:
@@ -89,7 +88,7 @@ join:
}
define i9 @test_with_overflow(i1 %cond, i8 %a) {
-; CHECK-LABEL: define range(i9 1, -255) i9 @test_with_overflow(
+; CHECK-LABEL: define i9 @test_with_overflow(
; CHECK-SAME: i1 [[COND:%.*]], i8 [[A:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br i1 [[COND]], label %[[IF:.*]], label %[[JOIN:.*]]
@@ -100,7 +99,7 @@ define i9 @test_with_overflow(i1 %cond, i8 %a) {
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
; CHECK-NEXT: [[WO:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 [[PHI]], i16 1)
; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i16, i1 } [[WO]], 0
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i16 [[ADD]] to i9
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[ADD]] to i9
; CHECK-NEXT: ret i9 [[TRUNC]]
;
entry:
More information about the llvm-commits
mailing list