summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-04-30 00:55:59 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-04-30 00:55:59 +0000
commit47cf2affbdb8a8152b84965134282581692baace (patch)
tree7f35f302fead07fd1a2695b9749d6e44e0d47d08
parent1befea2bdcb2514298441fd15adf89e65548faeb (diff)
downloadbcm5719-llvm-47cf2affbdb8a8152b84965134282581692baace.tar.gz
bcm5719-llvm-47cf2affbdb8a8152b84965134282581692baace.zip
[LowerGuardIntrinsics] Keep track of !make.implicit metadata
If a guard call being lowered by LowerGuardIntrinsics has the `!make.implicit` metadata attached, then reattach the metadata to the branch in the resulting expanded form of the intrinsic. This allows us to implement null checks as guards and still get the benefit of implicit null checks. llvm-svn: 268148
-rw-r--r--llvm/docs/LangRef.rst7
-rw-r--r--llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp3
-rw-r--r--llvm/test/Transforms/LowerGuardIntrinsic/basic.ll12
3 files changed, 21 insertions, 1 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index dc8b4d14bc0..7c6ff7a72c3 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -12375,7 +12375,7 @@ equivalent to:
define void @llvm.experimental.guard(i1 %pred, <args...>) {
%realPred = and i1 %pred, undef
- br i1 %realPred, label %continue, label %leave
+ br i1 %realPred, label %continue, label %leave [, !make.implicit !{}]
leave:
call void @llvm.experimental.deoptimize(<args...>) [ "deopt"() ]
@@ -12385,6 +12385,11 @@ equivalent to:
ret void
}
+
+with the optional ``[, !make.implicit !{}]`` present if and only if it
+is present on the call site. For more details on ``!make.implicit``,
+see :doc:`FaultMaps`.
+
In words, ``@llvm.experimental.guard`` executes the attached
``"deopt"`` continuation if (but **not** only if) its first argument
is ``false``. Since the optimizer is allowed to replace the ``undef``
diff --git a/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp b/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp
index a58346c2b1c..7ba17069f42 100644
--- a/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp
+++ b/llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp
@@ -56,6 +56,9 @@ static void MakeGuardControlFlowExplicit(Function *DeoptIntrinsic,
CheckBI->getSuccessor(0)->setName("guarded");
CheckBI->getSuccessor(1)->setName("deopt");
+ if (auto *MD = CI->getMetadata(LLVMContext::MD_make_implicit))
+ CheckBI->setMetadata(LLVMContext::MD_make_implicit, MD);
+
IRBuilder<> B(DeoptBlockTerm);
auto *DeoptCall = B.CreateCall(DeoptIntrinsic, Args, {DeoptOB}, "");
diff --git a/llvm/test/Transforms/LowerGuardIntrinsic/basic.ll b/llvm/test/Transforms/LowerGuardIntrinsic/basic.ll
index ae696cf4269..ade24eb7b22 100644
--- a/llvm/test/Transforms/LowerGuardIntrinsic/basic.ll
+++ b/llvm/test/Transforms/LowerGuardIntrinsic/basic.ll
@@ -60,3 +60,15 @@ define i32 @f_zero_args(i1* %c_ptr) {
; CHECK: guarded:
; CHECK-NEXT: ret i32 500
}
+
+define i8 @f_with_make_implicit_md(i32* %ptr) {
+; CHECK-LABEL: @f_with_make_implicit_md(
+; CHECK: br i1 %notNull, label %guarded, label %deopt, !make.implicit !0
+; CHECK: deopt:
+; CHECK-NEXT: %deoptcall = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i32 1) ]
+; CHECK-NEXT: ret i8 %deoptcall
+
+ %notNull = icmp ne i32* %ptr, null
+ call void(i1, ...) @llvm.experimental.guard(i1 %notNull, i32 1) [ "deopt"(i32 1) ], !make.implicit !{}
+ ret i8 5
+}
OpenPOWER on IntegriCloud