[IndVarSimply] Fix assert/release build difference.

In builds with assertions enabled (!NDEBUG), IndVarSimplify does an
additional query to ScalarEvolution which may change future SCEV queries
since it fills the internal cache differently. The result is actually
only used with the -verify-indvars command line option. We fix the issue
by only calling SE->getBackedgeTakenCount(L) if -verify-indvars is
enabled such that only -verify-indvars shows the behavior, but not debug
builds themselves. Also add a remark to the description of
-verify-indvars about this behavior.

Fixes llvm.org/PR44815

Differential Revision: https://reviews.llvm.org/D74810
This commit is contained in:
Michael Kruse 2020-02-19 14:20:55 -06:00
parent f5678d4a6a
commit e4d20ec8ad
2 changed files with 48 additions and 3 deletions

View File

@ -102,8 +102,10 @@ STATISTIC(NumElimIV , "Number of congruent IVs eliminated");
// implement a strong expression equivalence checker in SCEV. Until then, we
// use the verify-indvars flag, which may assert in some cases.
static cl::opt<bool> VerifyIndvars(
"verify-indvars", cl::Hidden,
cl::desc("Verify the ScalarEvolution result after running indvars"));
"verify-indvars", cl::Hidden,
cl::desc("Verify the ScalarEvolution result after running indvars. Has no "
"effect in release builds. (Note: this adds additional SCEV "
"queries potentially changing the analysis result)"));
static cl::opt<ReplaceExitVal> ReplaceExitValue(
"replexitval", cl::Hidden, cl::init(OnlyCheapRepl),
@ -2663,7 +2665,12 @@ bool IndVarSimplify::run(Loop *L) {
#ifndef NDEBUG
// Used below for a consistency check only
const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
// Note: Since the result returned by ScalarEvolution may depend on the order
// in which previous results are added to its cache, the call to
// getBackedgeTakenCount() may change following SCEV queries.
const SCEV *BackedgeTakenCount;
if (VerifyIndvars)
BackedgeTakenCount = SE->getBackedgeTakenCount(L);
#endif
bool Changed = false;

View File

@ -0,0 +1,38 @@
; RUN: opt -indvars -stats -disable-output < %s 2>&1 | FileCheck %s --check-prefix=STATS
; RUN: opt -indvars -S < %s | FileCheck %s --check-prefix=IR
; REQUIRES: asserts
; Check that IndVarSimplify's result is not influenced by stray calls to
; ScalarEvolution in debug builds. However, -verify-indvars may still do
; such calls.
; llvm.org/PR44815
; STATS: 1 scalar-evolution - Number of loops with trip counts computed by force
; STATS: 2 scalar-evolution - Number of loops with predictable loop counts
; In this test, adding -verify-indvars causes %tmp13 to not be optimized away.
; IR-LABEL: @foo
; IR-NOT: phi i32
target triple = "x86_64-unknown-linux-gnu"
@b = external dso_local local_unnamed_addr global i32
define dso_local void @foo() {
tmp0:
br label %tmp12
tmp7:
%tmp8 = add nuw nsw i32 %tmp13, 1
store i32 undef, i32* @b
br label %tmp12
tmp12:
%tmp13 = phi i32 [ 2, %tmp0 ], [ %tmp8, %tmp7 ]
%tmp14 = phi i32 [ 1, %tmp0 ], [ %tmp13, %tmp7 ]
%tmp15 = icmp ult i32 %tmp14, undef
br i1 %tmp15, label %tmp7, label %tmp16
tmp16:
ret void
}