Skip to content

Commit 5ba4943

Browse files
committed
[SCEV] Do not allow refinement in the rewriting of BEValue
1 parent 8aecde3 commit 5ba4943

File tree

6 files changed

+34
-26
lines changed

6 files changed

+34
-26
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,9 @@ class ScalarEvolution {
21872187
bool isGuaranteedToTransferExecutionTo(const Instruction *A,
21882188
const Instruction *B);
21892189

2190+
/// Returns true if \p Op is guaranteed not to cause immediate UB.
2191+
bool isGuaranteedNotToCauseUB(const SCEV *Op);
2192+
21902193
/// Returns true if \p Op is guaranteed to not be poison.
21912194
static bool isGuaranteedNotToBePoison(const SCEV *Op);
21922195

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4307,15 +4307,7 @@ ScalarEvolution::getSequentialMinMaxExpr(SCEVTypes Kind,
43074307
}
43084308

43094309
for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
4310-
bool MayBeUB = SCEVExprContains(Ops[i], [this](const SCEV *S) {
4311-
auto *UDiv = dyn_cast<SCEVUDivExpr>(S);
4312-
// The UDiv may be UB if the divisor is poison or zero. Unless the divisor
4313-
// is a non-zero constant, we have to assume the UDiv may be UB.
4314-
return UDiv && (!isKnownNonZero(UDiv->getOperand(1)) ||
4315-
!isGuaranteedNotToBePoison(UDiv->getOperand(1)));
4316-
});
4317-
4318-
if (MayBeUB)
4310+
if (!isGuaranteedNotToCauseUB(Ops[i]))
43194311
continue;
43204312
// We can replace %x umin_seq %y with %x umin %y if either:
43214313
// * %y being poison implies %x is also poison.
@@ -5933,18 +5925,21 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
59335925
// We can generalize this saying that i is the shifted value of BEValue
59345926
// by one iteration:
59355927
// PHI(f(0), f({1,+,1})) --> f({0,+,1})
5936-
const SCEV *Shifted = SCEVShiftRewriter::rewrite(BEValue, L, *this);
5937-
const SCEV *Start = SCEVInitRewriter::rewrite(Shifted, L, *this, false);
5938-
if (Shifted != getCouldNotCompute() &&
5939-
Start != getCouldNotCompute()) {
5940-
const SCEV *StartVal = getSCEV(StartValueV);
5941-
if (Start == StartVal) {
5942-
// Okay, for the entire analysis of this edge we assumed the PHI
5943-
// to be symbolic. We now need to go back and purge all of the
5944-
// entries for the scalars that use the symbolic expression.
5945-
forgetMemoizedResults(SymbolicName);
5946-
insertValueToMap(PN, Shifted);
5947-
return Shifted;
5928+
5929+
// Do not allow refinement in rewriting of BEValue.
5930+
if (isGuaranteedNotToCauseUB(BEValue)) {
5931+
const SCEV *Shifted = SCEVShiftRewriter::rewrite(BEValue, L, *this);
5932+
const SCEV *Start = SCEVInitRewriter::rewrite(Shifted, L, *this, false);
5933+
if (Shifted != getCouldNotCompute() && Start != getCouldNotCompute()) {
5934+
const SCEV *StartVal = getSCEV(StartValueV);
5935+
if (Start == StartVal) {
5936+
// Okay, for the entire analysis of this edge we assumed the PHI
5937+
// to be symbolic. We now need to go back and purge all of the
5938+
// entries for the scalars that use the symbolic expression.
5939+
forgetMemoizedResults(SymbolicName);
5940+
insertValueToMap(PN, Shifted);
5941+
return Shifted;
5942+
}
59485943
}
59495944
}
59505945
}
@@ -7322,6 +7317,16 @@ bool ScalarEvolution::isGuaranteedNotToBePoison(const SCEV *Op) {
73227317
return PC.MaybePoison.empty();
73237318
}
73247319

7320+
bool ScalarEvolution::isGuaranteedNotToCauseUB(const SCEV *Op) {
7321+
return !SCEVExprContains(Op, [this](const SCEV *S) {
7322+
auto *UDiv = dyn_cast<SCEVUDivExpr>(S);
7323+
// The UDiv may be UB if the divisor is poison or zero. Unless the divisor
7324+
// is a non-zero constant, we have to assume the UDiv may be UB.
7325+
return UDiv && (!isKnownNonZero(UDiv->getOperand(1)) ||
7326+
!isGuaranteedNotToBePoison(UDiv->getOperand(1)));
7327+
});
7328+
}
7329+
73257330
bool ScalarEvolution::isSCEVExprNeverPoison(const Instruction *I) {
73267331
// Only proceed if we can prove that I does not yield poison.
73277332
if (!programUndefinedIfPoison(I))

llvm/test/Analysis/ScalarEvolution/fold.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ define i64 @test10(i64 %a, i64 %b) {
214214
ret i64 %t2
215215
}
216216

217-
define i64 @test11(i64 %a) {
217+
define i64 @test11(i64 noundef range(i64 1, 0) %a) {
218218
; CHECK-LABEL: 'test11'
219219
; CHECK-NEXT: Classifying expressions for: @test11
220220
; CHECK-NEXT: %t0 = udiv i64 0, %a

llvm/test/Analysis/ScalarEvolution/pr117133.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ define i32 @widget() {
55
; CHECK-LABEL: 'widget'
66
; CHECK-NEXT: Classifying expressions for: @widget
77
; CHECK-NEXT: %phi = phi i32 [ 0, %b ], [ %udiv6, %b5 ]
8-
; CHECK-NEXT: --> ({0,+,1}<nuw><nsw><%b1> /u 0) U: empty-set S: empty-set Exits: <<Unknown>> LoopDispositions: { %b1: Computable }
8+
; CHECK-NEXT: --> %phi U: [0,1) S: [0,1) Exits: <<Unknown>> LoopDispositions: { %b1: Variant }
99
; CHECK-NEXT: %phi2 = phi i32 [ 1, %b ], [ %add, %b5 ]
1010
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%b1> U: [1,2) S: [1,2) Exits: <<Unknown>> LoopDispositions: { %b1: Computable }
1111
; CHECK-NEXT: %udiv = udiv i32 10, %phi2

llvm/test/Analysis/ScalarEvolution/udiv-of-x-xsmaxone-fold.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
22
; RUN: opt -disable-output -passes="print<scalar-evolution>" < %s 2>&1 | FileCheck %s
33

4-
define i32 @test_expr_with_constant_1(i32 %x) {
4+
define i32 @test_expr_with_constant_1(i32 noundef range(i32 1, 0) %x) {
55
; CHECK-LABEL: 'test_expr_with_constant_1'
66
; CHECK-NEXT: Classifying expressions for: @test_expr_with_constant_1
77
; CHECK-NEXT: %smax = tail call i32 @llvm.smax.i32(i32 %x, i32 1)
@@ -20,7 +20,7 @@ entry:
2020
}
2121

2222
; Non-1 constant: (-2 + (2 smax %x)) /u %x
23-
define i32 @test_expr_with_constant_2(i32 %x) {
23+
define i32 @test_expr_with_constant_2(i32 noundef range(i32 1, 0) %x) {
2424
; CHECK-LABEL: 'test_expr_with_constant_2'
2525
; CHECK-NEXT: Classifying expressions for: @test_expr_with_constant_2
2626
; CHECK-NEXT: %smax = tail call i32 @llvm.smax.i32(i32 %x, i32 2)

llvm/test/Transforms/IndVarSimplify/pr117133.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ define i32 @widget() {
77
; CHECK-NEXT: [[B:.*:]]
88
; CHECK-NEXT: br label %[[B1:.*]]
99
; CHECK: [[B1]]:
10-
; CHECK-NEXT: br i1 false, label %[[B3:.*]], label %[[B8:.*]]
10+
; CHECK-NEXT: br i1 true, label %[[B3:.*]], label %[[B8:.*]]
1111
; CHECK: [[B3]]:
1212
; CHECK-NEXT: br i1 true, label %[[B7:.*]], label %[[B5:.*]]
1313
; CHECK: [[B5]]:

0 commit comments

Comments
 (0)