mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Enhance DSE to handle the variable index case in PR8657.
llvm-svn: 120498
This commit is contained in:
parent
ce4e8350aa
commit
c888f3ec58
@ -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 @@ static uint64_t getPointerSize(Value *V, AliasAnalysis &AA) {
|
||||
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 @@ static bool isCompleteOverwrite(const AliasAnalysis::Location &Later,
|
||||
// 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.
|
||||
|
@ -52,3 +52,20 @@ define void @test4(i8* %P) {
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user