[llvm-commits] [llvm] r120498 - in /llvm/trunk: lib/Transforms/Scalar/DeadStoreElimination.cpp test/Transforms/DeadStoreElimination/PartialStore.ll
Chris Lattner
sabre at nondot.org
Tue Nov 30 15:43:23 PST 2010
Author: lattner
Date: Tue Nov 30 17:43:23 2010
New Revision: 120498
URL: http://llvm.org/viewvc/llvm-project?rev=120498&view=rev
Log:
Enhance DSE to handle the variable index case in PR8657.
Modified:
llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll
Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=120498&r1=120497&r2=120498&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Nov 30 17:43:23 2010
@@ -19,6 +19,7 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Pass.h"
@@ -255,6 +256,17 @@
return TD->getTypeAllocSize(PT->getElementType());
}
+/// isObjectPointerWithTrustworthySize - Return true if the specified Value* is
+/// pointing to an object with a pointer size we can trust.
+static bool isObjectPointerWithTrustworthySize(const Value *V) {
+ if (const AllocaInst *AI = dyn_cast<AllocaInst>(V))
+ return !AI->isArrayAllocation();
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+ return !GV->isWeakForLinker();
+ if (const Argument *A = dyn_cast<Argument>(V))
+ return A->hasByValAttr();
+ return false;
+}
/// isCompleteOverwrite - Return true if a store to the 'Later' location
/// completely overwrites a store to the 'Earlier' location.
@@ -289,12 +301,29 @@
// larger than the earlier one.
if (Later.Size == AliasAnalysis::UnknownSize ||
Earlier.Size == AliasAnalysis::UnknownSize ||
- Later.Size <= Earlier.Size ||
- AA.getTargetData() == 0)
+ Later.Size <= Earlier.Size || AA.getTargetData() == 0)
return false;
+ // Check to see if the later store is to the entire object (either a global,
+ // an alloca, or a byval argument). If so, then it clearly overwrites any
+ // other store to the same object.
const TargetData &TD = *AA.getTargetData();
+ const Value *UO1 = P1->getUnderlyingObject(), *UO2 = P2->getUnderlyingObject();
+
+ // If we can't resolve the same pointers to the same object, then we can't
+ // analyze them at all.
+ if (UO1 != UO2)
+ return false;
+
+ // If the "Later" store is to a recognizable object, get its size.
+ if (isObjectPointerWithTrustworthySize(UO2)) {
+ uint64_t ObjectSize =
+ TD.getTypeAllocSize(cast<PointerType>(UO2->getType())->getElementType());
+ if (ObjectSize == Later.Size)
+ return true;
+ }
+
// Okay, we have stores to two completely different pointers. Try to
// decompose the pointer into a "base + constant_offset" form. If the base
// pointers are equal, then we can reason about the two stores.
Modified: llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll?rev=120498&r1=120497&r2=120498&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll (original)
+++ llvm/trunk/test/Transforms/DeadStoreElimination/PartialStore.ll Tue Nov 30 17:43:23 2010
@@ -52,3 +52,20 @@
store double 0.0, double* %Q
ret void
}
+
+; PR8657
+declare void @test5a(i32*)
+define void @test5(i32 %i) nounwind ssp {
+ %A = alloca i32
+ %B = bitcast i32* %A to i8*
+ %C = getelementptr i8* %B, i32 %i
+ store i8 10, i8* %C ;; Dead store to variable index.
+ store i32 20, i32* %A
+
+ call void @test5a(i32* %A)
+ ret void
+; CHECK: @test5(
+; CHECK-NEXT: alloca
+; CHECK-NEXT: store i32 20
+; CHECK-NEXT: call void @test5a
+}
More information about the llvm-commits
mailing list