From: Sanjoy Das Date: Tue, 24 Mar 2015 19:29:18 +0000 (+0000) Subject: [IRCE] Fix a regression introduced in r232444. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=33a864aae22acdca97244e8cca29b1b9a26ab881;p=oota-llvm.git [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 --- diff --git a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index aa3a029fc88..a7c02433d37 100644 --- a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -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(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(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; diff --git a/test/Transforms/IRCE/bug-loop-varying-upper-limit.ll b/test/Transforms/IRCE/bug-loop-varying-upper-limit.ll new file mode 100644 index 00000000000..4635bb4381e --- /dev/null +++ b/test/Transforms/IRCE/bug-loop-varying-upper-limit.ll @@ -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}