mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
enhance isRemovable to refuse to delete volatile mem transfers
now that DSE hacks on them. This fixes a regression I introduced, by generalizing DSE to hack on transfers. llvm-svn: 120445
This commit is contained in:
parent
7ae5c75ab7
commit
41b6b286a3
@ -152,12 +152,27 @@ getLocForWrite(Instruction *Inst, AliasAnalysis &AA) {
|
|||||||
/// isRemovable - If the value of this instruction and the memory it writes to
|
/// isRemovable - If the value of this instruction and the memory it writes to
|
||||||
/// is unused, may we delete this instruction?
|
/// is unused, may we delete this instruction?
|
||||||
static bool isRemovable(Instruction *I) {
|
static bool isRemovable(Instruction *I) {
|
||||||
assert(hasMemoryWrite(I));
|
// Don't remove volatile stores.
|
||||||
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
|
|
||||||
return II->getIntrinsicID() != Intrinsic::lifetime_end;
|
|
||||||
if (StoreInst *SI = dyn_cast<StoreInst>(I))
|
if (StoreInst *SI = dyn_cast<StoreInst>(I))
|
||||||
return !SI->isVolatile();
|
return !SI->isVolatile();
|
||||||
return true;
|
|
||||||
|
IntrinsicInst *II = cast<IntrinsicInst>(I);
|
||||||
|
switch (II->getIntrinsicID()) {
|
||||||
|
default: assert(0 && "doesn't pass 'hasMemoryWrite' predicate");
|
||||||
|
case Intrinsic::lifetime_end:
|
||||||
|
// Never remove dead lifetime_end's, e.g. because it is followed by a
|
||||||
|
// free.
|
||||||
|
return false;
|
||||||
|
case Intrinsic::init_trampoline:
|
||||||
|
// Always safe to remove init_trampoline.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Intrinsic::memset:
|
||||||
|
case Intrinsic::memmove:
|
||||||
|
case Intrinsic::memcpy:
|
||||||
|
// Don't remove volatile memory intrinsics.
|
||||||
|
return !cast<MemIntrinsic>(II)->isVolatile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getPointerOperand - Return the pointer that is being written to.
|
/// getPointerOperand - Return the pointer that is being written to.
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
; RUN: opt < %s -basicaa -dse -S | FileCheck %s
|
; RUN: opt < %s -basicaa -dse -S | FileCheck %s
|
||||||
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"
|
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.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
|
||||||
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
||||||
|
declare void @llvm.memset.i64(i8*, i8, i64, i32)
|
||||||
|
declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
|
||||||
|
declare i8* @llvm.init.trampoline(i8*, i8*, i8*)
|
||||||
|
|
||||||
define void @test1(i32* %Q, i32* %P) {
|
define void @test1(i32* %Q, i32* %P) {
|
||||||
%DEAD = load i32* %Q
|
%DEAD = load i32* %Q
|
||||||
store i32 %DEAD, i32* %P
|
store i32 %DEAD, i32* %P
|
||||||
@ -55,9 +61,6 @@ define void @test5(i32* %Q) {
|
|||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memset.i64(i8*, i8, i64, i32)
|
|
||||||
declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
|
|
||||||
|
|
||||||
; Should delete store of 10 even though memset is a may-store to P (P and Q may
|
; Should delete store of 10 even though memset is a may-store to P (P and Q may
|
||||||
; alias).
|
; alias).
|
||||||
define void @test6(i32 *%p, i8 *%q) {
|
define void @test6(i32 *%p, i8 *%q) {
|
||||||
@ -116,7 +119,6 @@ define double @test10(i8* %X) {
|
|||||||
|
|
||||||
|
|
||||||
; DSE should delete the dead trampoline.
|
; DSE should delete the dead trampoline.
|
||||||
declare i8* @llvm.init.trampoline(i8*, i8*, i8*)
|
|
||||||
declare void @test11f()
|
declare void @test11f()
|
||||||
define void @test11() {
|
define void @test11() {
|
||||||
; CHECK: @test11
|
; CHECK: @test11
|
||||||
@ -210,3 +212,13 @@ define void @test17(i8* %P, i8* %Q) nounwind ssp {
|
|||||||
; CHECK-NEXT: ret
|
; CHECK-NEXT: ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Should not delete the volatile memset.
|
||||||
|
define void @test17v(i8* %P, i8* %Q) nounwind ssp {
|
||||||
|
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 true)
|
||||||
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
||||||
|
ret void
|
||||||
|
; CHECK: @test17v
|
||||||
|
; CHECK-NEXT: call void @llvm.memset
|
||||||
|
; CHECK-NEXT: call void @llvm.memcpy
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user