Teach memdep to look for memory use intrinsics during dependency queries. Fixes

PR5574.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90045 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2009-11-28 21:27:49 +00:00
parent 0c264b16b0
commit d801c10de6
2 changed files with 49 additions and 10 deletions

View File

@ -201,7 +201,7 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
// If we reach a lifetime begin or end marker, then the query ends here
// because the value is undefined.
} else if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end) {
II->getIntrinsicID() == Intrinsic::lifetime_end) {
uint64_t invariantSize = ~0ULL;
if (ConstantInt *CI = dyn_cast<ConstantInt>(II->getOperand(1)))
invariantSize = CI->getZExtValue();
@ -369,20 +369,41 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
// calls to free() erase the entire structure, not just a field.
MemSize = ~0UL;
} else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
CallSite QueryCS = CallSite::get(QueryInst);
bool isReadOnly = AA->onlyReadsMemory(QueryCS);
LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
QueryParent);
int IntrinsicID = 0; // Intrinsic IDs start at 1.
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(QueryInst))
IntrinsicID = II->getIntrinsicID();
switch (IntrinsicID) {
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
case Intrinsic::invariant_start:
MemPtr = QueryInst->getOperand(2);
MemSize = cast<ConstantInt>(QueryInst->getOperand(1))->getZExtValue();
break;
case Intrinsic::invariant_end:
MemPtr = QueryInst->getOperand(3);
MemSize = cast<ConstantInt>(QueryInst->getOperand(2))->getZExtValue();
break;
default:
CallSite QueryCS = CallSite::get(QueryInst);
bool isReadOnly = AA->onlyReadsMemory(QueryCS);
LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
QueryParent);
}
} else {
// Non-memory instruction.
LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
}
// If we need to do a pointer scan, make it happen.
if (MemPtr)
LocalCache = getPointerDependencyFrom(MemPtr, MemSize,
isa<LoadInst>(QueryInst),
ScanPos, QueryParent);
if (MemPtr) {
bool isLoad = !QueryInst->mayWriteToMemory();
if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) {
isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end;
}
LocalCache = getPointerDependencyFrom(MemPtr, MemSize, isLoad, ScanPos,
QueryParent);
}
// Remember the result!
if (Instruction *I = LocalCache.getInst())

View File

@ -1,6 +1,9 @@
; RUN: opt -S -dse < %s | FileCheck %s
declare void @llvm.lifetime.end(i64, i8*)
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
declare void @llvm.memset.i8(i8*, i8, i8, i32)
define void @test1() {
@ -17,3 +20,18 @@ define void @test1() {
ret void
; CHECK: ret void
}
define void @test2(i32* %P) {
; CHECK: test2
%Q = getelementptr i32* %P, i32 1
%R = bitcast i32* %Q to i8*
call void @llvm.lifetime.start(i64 4, i8* %R)
; CHECK: lifetime.start
store i32 0, i32* %Q ;; This store is dead.
; CHECK-NOT: store
call void @llvm.lifetime.end(i64 4, i8* %R)
; CHECK: lifetime.end
ret void
}