diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 6a8f3763926..1e1dca2ebab 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -320,6 +320,28 @@ namespace llvm { } }; + /// MemoryUseIntrinsic - This is the common base class for the memory use + /// marker intrinsics. + /// + struct MemoryUseIntrinsic : public IntrinsicInst { + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const MemoryUseIntrinsic *) { return true; } + static inline bool classof(const IntrinsicInst *I) { + switch (I->getIntrinsicID()) { + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + case Intrinsic::invariant_start: + case Intrinsic::invariant_end: + return true; + default: return false; + } + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + }; + } #endif diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 0167ea0bcb2..aef0f5f03c2 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -252,6 +252,9 @@ bool llvm::isInstructionTriviallyDead(Instruction *I) { // We don't want debug info removed by anything this general. if (isa(I)) return false; + // Likewise for memory use markers. + if (isa(I)) return false; + if (!I->mayHaveSideEffects()) return true; // Special case intrinsics that "may have side effects" but can be deleted diff --git a/test/Transforms/InstCombine/invariant.ll b/test/Transforms/InstCombine/invariant.ll new file mode 100644 index 00000000000..c67ad331959 --- /dev/null +++ b/test/Transforms/InstCombine/invariant.ll @@ -0,0 +1,16 @@ +; Test to make sure unused llvm.invariant.start calls are not trivially eliminated +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare void @g(i8*) + +declare { }* @llvm.invariant.start(i64, i8* nocapture) nounwind readonly + +define i8 @f() { + %a = alloca i8 ; [#uses=4] + store i8 0, i8* %a + %i = call { }* @llvm.invariant.start(i64 1, i8* %a) ; <{ }*> [#uses=0] + ; CHECK: call { }* @llvm.invariant.start + call void @g(i8* %a) + %r = load i8* %a ; [#uses=1] + ret i8 %r +}