diff options
-rw-r--r-- | llvm/docs/LangRef.rst | 7 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LowerGuardIntrinsic.cpp | 3 | ||||
-rw-r--r-- | llvm/test/Transforms/LowerGuardIntrinsic/basic.ll | 12 |
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 +} |