mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-22 13:29:44 +00:00
[IRCE] Fix a regression introduced in r232444.
IRCE should not try to eliminate range checks that check an induction variable against a loop-varying length. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233101 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fe76881930
commit
33a864aae2
@ -122,8 +122,9 @@ class InductiveRangeCheck {
|
|||||||
BranchInst *Branch;
|
BranchInst *Branch;
|
||||||
RangeCheckKind Kind;
|
RangeCheckKind Kind;
|
||||||
|
|
||||||
static RangeCheckKind parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
static RangeCheckKind parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
|
||||||
Value *&Index, Value *&Length);
|
ScalarEvolution &SE, Value *&Index,
|
||||||
|
Value *&Length);
|
||||||
|
|
||||||
static InductiveRangeCheck::RangeCheckKind
|
static InductiveRangeCheck::RangeCheckKind
|
||||||
parseRangeCheck(Loop *L, ScalarEvolution &SE, Value *Condition,
|
parseRangeCheck(Loop *L, ScalarEvolution &SE, Value *Condition,
|
||||||
@ -255,8 +256,18 @@ const char *InductiveRangeCheck::rangeCheckKindToStr(
|
|||||||
/// RANGE_CHECK_UPPER.
|
/// RANGE_CHECK_UPPER.
|
||||||
///
|
///
|
||||||
InductiveRangeCheck::RangeCheckKind
|
InductiveRangeCheck::RangeCheckKind
|
||||||
InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
|
||||||
Value *&Index, Value *&Length) {
|
ScalarEvolution &SE, Value *&Index,
|
||||||
|
Value *&Length) {
|
||||||
|
|
||||||
|
auto IsNonNegativeAndNotLoopVarying = [&SE, L](Value *V) {
|
||||||
|
const SCEV *S = SE.getSCEV(V);
|
||||||
|
if (isa<SCEVCouldNotCompute>(S))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return SE.getLoopDisposition(S, L) == ScalarEvolution::LoopInvariant &&
|
||||||
|
SE.isKnownNonNegative(S);
|
||||||
|
};
|
||||||
|
|
||||||
using namespace llvm::PatternMatch;
|
using namespace llvm::PatternMatch;
|
||||||
|
|
||||||
@ -287,7 +298,7 @@ InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
|||||||
return RANGE_CHECK_LOWER;
|
return RANGE_CHECK_LOWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SE.isKnownNonNegative(SE.getSCEV(LHS))) {
|
if (IsNonNegativeAndNotLoopVarying(LHS)) {
|
||||||
Index = RHS;
|
Index = RHS;
|
||||||
Length = LHS;
|
Length = LHS;
|
||||||
return RANGE_CHECK_UPPER;
|
return RANGE_CHECK_UPPER;
|
||||||
@ -298,7 +309,7 @@ InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
|||||||
std::swap(LHS, RHS);
|
std::swap(LHS, RHS);
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case ICmpInst::ICMP_UGT:
|
case ICmpInst::ICMP_UGT:
|
||||||
if (SE.isKnownNonNegative(SE.getSCEV(LHS))) {
|
if (IsNonNegativeAndNotLoopVarying(LHS)) {
|
||||||
Index = RHS;
|
Index = RHS;
|
||||||
Length = LHS;
|
Length = LHS;
|
||||||
return RANGE_CHECK_BOTH;
|
return RANGE_CHECK_BOTH;
|
||||||
@ -328,8 +339,8 @@ InductiveRangeCheck::parseRangeCheck(Loop *L, ScalarEvolution &SE,
|
|||||||
if (!ICmpA || !ICmpB)
|
if (!ICmpA || !ICmpB)
|
||||||
return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
|
return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
|
||||||
|
|
||||||
auto RCKindA = parseRangeCheckICmp(ICmpA, SE, IndexA, LengthA);
|
auto RCKindA = parseRangeCheckICmp(L, ICmpA, SE, IndexA, LengthA);
|
||||||
auto RCKindB = parseRangeCheckICmp(ICmpB, SE, IndexB, LengthB);
|
auto RCKindB = parseRangeCheckICmp(L, ICmpB, SE, IndexB, LengthB);
|
||||||
|
|
||||||
if (RCKindA == InductiveRangeCheck::RANGE_CHECK_UNKNOWN ||
|
if (RCKindA == InductiveRangeCheck::RANGE_CHECK_UNKNOWN ||
|
||||||
RCKindB == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
|
RCKindB == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
|
||||||
@ -353,7 +364,7 @@ InductiveRangeCheck::parseRangeCheck(Loop *L, ScalarEvolution &SE,
|
|||||||
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Condition)) {
|
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Condition)) {
|
||||||
Value *IndexVal = nullptr;
|
Value *IndexVal = nullptr;
|
||||||
|
|
||||||
auto RCKind = parseRangeCheckICmp(ICI, SE, IndexVal, Length);
|
auto RCKind = parseRangeCheckICmp(L, ICI, SE, IndexVal, Length);
|
||||||
|
|
||||||
if (RCKind == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
|
if (RCKind == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
|
||||||
return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
|
return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
|
||||||
|
31
test/Transforms/IRCE/bug-loop-varying-upper-limit.ll
Normal file
31
test/Transforms/IRCE/bug-loop-varying-upper-limit.ll
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
; RUN: opt -irce-print-changed-loops -S -irce -verify < %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK-NOT: constrained loop
|
||||||
|
|
||||||
|
define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) {
|
||||||
|
entry:
|
||||||
|
%first.itr.check = icmp sgt i32 %n, 0
|
||||||
|
br i1 %first.itr.check, label %loop, label %exit
|
||||||
|
|
||||||
|
loop:
|
||||||
|
%idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ]
|
||||||
|
%idx.next = add i32 %idx, 1
|
||||||
|
%len = load i32, i32* %a_len_ptr, !range !0
|
||||||
|
%abc = icmp slt i32 %idx, %len
|
||||||
|
br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
|
||||||
|
|
||||||
|
in.bounds:
|
||||||
|
%addr = getelementptr i32, i32* %arr, i32 %idx
|
||||||
|
store i32 0, i32* %addr
|
||||||
|
%next = icmp slt i32 %idx.next, %n
|
||||||
|
br i1 %next, label %loop, label %exit
|
||||||
|
|
||||||
|
out.of.bounds:
|
||||||
|
ret void
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
!0 = !{i32 0, i32 2147483647}
|
||||||
|
!1 = !{!"branch_weights", i32 64, i32 4}
|
Loading…
x
Reference in New Issue
Block a user