summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/IntrinsicInst.h22
-rw-r--r--lib/Transforms/Utils/Local.cpp3
-rw-r--r--test/Transforms/InstCombine/invariant.ll16
3 files changed, 41 insertions, 0 deletions
diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h
index 6a8f376392..1e1dca2eba 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<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
}
#endif
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 0167ea0bcb..aef0f5f03c 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<DbgInfoIntrinsic>(I)) return false;
+ // Likewise for memory use markers.
+ if (isa<MemoryUseIntrinsic>(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 0000000000..c67ad33195
--- /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 ; <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 ; <i8> [#uses=1]
+ ret i8 %r
+}