mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
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`. llvm-svn: 256110
This commit is contained in:
parent
378d350613
commit
d080ee893d
@ -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) {}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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" }
|
||||
|
Loading…
Reference in New Issue
Block a user