From 64f5ed172a66f9687d1d70253b7faae2dd2064ba Mon Sep 17 00:00:00 2001 From: Geoff Berry Date: Wed, 31 Aug 2016 17:45:31 +0000 Subject: [PATCH] [EarlyCSE] Allow forwarding a non-invariant load into an invariant load. Reviewers: sanjoy Subscribers: mcrosier, llvm-commits Differential Revision: https://reviews.llvm.org/D23935 llvm-svn: 280265 --- llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 10 +++++----- llvm/test/Transforms/EarlyCSE/invariant-loads.ll | 10 +++------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp index 0a8a750..f57b895 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 04c7dd1..3261b92 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) -- 2.7.4