llvm.org GIT mirror llvm / 55ee75d
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120445 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 8 years ago
2 changed file(s) with 35 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
151151 /// isRemovable - If the value of this instruction and the memory it writes to
152152 /// is unused, may we delete this instruction?
153153 static bool isRemovable(Instruction *I) {
154 assert(hasMemoryWrite(I));
155 if (IntrinsicInst *II = dyn_cast(I))
156 return II->getIntrinsicID() != Intrinsic::lifetime_end;
154 // Don't remove volatile stores.
157155 if (StoreInst *SI = dyn_cast(I))
158156 return !SI->isVolatile();
159 return true;
157
158 IntrinsicInst *II = cast(I);
159 switch (II->getIntrinsicID()) {
160 default: assert(0 && "doesn't pass 'hasMemoryWrite' predicate");
161 case Intrinsic::lifetime_end:
162 // Never remove dead lifetime_end's, e.g. because it is followed by a
163 // free.
164 return false;
165 case Intrinsic::init_trampoline:
166 // Always safe to remove init_trampoline.
167 return true;
168
169 case Intrinsic::memset:
170 case Intrinsic::memmove:
171 case Intrinsic::memcpy:
172 // Don't remove volatile memory intrinsics.
173 return !cast(II)->isVolatile();
174 }
160175 }
161176
162177 /// getPointerOperand - Return the pointer that is being written to.
0 ; RUN: opt < %s -basicaa -dse -S | FileCheck %s
11 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"
2
3 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
4 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
5 declare void @llvm.memset.i64(i8*, i8, i64, i32)
6 declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
7 declare i8* @llvm.init.trampoline(i8*, i8*, i8*)
28
39 define void @test1(i32* %Q, i32* %P) {
410 %DEAD = load i32* %Q
5359 ; CHECK-NEXT: volatile load
5460 ; CHECK-NEXT: ret void
5561 }
56
57 declare void @llvm.memset.i64(i8*, i8, i64, i32)
58 declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
5962
6063 ; Should delete store of 10 even though memset is a may-store to P (P and Q may
6164 ; alias).
115118
116119
117120 ; DSE should delete the dead trampoline.
118 declare i8* @llvm.init.trampoline(i8*, i8*, i8*)
119121 declare void @test11f()
120122 define void @test11() {
121123 ; CHECK: @test11
209211 ; CHECK-NEXT: ret
210212 }
211213
214 ; Should not delete the volatile memset.
215 define void @test17v(i8* %P, i8* %Q) nounwind ssp {
216 tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 true)
217 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
218 ret void
219 ; CHECK: @test17v
220 ; CHECK-NEXT: call void @llvm.memset
221 ; CHECK-NEXT: call void @llvm.memcpy
222 ; CHECK-NEXT: ret
223 }