Skip to content

Commit 27392a3

Browse files
authored
[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 #93096.
1 parent 300e5b9 commit 27392a3

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static ValueLatticeElement::MergeOptions getMaxWidenStepsOpts() {
4343
}
4444

4545
static ConstantRange getConstantRange(const ValueLatticeElement &LV, Type *Ty,
46-
bool UndefAllowed = true) {
46+
bool UndefAllowed) {
4747
assert(Ty->isIntOrIntVectorTy() && "Should be int or int vector");
4848
if (LV.isConstantRange(UndefAllowed))
4949
return LV.getConstantRange();
@@ -1297,7 +1297,8 @@ void SCCPInstVisitor::visitCastInst(CastInst &I) {
12971297

12981298
if (I.getDestTy()->isIntegerTy() && I.getSrcTy()->isIntOrIntVectorTy()) {
12991299
auto &LV = getValueState(&I);
1300-
ConstantRange OpRange = getConstantRange(OpSt, I.getSrcTy());
1300+
ConstantRange OpRange =
1301+
getConstantRange(OpSt, I.getSrcTy(), /*UndefAllowed=*/false);
13011302

13021303
Type *DestTy = I.getDestTy();
13031304
// Vectors where all elements have the same known constant range are treated
@@ -1329,8 +1330,8 @@ void SCCPInstVisitor::handleExtractOfWithOverflow(ExtractValueInst &EVI,
13291330
return; // Wait to resolve.
13301331

13311332
Type *Ty = LHS->getType();
1332-
ConstantRange LR = getConstantRange(L, Ty);
1333-
ConstantRange RR = getConstantRange(R, Ty);
1333+
ConstantRange LR = getConstantRange(L, Ty, /*UndefAllowed=*/false);
1334+
ConstantRange RR = getConstantRange(R, Ty, /*UndefAllowed=*/false);
13341335
if (Idx == 0) {
13351336
ConstantRange Res = LR.binaryOp(WO->getBinaryOp(), RR);
13361337
mergeInValue(&EVI, ValueLatticeElement::getRange(Res));
@@ -1534,8 +1535,10 @@ void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
15341535
return markOverdefined(&I);
15351536

15361537
// Try to simplify to a constant range.
1537-
ConstantRange A = getConstantRange(V1State, I.getType());
1538-
ConstantRange B = getConstantRange(V2State, I.getType());
1538+
ConstantRange A =
1539+
getConstantRange(V1State, I.getType(), /*UndefAllowed=*/false);
1540+
ConstantRange B =
1541+
getConstantRange(V2State, I.getType(), /*UndefAllowed=*/false);
15391542

15401543
auto *BO = cast<BinaryOperator>(&I);
15411544
ConstantRange R = ConstantRange::getEmpty(I.getType()->getScalarSizeInBits());
@@ -1818,7 +1821,8 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
18181821

18191822
// Combine range info for the original value with the new range from the
18201823
// condition.
1821-
auto CopyOfCR = getConstantRange(CopyOfVal, CopyOf->getType());
1824+
auto CopyOfCR = getConstantRange(CopyOfVal, CopyOf->getType(),
1825+
/*UndefAllowed=*/true);
18221826
auto NewCR = ImposedCR.intersectWith(CopyOfCR);
18231827
// If the existing information is != x, do not use the information from
18241828
// a chained predicate, as the != x information is more likely to be
@@ -1863,7 +1867,8 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
18631867
const ValueLatticeElement &State = getValueState(Op);
18641868
if (State.isUnknownOrUndef())
18651869
return;
1866-
OpRanges.push_back(getConstantRange(State, Op->getType()));
1870+
OpRanges.push_back(
1871+
getConstantRange(State, Op->getType(), /*UndefAllowed=*/false));
18671872
}
18681873

18691874
ConstantRange Result =

llvm/test/Transforms/SCCP/ip-add-range-to-call.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ exit:
159159
}
160160

161161
define i32 @caller5() {
162-
; CHECK-LABEL: define range(i32 200, 401) i32 @caller5() {
162+
; CHECK-LABEL: define i32 @caller5() {
163163
; CHECK-NEXT: [[C1:%.*]] = call i32 @callee5(i32 10, i32 100)
164164
; CHECK-NEXT: [[C2:%.*]] = call i32 @callee5(i32 20, i32 200)
165165
; CHECK-NEXT: [[A:%.*]] = add i32 [[C1]], [[C2]]

llvm/test/Transforms/SCCP/range-with-undef.ll

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
; RUN: opt -S -passes=ipsccp < %s | FileCheck %s
33

44
; Make sure that constant ranges including undef are propagated correctly.
5-
; FIXME: All of the following are currently miscompiled.
65

76
define i8 @test_binop(i1 %cond, i8 %a) {
87
; CHECK-LABEL: define i8 @test_binop(
@@ -15,7 +14,7 @@ define i8 @test_binop(i1 %cond, i8 %a) {
1514
; CHECK: [[JOIN]]:
1615
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
1716
; CHECK-NEXT: [[AND:%.*]] = and i16 [[PHI]], -1
18-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i16 [[AND]] to i8
17+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[AND]] to i8
1918
; CHECK-NEXT: ret i8 [[TRUNC]]
2019
;
2120
entry:
@@ -43,7 +42,7 @@ define i8 @test_cast(i1 %cond, i8 %a) {
4342
; CHECK: [[JOIN]]:
4443
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
4544
; CHECK-NEXT: [[ZEXT:%.*]] = zext i16 [[PHI]] to i32
46-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 [[ZEXT]] to i8
45+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ZEXT]] to i8
4746
; CHECK-NEXT: ret i8 [[TRUNC]]
4847
;
4948
entry:
@@ -61,7 +60,7 @@ join:
6160
}
6261

6362
define i8 @test_intrin(i1 %cond, i8 %a) {
64-
; CHECK-LABEL: define range(i8 42, 0) i8 @test_intrin(
63+
; CHECK-LABEL: define i8 @test_intrin(
6564
; CHECK-SAME: i1 [[COND:%.*]], i8 [[A:%.*]]) {
6665
; CHECK-NEXT: [[ENTRY:.*]]:
6766
; CHECK-NEXT: br i1 [[COND]], label %[[IF:.*]], label %[[JOIN:.*]]
@@ -71,7 +70,7 @@ define i8 @test_intrin(i1 %cond, i8 %a) {
7170
; CHECK: [[JOIN]]:
7271
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
7372
; CHECK-NEXT: [[UMAX:%.*]] = call i16 @llvm.umax.i16(i16 [[PHI]], i16 42)
74-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i16 [[UMAX]] to i8
73+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[UMAX]] to i8
7574
; CHECK-NEXT: ret i8 [[TRUNC]]
7675
;
7776
entry:
@@ -89,7 +88,7 @@ join:
8988
}
9089

9190
define i9 @test_with_overflow(i1 %cond, i8 %a) {
92-
; CHECK-LABEL: define range(i9 1, -255) i9 @test_with_overflow(
91+
; CHECK-LABEL: define i9 @test_with_overflow(
9392
; CHECK-SAME: i1 [[COND:%.*]], i8 [[A:%.*]]) {
9493
; CHECK-NEXT: [[ENTRY:.*]]:
9594
; CHECK-NEXT: br i1 [[COND]], label %[[IF:.*]], label %[[JOIN:.*]]
@@ -100,7 +99,7 @@ define i9 @test_with_overflow(i1 %cond, i8 %a) {
10099
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
101100
; CHECK-NEXT: [[WO:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 [[PHI]], i16 1)
102101
; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i16, i1 } [[WO]], 0
103-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i16 [[ADD]] to i9
102+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[ADD]] to i9
104103
; CHECK-NEXT: ret i9 [[TRUNC]]
105104
;
106105
entry:

0 commit comments

Comments
 (0)