Repository: llvm/llvm-project
File: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (C++)

Code before:
  if (!NewC)
    return nullptr;

  // Make a new binop in the predecessor block with the non-constant incoming
  // values.
  Builder.SetInsertPoint(PredBlockBranch);
  Value *NewBO = Builder.CreateBinOp(BO.getOpcode(),
                                     Phi0->getIncomingValueForBlock(OtherBB),
                                     Phi1->getIncomingValueForBlock(OtherBB));
  if (auto *NotFoldedNewBO = dyn_cast<BinaryOperator>(NewBO))
    NotFoldedNewBO->copyIRFlags(&BO);

  // Replace the binop with a phi of the new values. The old phis are dead.
  PHINode *NewPhi = PHINode::Create(BO.getType(), 2);
  NewPhi->addIncoming(NewBO, OtherBB);
  NewPhi->addIncoming(NewC, ConstBB);
  return NewPhi;
}

Instruction *InstCombinerImpl::foldBinOpIntoSelectOrPhi(BinaryOperator &I) {
  auto TryFoldOperand = [&](unsigned OpIdx, bool IsOtherParamConst) {
    if (auto *Sel = dyn_cast<SelectInst>(I.getOperand(OpIdx)))
      return FoldOpIntoSelect(I, Sel, false, !IsOtherParamConst);
    if (auto *PN = dyn_cast<PHINode>(I.getOperand(OpIdx)))
      return foldOpIntoPhi(I, PN);
    return static_cast<Instruction *>(nullptr);
  };

  if (Instruction *NewI =
          TryFoldOperand(/*OpIdx=*/0, isa<Constant>(I.getOperand(1))))
    return NewI;
  if (I.isCommutative())
    return TryFoldOperand(/*OpIdx=*/1, isa<Constant>(I.getOperand(0)));
  return nullptr;
}

static bool shouldMergeGEPs(GEPOperator &GEP, GEPOperator &Src) {
  // If this GEP has only 0 indices, it is the same pointer as
  // Src. If Src is not a trivial GEP too, don't combine
  // the indices.
  if (GEP.hasAllZeroIndices() && !Src.hasAllZeroIndices() &&
      !Src.hasOneUse())
    return false;
  return true;
}

/// Find a constant NewC that has property:
///   shuffle(NewC, ShMask) = C
/// Returns nullptr if such a constant does not exist e.g. ShMask=<0,0> C=<1,2>
///
/// A 1-to-1 mapping is not required. Example:

Review comment (bug):
Add `-> Instruction *` to the lambda if it doesn't work with a plain `return nullptr`.

Code after:
  if (!NewC)
    return nullptr;

  // Make a new binop in the predecessor block with the non-constant incoming
  // values.
  Builder.SetInsertPoint(PredBlockBranch);
  Value *NewBO = Builder.CreateBinOp(BO.getOpcode(),
                                     Phi0->getIncomingValueForBlock(OtherBB),
                                     Phi1->getIncomingValueForBlock(OtherBB));
  if (auto *NotFoldedNewBO = dyn_cast<BinaryOperator>(NewBO))
    NotFoldedNewBO->copyIRFlags(&BO);

  // Replace the binop with a phi of the new values. The old phis are dead.
  PHINode *NewPhi = PHINode::Create(BO.getType(), 2);
  NewPhi->addIncoming(NewBO, OtherBB);
  NewPhi->addIncoming(NewC, ConstBB);
  return NewPhi;
}

Instruction *InstCombinerImpl::foldBinOpIntoSelectOrPhi(BinaryOperator &I) {
  auto TryFoldOperand = [&](unsigned OpIdx,
                            bool IsOtherParamConst) -> Instruction * {
    if (auto *Sel = dyn_cast<SelectInst>(I.getOperand(OpIdx)))
      return FoldOpIntoSelect(I, Sel, false, !IsOtherParamConst);
    if (auto *PN = dyn_cast<PHINode>(I.getOperand(OpIdx)))
      return foldOpIntoPhi(I, PN);
    return nullptr;
  };

  if (Instruction *NewI =
          TryFoldOperand(/*OpIdx=*/0, isa<Constant>(I.getOperand(1))))
    return NewI;
  return TryFoldOperand(/*OpIdx=*/1, isa<Constant>(I.getOperand(0)));
}

static bool shouldMergeGEPs(GEPOperator &GEP, GEPOperator &Src) {
  // If this GEP has only 0 indices, it is the same pointer as
  // Src. If Src is not a trivial GEP too, don't combine
  // the indices.
  if (GEP.hasAllZeroIndices() && !Src.hasAllZeroIndices() &&
      !Src.hasOneUse())
    return false;
  return true;
}

/// Find a constant NewC that has property:
///   shuffle(NewC, ShMask) = C
/// Returns nullptr if such a constant does not exist e.g. ShMask=<0,0> C=<1,2>
///
/// A 1-to-1 mapping is not required. Example:
/// ShMask = <1,1,2,2> and C = <5,5,6,6> --> NewC = <poison,5,6,poison>