summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/Scalar/EarlyCSE.cpp10
-rw-r--r--llvm/test/Transforms/EarlyCSE/invariant-loads.ll10
2 files changed, 8 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 0a8a7508c19..f57b89556fb 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -644,13 +644,13 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
// generation or the load is known to be from an invariant location,
// replace this instruction.
//
- // A dominating invariant load implies that the location loaded from is
- // unchanging beginning at the point of the invariant load, so the load
- // we're CSE'ing _away_ does not need to be invariant, only the available
- // load we're CSE'ing _to_ does.
+ // If either the dominating load or the current load are invariant, then
+ // we can assume the current load loads the same value as the dominating
+ // load.
LoadValue InVal = AvailableLoads.lookup(MemInst.getPointerOperand());
if (InVal.DefInst != nullptr &&
- (InVal.Generation == CurrentGeneration || InVal.IsInvariant) &&
+ (InVal.Generation == CurrentGeneration ||
+ InVal.IsInvariant || MemInst.isInvariantLoad()) &&
InVal.MatchingId == MemInst.getMatchingId() &&
// We don't yet handle removing loads with ordering of any kind.
!MemInst.isVolatile() && MemInst.isUnordered() &&
diff --git a/llvm/test/Transforms/EarlyCSE/invariant-loads.ll b/llvm/test/Transforms/EarlyCSE/invariant-loads.ll
index 04c7dd1372d..3261b926d88 100644
--- a/llvm/test/Transforms/EarlyCSE/invariant-loads.ll
+++ b/llvm/test/Transforms/EarlyCSE/invariant-loads.ll
@@ -20,9 +20,7 @@ define void @f_0(i32* %ptr) {
}
define void @f_1(i32* %ptr) {
-; We can forward invariant loads to non-invariant loads, since once an
-; invariant load has executed, the location loaded from is known to be
-; unchanging.
+; We can forward invariant loads to non-invariant loads.
; CHECK-LABEL: @f_1(
; CHECK: %val0 = load i32, i32* %ptr, !invariant.load !0
@@ -37,14 +35,12 @@ define void @f_1(i32* %ptr) {
}
define void @f_2(i32* %ptr) {
-; Negative test -- we can't forward a non-invariant load into an
-; invariant load.
+; We can forward a non-invariant load into an invariant load.
; CHECK-LABEL: @f_2(
; CHECK: %val0 = load i32, i32* %ptr
; CHECK: call void @clobber_and_use(i32 %val0)
-; CHECK: %val1 = load i32, i32* %ptr, !invariant.load !0
-; CHECK: call void @clobber_and_use(i32 %val1)
+; CHECK: call void @clobber_and_use(i32 %val0)
%val0 = load i32, i32* %ptr
call void @clobber_and_use(i32 %val0)
OpenPOWER on IntegriCloud