This is an archive of the discontinued LLVM Phabricator instance.

[ValueTracking] Improve isImpliedCondition for conditions with matching LHS operands and Immediate RHS operands.
AbandonedPublic

Authored by mcrosier on Apr 13 2016, 2:04 PM.

Details

Summary

This patch improves SimplifyCFG to catch things like:

if (a > 5) {
  if (a > 4) <- known to be true; remove branch
    alive();
}

and

if (a > 5) {
  if (a < 4) <- known to be false; remove branch and call
    dead();
}

This is very similar to (and has a dependency on) http://reviews.llvm.org/D18905.

Please take a look,
Chad

Diff Detail

Event Timeline

mcrosier updated this revision to Diff 53617.Apr 13 2016, 2:04 PM
mcrosier retitled this revision from to [ValueTracking] Improve isImpliedCondition for conditions with matching LHS operands and Immediate RHS operands..
mcrosier updated this object.
mcrosier added reviewers: sanjoy, reames, mssimpso, gberry.
mcrosier updated this object.
mcrosier added a subscriber: llvm-commits.

Hi Chad,

I think LazyValueInfo can figure out the branch direction in your test cases and then JumpThreading can optimize the CFG.

The related JumpThreading code is

JumpThreading.cpp

bool JumpThreading::ProcessBlock(BasicBlock *BB)

if (CmpInst *CondCmp = dyn_cast<CmpInst>(CondInst)) {
  // If we're branching on a conditional, LVI might be able to determine
  // it's value at the branch instruction.  We only handle comparisons
  // against a constant at this time.
  // TODO: This should be extended to handle switches as well.
  BranchInst *CondBr = dyn_cast<BranchInst>(BB->getTerminator());
  Constant *CondConst = dyn_cast<Constant>(CondCmp->getOperand(1));
  if (CondBr && CondConst && CondBr->isConditional()) {
    LazyValueInfo::Tristate Ret =
      LVI->getPredicateAt(CondCmp->getPredicate(), CondCmp->getOperand(0),
                          CondConst, CondBr);
    if (Ret != LazyValueInfo::Unknown) {
      unsigned ToRemove = Ret == LazyValueInfo::True ? 1 : 0;
      unsigned ToKeep = Ret == LazyValueInfo::True ? 0 : 1;
      CondBr->getSuccessor(ToRemove)->removePredecessor(BB, true);
      BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr);
      CondBr->eraseFromParent();
      if (CondCmp->use_empty())
        CondCmp->eraseFromParent();
      else if (CondCmp->getParent() == BB) {
        // If the fact we just learned is true for all uses of the
        // condition, replace it with a constant value
        auto *CI = Ret == LazyValueInfo::True ?
          ConstantInt::getTrue(CondCmp->getType()) :
          ConstantInt::getFalse(CondCmp->getType());
        CondCmp->replaceAllUsesWith(CI);
        CondCmp->eraseFromParent();
      }
      return true;
    }
  }

  if (CondBr && CondConst && TryToUnfoldSelect(CondCmp, BB))
    return true;
}

Best,

Haicheng

mcrosier added a comment.EditedApr 14 2016, 12:53 PM

I think LazyValueInfo can figure out the branch direction in your test cases and then JumpThreading can optimize the CFG.

Correct! Regardless, enabling this type of optimization in SimplifyCFG is worth while because SimplifyCFG is called much more frequently then Jump Threading. This has the potential to expose more opportunities later in the pipeline. It can also remove unreachable code earlier in the pipeline, which can save some compile time because we no longer analyze unreachable code. Once D18905 I was hoping to make a change to make SimplifyCFG that would catch a lot more cases.

The unfortunate part is that I don't think I can easily reuse the logic in LVI here.

mcrosier updated this object.Apr 14 2016, 12:54 PM
reames requested changes to this revision.Apr 18 2016, 5:03 PM
reames edited edge metadata.
reames added inline comments.
lib/Analysis/ValueTracking.cpp
3791

Comments to explain what this function does?

3796

Shift this check into caller and pass in ConstantInt arguments as appropriate.

3808

A more general framing of a lot of this logic would be to use ConstantFoldICmp. This wouldn't require the code duplication and would be more general.

This revision now requires changes to proceed.Apr 18 2016, 5:03 PM
mcrosier added inline comments.Apr 25 2016, 3:17 PM
lib/Analysis/ValueTracking.cpp
3808

I'll all for no reinventing the wheel, but I'm not sure what code you're referring to. Can you please point me in the right direction, Philip?

mcrosier abandoned this revision.Apr 27 2016, 6:15 AM

@bmakam's ongoing work will supersede this patch.