diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/IR/CallSite.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Analysis/LoopInfo.cpp | 19 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnswitch.cpp | 5 | ||||
| -rw-r--r-- | llvm/test/Transforms/LoopUnroll/unroll-cleanuppad.ll | 40 |
4 files changed, 56 insertions, 16 deletions
diff --git a/llvm/include/llvm/IR/CallSite.h b/llvm/include/llvm/IR/CallSite.h index ad66cfbfaad..1a08434a31d 100644 --- a/llvm/include/llvm/IR/CallSite.h +++ b/llvm/include/llvm/IR/CallSite.h @@ -426,6 +426,14 @@ public: CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); } + /// @brief Determine if the call can be duplicated. + bool cannotDuplicate() const { + CALLSITE_DELEGATE_GETTER(cannotDuplicate()); + } + void setCannotDuplicate() { + CALLSITE_DELEGATE_GETTER(setCannotDuplicate()); + } + /// @brief Determine if the call is convergent. bool isConvergent() const { CALLSITE_DELEGATE_GETTER(isConvergent()); diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 277bd0dbb0f..2ac1ae2e5cf 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -195,23 +195,10 @@ bool Loop::isSafeToClone() const { if (isa<IndirectBrInst>(BB->getTerminator())) return false; - if (const InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) { - if (II->cannotDuplicate()) - return false; - // Return false if any loop blocks contain invokes to EH-pads other than - // landingpads; we don't know how to split those edges yet. - auto *FirstNonPHI = II->getUnwindDest()->getFirstNonPHI(); - if (FirstNonPHI->isEHPad() && !isa<LandingPadInst>(FirstNonPHI)) - return false; - } - for (Instruction &I : *BB) { - if (const CallInst *CI = dyn_cast<CallInst>(&I)) { - if (CI->cannotDuplicate()) + for (Instruction &I : *BB) + if (auto CS = CallSite(&I)) + if (CS.cannotDuplicate()) return false; - } - if (I.getType()->isTokenTy() && I.isUsedOutsideOfBlock(BB)) - return false; - } } return true; } diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index 310f41ed7df..0e861b638d6 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -500,6 +500,11 @@ bool LoopUnswitch::processCurrentLoop() { if (!CS) continue; if (CS.hasFnAttr(Attribute::Convergent)) return false; + // Return false if any loop blocks contain invokes whose predecessor edges + // we cannot split. + if (auto *II = dyn_cast<InvokeInst>(&I)) + if (!II->getUnwindDest()->canSplitPredecessors()) + return false; } } diff --git a/llvm/test/Transforms/LoopUnroll/unroll-cleanuppad.ll b/llvm/test/Transforms/LoopUnroll/unroll-cleanuppad.ll new file mode 100644 index 00000000000..67f3194f474 --- /dev/null +++ b/llvm/test/Transforms/LoopUnroll/unroll-cleanuppad.ll @@ -0,0 +1,40 @@ +; RUN: opt -S -loop-unroll %s | FileCheck %s +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc18.0.0" + +define void @test1() personality i32 (...)* @__CxxFrameHandler3 { +entry: + br label %for.body + +for.body: ; preds = %entry, %for.inc + %phi = phi i32 [ 0, %entry ], [ %inc, %for.inc ] + invoke void @callee(i32 %phi) + to label %for.inc unwind label %ehcleanup + +for.inc: ; preds = %for.body + %inc = add nuw nsw i32 %phi, 1 + %cmp = icmp slt i32 %inc, 3 + br i1 %cmp, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.inc + call void @dtor() + ret void + +ehcleanup: ; preds = %for.body + %cp = cleanuppad within none [] + call void @dtor() [ "funclet"(token %cp) ] + cleanupret from %cp unwind to caller +} + +; CHECK-LABEL: define void @test1( +; CHECK: invoke void @callee(i32 0 + +; CHECK: invoke void @callee(i32 1 + +; CHECK: invoke void @callee(i32 2 + +declare void @callee(i32) + +declare i32 @__CxxFrameHandler3(...) + +declare void @dtor() |

