[PATCH] D153963: [InstCombine] Fold binop of select and cast of select condition

Noah Goldstein via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 8 09:47:38 PDT 2023


goldstein.w.n added a comment.

So I'm going to propose something slightly different for accomplishing this patch.
Instead of making a combine for binops, I think you can just arbitrarily
constant propagate any usage of `cond` to the true/false arms.

I would suggest something along the following lines (pseudo code):

  if (TrueVal->hasOneUse()) {
    SmallVector<std::optional<bool>> TrueReplacements;
    bool DoReplace = false;
    for (Value *Op : TrueVal->Operands()) {
      if (Op == CondVal || match(Op, m_ZExt(m_Specific(CondVal)))) {
        TrueReplacements.emplace_back(true);
        DoReplace = true;
      } else if (match(Op, m_SExt(m_Specific(CondVal)))) {
        TrueReplacements.emplace_back(false);
        DoReplace = true;
  
      } else
        TrueReplacements.emplace_back(std::nullopt);
    }
    if (DoReplace) {
      SmallVector<Value *> TrueOps;
      for (unsigned I = 0; I < TrueVal->numOperands(); ++I) {
        if (TrueReplacements[I]) {
          TrueOps->emplace_back(*TrueReplacement[I] ? Constant::getOneValue(Ty)
                                                    : Constant::getAllOnes(Ty));
        } else {
                TrueOps->emplace_back(TrueVal->getOperand(I);
        }
      }
      NewTrue = Builder.Create(TrueVal->getOpcode(), TrueOps);
    }
  }

For false its always replace with zero.
Maybe put this in a lambda and if you get new true/false vals
then create new instructions.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153963/new/

https://reviews.llvm.org/D153963



More information about the llvm-commits mailing list