Skip to content

Commit

Permalink
[InstCombine] Simplify foldOperationIntoSelectOperand() (NFCI)
Browse files Browse the repository at this point in the history
Rather than handling all instruction types separately, clone the
original instruction and replace the select operand.
  • Loading branch information
nikic committed Mar 21, 2023
1 parent 9f48562 commit d0de2c5
Showing 1 changed file with 8 additions and 41 deletions.
49 changes: 8 additions & 41 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1044,45 +1044,12 @@ static Constant *constantFoldOperationIntoSelectOperand(
return ConstantFoldInstOperands(&I, ConstOps, I.getModule()->getDataLayout());
}

static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
InstCombiner::BuilderTy &Builder) {
if (auto *Cast = dyn_cast<CastInst>(&I))
return Builder.CreateCast(Cast->getOpcode(), SO, I.getType());

if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
assert(canConstantFoldCallTo(II, cast<Function>(II->getCalledOperand())) &&
"Expected constant-foldable intrinsic");
Intrinsic::ID IID = II->getIntrinsicID();
if (II->arg_size() == 1)
return Builder.CreateUnaryIntrinsic(IID, SO);

// This works for real binary ops like min/max (where we always expect the
// constant operand to be canonicalized as op1) and unary ops with a bonus
// constant argument like ctlz/cttz.
// TODO: Handle non-commutative binary intrinsics as below for binops.
assert(II->arg_size() == 2 && "Expected binary intrinsic");
assert(isa<Constant>(II->getArgOperand(1)) && "Expected constant operand");
return Builder.CreateBinaryIntrinsic(IID, SO, II->getArgOperand(1));
}

if (auto *EI = dyn_cast<ExtractElementInst>(&I))
return Builder.CreateExtractElement(SO, EI->getIndexOperand());

assert(I.isBinaryOp() && "Unexpected opcode for select folding");

// Figure out if the constant is the left or the right argument.
bool ConstIsRHS = isa<Constant>(I.getOperand(1));
Constant *ConstOperand = cast<Constant>(I.getOperand(ConstIsRHS));

Value *Op0 = SO, *Op1 = ConstOperand;
if (!ConstIsRHS)
std::swap(Op0, Op1);

Value *NewBO = Builder.CreateBinOp(cast<BinaryOperator>(&I)->getOpcode(), Op0,
Op1, SO->getName() + ".op");
if (auto *NewBOI = dyn_cast<Instruction>(NewBO))
NewBOI->copyIRFlags(&I);
return NewBO;
static Value *foldOperationIntoSelectOperand(Instruction &I, SelectInst *SI,
Value *NewOp, InstCombiner &IC) {
Instruction *Clone = I.clone();
Clone->replaceUsesOfWith(SI, NewOp);
IC.InsertNewInstBefore(Clone, *SI);
return Clone;
}

Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
Expand Down Expand Up @@ -1162,9 +1129,9 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,

// Create an instruction for the arm that did not fold.
if (!NewTV)
NewTV = foldOperationIntoSelectOperand(Op, TV, Builder);
NewTV = foldOperationIntoSelectOperand(Op, SI, TV, *this);
if (!NewFV)
NewFV = foldOperationIntoSelectOperand(Op, FV, Builder);
NewFV = foldOperationIntoSelectOperand(Op, SI, FV, *this);
return SelectInst::Create(SI->getCondition(), NewTV, NewFV, "", nullptr, SI);
}

Expand Down

0 comments on commit d0de2c5

Please sign in to comment.