forked from OSchip/llvm-project
[CVP] Allow two transforms in one invocation
For a call site which had both constant deopt operands and nonnull arguments, we were missing the opportunity to recognize the later by bailing early. This is somewhat of a speculative fix. Months ago, I'd had a private report of performance and compile time regressions from the deopt operand folding. I never received a test case. However, the only possibility I see was that after that change CVP missed the nonnull fold, and we end up with a pass ordering/missed simplification issue. So, since it's a real issue, fix it and hope.
This commit is contained in:
parent
bd08a87cfe
commit
e46d74b589
|
@ -524,8 +524,6 @@ static void processSaturatingInst(SaturatingInst *SI, LazyValueInfo *LVI) {
|
|||
|
||||
/// Infer nonnull attributes for the arguments at the specified callsite.
|
||||
static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
|
||||
SmallVector<unsigned, 4> ArgNos;
|
||||
unsigned ArgNo = 0;
|
||||
|
||||
if (auto *WO = dyn_cast<WithOverflowInst>(&CB)) {
|
||||
if (WO->getLHS()->getType()->isIntegerTy() && willNotOverflow(WO, LVI)) {
|
||||
|
@ -541,6 +539,8 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
// Deopt bundle operands are intended to capture state with minimal
|
||||
// perturbance of the code otherwise. If we can find a constant value for
|
||||
// any such operand and remove a use of the original value, that's
|
||||
|
@ -549,7 +549,6 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
|
|||
// idiomatically, appear along rare conditional paths, it's reasonable likely
|
||||
// we may have a conditional fact with which LVI can fold.
|
||||
if (auto DeoptBundle = CB.getOperandBundle(LLVMContext::OB_deopt)) {
|
||||
bool Progress = false;
|
||||
for (const Use &ConstU : DeoptBundle->Inputs) {
|
||||
Use &U = const_cast<Use&>(ConstU);
|
||||
Value *V = U.get();
|
||||
|
@ -559,12 +558,13 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
|
|||
Constant *C = LVI->getConstant(V, &CB);
|
||||
if (!C) continue;
|
||||
U.set(C);
|
||||
Progress = true;
|
||||
Changed = true;
|
||||
}
|
||||
if (Progress)
|
||||
return true;
|
||||
}
|
||||
|
||||
SmallVector<unsigned, 4> ArgNos;
|
||||
unsigned ArgNo = 0;
|
||||
|
||||
for (Value *V : CB.args()) {
|
||||
PointerType *Type = dyn_cast<PointerType>(V->getType());
|
||||
// Try to mark pointer typed parameters as non-null. We skip the
|
||||
|
@ -582,7 +582,7 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
|
|||
assert(ArgNo == CB.arg_size() && "sanity check");
|
||||
|
||||
if (ArgNos.empty())
|
||||
return false;
|
||||
return Changed;
|
||||
|
||||
AttributeList AS = CB.getAttributes();
|
||||
LLVMContext &Ctx = CB.getContext();
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
; RUN: opt -correlated-propagation -S < %s | FileCheck %s
|
||||
|
||||
declare void @use()
|
||||
declare void @use_ptr(i8*)
|
||||
|
||||
; test requires a mix of context sensative refinement, and analysis
|
||||
; of the originating IR pattern. Neither part is enough in isolation.
|
||||
define void @test1(i1 %c, i1 %c2) {
|
||||
|
@ -140,3 +142,23 @@ taken:
|
|||
untaken:
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define void @test5(i64 %a, i8* nonnull %p) {
|
||||
; CHECK-LABEL: @test5(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[A:%.*]], 0
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
|
||||
; CHECK: taken:
|
||||
; CHECK-NEXT: call void @use_ptr(i8* nonnull [[P:%.*]]) [ "deopt"(i64 0) ]
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: untaken:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%cmp = icmp eq i64 %a, 0
|
||||
br i1 %cmp, label %taken, label %untaken
|
||||
taken:
|
||||
call void @use_ptr(i8* %p) ["deopt" (i64 %a)]
|
||||
ret void
|
||||
untaken:
|
||||
ret void
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue