diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-12-19 22:40:28 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-12-19 22:40:28 +0000 |
commit | 1d8492ee7dc43304d92ffc91209f68d5b536d415 (patch) | |
tree | 1c4636d76a4882ba33af74b00110fc3996cd6bbf | |
parent | 269b8a6713b2bf8feac57f3b34456153b483f3c8 (diff) |
Nonnull elements in OperandBundleCallSites are not all Instructions
`CloneAndPruneIntoFromInst` sometimes RAUW's dead instructions with
`undef` before erasing them (to avoid deleting instructions that still
have uses). This changes the `WeakVH` in `OperandBundleCallSites` to
hold an `undef`, and we need to guard for this situation in eventuality
in `llvm::InlineFunction`.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256110 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Transforms/Utils/Cloning.h | 4 | ||||
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 5 | ||||
-rw-r--r-- | test/Transforms/Inline/deopt-bundles.ll | 36 |
3 files changed, 40 insertions, 5 deletions
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index d1a5fdeaddc..92a1d52f101 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -75,8 +75,8 @@ struct ClonedCodeInfo { bool ContainsDynamicAllocas; /// All cloned call sites that have operand bundles attached are appended to - /// this vector. This vector may contain nulls if some of the originally - /// inserted callsites were DCE'ed after they were cloned. + /// this vector. This vector may contain nulls or undefs if some of the + /// originally inserted callsites were DCE'ed after they were cloned. std::vector<WeakVH> OperandBundleCallSites; ClonedCodeInfo() : ContainsCalls(false), ContainsDynamicAllocas(false) {} diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index db2cacd4739..14574119b9a 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -1196,9 +1196,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, SmallVector<OperandBundleDef, 2> OpDefs; for (auto &VH : InlinedFunctionInfo.OperandBundleCallSites) { - if (!VH) continue; // instruction was DCE'd after being cloned - - Instruction *I = cast<Instruction>(VH); + Instruction *I = dyn_cast_or_null<Instruction>(VH); + if (!I) continue; // instruction was DCE'd or RAUW'ed to undef OpDefs.clear(); diff --git a/test/Transforms/Inline/deopt-bundles.ll b/test/Transforms/Inline/deopt-bundles.ll index 1acbb2f0585..3e3c52f7d2d 100644 --- a/test/Transforms/Inline/deopt-bundles.ll +++ b/test/Transforms/Inline/deopt-bundles.ll @@ -162,6 +162,42 @@ define i32 @caller_7() { ret i32 %x } +define i32 @callee_8(i1 %val) alwaysinline personality i8 3 { +; We want something that PruningFunctionCloner is not smart enough to +; recognize, but can be recognized by recursivelySimplifyInstruction. + + entry: + br i1 %val, label %check, label %precheck + + precheck: + br label %check + + check: + %p = phi i1 [ %val, %entry ], [ true, %precheck ] + br i1 %p, label %do.not, label %do + + do.not: + ret i32 0 + + do: + %phi = phi i32 [ 0, %check ], [ %v, %do ] + %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] + %ic = icmp eq i32 %v, 42 + br i1 %ic, label %do, label %done + + done: + ret i32 %phi +} + +define i32 @caller_8() { +; CHECK-LABEL: @caller_8( + entry: +; CHECK-NOT: call fastcc i32 @g.fastcc() +; CHECK: ret i32 0 + %x = call i32 @callee_8(i1 true) [ "deopt"(i32 7) ] + ret i32 %x +} + attributes #0 = { "foo"="bar" } ; CHECK: attributes #[[FOO_BAR_ATTR_IDX]] = { "foo"="bar" } |