From 4d7257dfa111d14cc6e6091898f6564a4f01f23c Mon Sep 17 00:00:00 2001 From: David L Kreitzer Date: Thu, 21 Jan 2016 21:32:35 +0000 Subject: Fix for two constant propagation problems in GVN with the assume intrinsic instruction. Patch by Yuanrui Zhang. Differential Revision: http://reviews.llvm.org/D16100 llvm-svn: 258435 --- llvm/include/llvm/Transforms/Utils/Local.h | 2 +- llvm/lib/Transforms/Scalar/GVN.cpp | 7 +++--- llvm/lib/Transforms/Utils/Local.cpp | 2 +- llvm/test/Transforms/GVN/assume-equal.ll | 40 ++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) (limited to 'llvm') diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index 3ae01657a2e..6c217c9b350 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -316,7 +316,7 @@ void combineMetadata(Instruction *K, const Instruction *J, ArrayRef Kn unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge); /// \brief Replace each use of 'From' with 'To' if that use is dominated by -/// the given BasicBlock. Returns the number of replacements made. +/// the end of the given BasicBlock. Returns the number of replacements made. unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, const BasicBlock *BB); diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index a028b8c444b..5f55db64e05 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -2133,7 +2133,8 @@ bool GVN::replaceOperandsWithConsts(Instruction *Instr) const { /// The given values are known to be equal in every block /// dominated by 'Root'. Exploit this, for example by replacing 'LHS' with /// 'RHS' everywhere in the scope. Returns whether a change was made. -/// If DominatesByEdge is false, then it means that it is dominated by Root.End. +/// If DominatesByEdge is false, then it means that we will propagate the RHS +/// value starting from the end of Root.Start. bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root, bool DominatesByEdge) { SmallVector, 4> Worklist; @@ -2195,7 +2196,7 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root, unsigned NumReplacements = DominatesByEdge ? replaceDominatedUsesWith(LHS, RHS, *DT, Root) - : replaceDominatedUsesWith(LHS, RHS, *DT, Root.getEnd()); + : replaceDominatedUsesWith(LHS, RHS, *DT, Root.getStart()); Changed |= NumReplacements > 0; NumGVNEqProp += NumReplacements; @@ -2271,7 +2272,7 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root, DominatesByEdge ? replaceDominatedUsesWith(NotCmp, NotVal, *DT, Root) : replaceDominatedUsesWith(NotCmp, NotVal, *DT, - Root.getEnd()); + Root.getStart()); Changed |= NumReplacements > 0; NumGVNEqProp += NumReplacements; } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 3e695539f3e..ed941a7d61a 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1569,7 +1569,7 @@ unsigned llvm::replaceDominatedUsesWith(Value *From, Value *To, UI != UE;) { Use &U = *UI++; auto *I = cast(U.getUser()); - if (DT.dominates(BB, I->getParent())) { + if (DT.properlyDominates(BB, I->getParent())) { U.set(To); DEBUG(dbgs() << "Replace dominated use of '" << From->getName() << "' as " << *To << " in " << *U << "\n"); diff --git a/llvm/test/Transforms/GVN/assume-equal.ll b/llvm/test/Transforms/GVN/assume-equal.ll index f9304a8fc7c..d423c1685e1 100644 --- a/llvm/test/Transforms/GVN/assume-equal.ll +++ b/llvm/test/Transforms/GVN/assume-equal.ll @@ -226,6 +226,46 @@ bb3: ret i32 17 } +; This test checks if GVN can do the constant propagation correctly +; when there are multiple uses of the same assume value in the +; basic block that has a loop back-edge pointing to itself. +; +; CHECK-LABEL: define i32 @_Z1il(i32 %val, i1 %k) +define i32 @_Z1il(i32 %val, i1 %k) { + br label %next + +next: +; CHECK: tail call void @llvm.assume(i1 %k) +; CHECK-NEXT: %cmp = icmp eq i32 %val, 50 + tail call void @llvm.assume(i1 %k) + tail call void @llvm.assume(i1 %k) + %cmp = icmp eq i32 %val, 50 + br i1 %cmp, label %next, label %meh + +meh: + ret i32 0 +} + +; This test checks if GVN can prevent the constant propagation correctly +; in the successor blocks that are not dominated by the basic block +; with the assume instruction. +; +; CHECK-LABEL: define i1 @_z1im(i32 %val, i1 %k, i1 %j) +define i1 @_z1im(i32 %val, i1 %k, i1 %j) { + br i1 %j, label %next, label %meh + +next: +; CHECK: tail call void @llvm.assume(i1 %k) +; CHECK-NEXT: br label %meh + tail call void @llvm.assume(i1 %k) + tail call void @llvm.assume(i1 %k) + br label %meh + +meh: +; CHECK: ret i1 %k + ret i1 %k +} + declare noalias i8* @_Znwm(i64) declare void @_ZN1AC1Ev(%struct.A*) declare void @llvm.assume(i1) -- cgit v1.2.3