mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-08 21:37:35 +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. llvm-svn: 233101
This commit is contained in:
parent
b1b1054a09
commit
867451d1ec
@ -122,8 +122,9 @@ class InductiveRangeCheck {
|
||||
BranchInst *Branch;
|
||||
RangeCheckKind Kind;
|
||||
|
||||
static RangeCheckKind parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
||||
Value *&Index, Value *&Length);
|
||||
static RangeCheckKind parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
|
||||
ScalarEvolution &SE, Value *&Index,
|
||||
Value *&Length);
|
||||
|
||||
static InductiveRangeCheck::RangeCheckKind
|
||||
parseRangeCheck(Loop *L, ScalarEvolution &SE, Value *Condition,
|
||||
@ -255,8 +256,18 @@ const char *InductiveRangeCheck::rangeCheckKindToStr(
|
||||
/// RANGE_CHECK_UPPER.
|
||||
///
|
||||
InductiveRangeCheck::RangeCheckKind
|
||||
InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
||||
Value *&Index, Value *&Length) {
|
||||
InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
|
||||
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;
|
||||
|
||||
@ -287,7 +298,7 @@ InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
||||
return RANGE_CHECK_LOWER;
|
||||
}
|
||||
|
||||
if (SE.isKnownNonNegative(SE.getSCEV(LHS))) {
|
||||
if (IsNonNegativeAndNotLoopVarying(LHS)) {
|
||||
Index = RHS;
|
||||
Length = LHS;
|
||||
return RANGE_CHECK_UPPER;
|
||||
@ -298,7 +309,7 @@ InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE,
|
||||
std::swap(LHS, RHS);
|
||||
// fallthrough
|
||||
case ICmpInst::ICMP_UGT:
|
||||
if (SE.isKnownNonNegative(SE.getSCEV(LHS))) {
|
||||
if (IsNonNegativeAndNotLoopVarying(LHS)) {
|
||||
Index = RHS;
|
||||
Length = LHS;
|
||||
return RANGE_CHECK_BOTH;
|
||||
@ -328,8 +339,8 @@ InductiveRangeCheck::parseRangeCheck(Loop *L, ScalarEvolution &SE,
|
||||
if (!ICmpA || !ICmpB)
|
||||
return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
|
||||
|
||||
auto RCKindA = parseRangeCheckICmp(ICmpA, SE, IndexA, LengthA);
|
||||
auto RCKindB = parseRangeCheckICmp(ICmpB, SE, IndexB, LengthB);
|
||||
auto RCKindA = parseRangeCheckICmp(L, ICmpA, SE, IndexA, LengthA);
|
||||
auto RCKindB = parseRangeCheckICmp(L, ICmpB, SE, IndexB, LengthB);
|
||||
|
||||
if (RCKindA == 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)) {
|
||||
Value *IndexVal = nullptr;
|
||||
|
||||
auto RCKind = parseRangeCheckICmp(ICI, SE, IndexVal, Length);
|
||||
auto RCKind = parseRangeCheckICmp(L, ICI, SE, IndexVal, Length);
|
||||
|
||||
if (RCKind == 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