Skip to content

Commit 3f23c7f

Browse files
committed
[InstSimplify] Actually use NewOps for calls in simplifyInstructionWithOperands
Resolves a TODO. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D146599
1 parent 0528087 commit 3f23c7f

File tree

4 files changed

+72
-64
lines changed

4 files changed

+72
-64
lines changed

llvm/include/llvm/Analysis/InstructionSimplify.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,9 @@ Value *simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
302302
Value *simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, FastMathFlags FMF,
303303
const SimplifyQuery &Q);
304304

305-
/// Given a callsite, fold the result or return null.
306-
Value *simplifyCall(CallBase *Call, const SimplifyQuery &Q);
305+
/// Given a callsite, callee, and arguments, fold the result or return null.
306+
Value *simplifyCall(CallBase *Call, Value *Callee, ArrayRef<Value *> Args,
307+
const SimplifyQuery &Q);
307308

308309
/// Given a constrained FP intrinsic call, tries to compute its simplified
309310
/// version. Returns a simplified result or null.

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6391,10 +6391,13 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
63916391
return nullptr;
63926392
}
63936393

6394-
static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
6395-
6396-
unsigned NumOperands = Call->arg_size();
6397-
Function *F = cast<Function>(Call->getCalledFunction());
6394+
static Value *simplifyIntrinsic(CallBase *Call, Value *Callee,
6395+
ArrayRef<Value *> Args,
6396+
const SimplifyQuery &Q) {
6397+
// Operand bundles should not be in Args.
6398+
assert(Call->arg_size() == Args.size());
6399+
unsigned NumOperands = Args.size();
6400+
Function *F = cast<Function>(Callee);
63986401
Intrinsic::ID IID = F->getIntrinsicID();
63996402

64006403
// Most of the intrinsics with no operands have some kind of side effect.
@@ -6420,42 +6423,40 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
64206423
}
64216424

64226425
if (NumOperands == 1)
6423-
return simplifyUnaryIntrinsic(F, Call->getArgOperand(0), Q);
6426+
return simplifyUnaryIntrinsic(F, Args[0], Q);
64246427

64256428
if (NumOperands == 2)
6426-
return simplifyBinaryIntrinsic(F, Call->getArgOperand(0),
6427-
Call->getArgOperand(1), Q);
6429+
return simplifyBinaryIntrinsic(F, Args[0], Args[1], Q);
64286430

64296431
// Handle intrinsics with 3 or more arguments.
64306432
switch (IID) {
64316433
case Intrinsic::masked_load:
64326434
case Intrinsic::masked_gather: {
6433-
Value *MaskArg = Call->getArgOperand(2);
6434-
Value *PassthruArg = Call->getArgOperand(3);
6435+
Value *MaskArg = Args[2];
6436+
Value *PassthruArg = Args[3];
64356437
// If the mask is all zeros or undef, the "passthru" argument is the result.
64366438
if (maskIsAllZeroOrUndef(MaskArg))
64376439
return PassthruArg;
64386440
return nullptr;
64396441
}
64406442
case Intrinsic::fshl:
64416443
case Intrinsic::fshr: {
6442-
Value *Op0 = Call->getArgOperand(0), *Op1 = Call->getArgOperand(1),
6443-
*ShAmtArg = Call->getArgOperand(2);
6444+
Value *Op0 = Args[0], *Op1 = Args[1], *ShAmtArg = Args[2];
64446445

64456446
// If both operands are undef, the result is undef.
64466447
if (Q.isUndefValue(Op0) && Q.isUndefValue(Op1))
64476448
return UndefValue::get(F->getReturnType());
64486449

64496450
// If shift amount is undef, assume it is zero.
64506451
if (Q.isUndefValue(ShAmtArg))
6451-
return Call->getArgOperand(IID == Intrinsic::fshl ? 0 : 1);
6452+
return Args[IID == Intrinsic::fshl ? 0 : 1];
64526453

64536454
const APInt *ShAmtC;
64546455
if (match(ShAmtArg, m_APInt(ShAmtC))) {
64556456
// If there's effectively no shift, return the 1st arg or 2nd arg.
64566457
APInt BitWidth = APInt(ShAmtC->getBitWidth(), ShAmtC->getBitWidth());
64576458
if (ShAmtC->urem(BitWidth).isZero())
6458-
return Call->getArgOperand(IID == Intrinsic::fshl ? 0 : 1);
6459+
return Args[IID == Intrinsic::fshl ? 0 : 1];
64596460
}
64606461

64616462
// Rotating zero by anything is zero.
@@ -6469,31 +6470,24 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
64696470
return nullptr;
64706471
}
64716472
case Intrinsic::experimental_constrained_fma: {
6472-
Value *Op0 = Call->getArgOperand(0);
6473-
Value *Op1 = Call->getArgOperand(1);
6474-
Value *Op2 = Call->getArgOperand(2);
64756473
auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
6476-
if (Value *V =
6477-
simplifyFPOp({Op0, Op1, Op2}, {}, Q, *FPI->getExceptionBehavior(),
6478-
*FPI->getRoundingMode()))
6474+
if (Value *V = simplifyFPOp(Args, {}, Q, *FPI->getExceptionBehavior(),
6475+
*FPI->getRoundingMode()))
64796476
return V;
64806477
return nullptr;
64816478
}
64826479
case Intrinsic::fma:
64836480
case Intrinsic::fmuladd: {
6484-
Value *Op0 = Call->getArgOperand(0);
6485-
Value *Op1 = Call->getArgOperand(1);
6486-
Value *Op2 = Call->getArgOperand(2);
6487-
if (Value *V = simplifyFPOp({Op0, Op1, Op2}, {}, Q, fp::ebIgnore,
6481+
if (Value *V = simplifyFPOp(Args, {}, Q, fp::ebIgnore,
64886482
RoundingMode::NearestTiesToEven))
64896483
return V;
64906484
return nullptr;
64916485
}
64926486
case Intrinsic::smul_fix:
64936487
case Intrinsic::smul_fix_sat: {
6494-
Value *Op0 = Call->getArgOperand(0);
6495-
Value *Op1 = Call->getArgOperand(1);
6496-
Value *Op2 = Call->getArgOperand(2);
6488+
Value *Op0 = Args[0];
6489+
Value *Op1 = Args[1];
6490+
Value *Op2 = Args[2];
64976491
Type *ReturnType = F->getReturnType();
64986492

64996493
// Canonicalize constant operand as Op1 (ConstantFolding handles the case
@@ -6520,9 +6514,9 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
65206514
return nullptr;
65216515
}
65226516
case Intrinsic::vector_insert: {
6523-
Value *Vec = Call->getArgOperand(0);
6524-
Value *SubVec = Call->getArgOperand(1);
6525-
Value *Idx = Call->getArgOperand(2);
6517+
Value *Vec = Args[0];
6518+
Value *SubVec = Args[1];
6519+
Value *Idx = Args[2];
65266520
Type *ReturnType = F->getReturnType();
65276521

65286522
// (insert_vector Y, (extract_vector X, 0), 0) -> X
@@ -6539,51 +6533,52 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
65396533
}
65406534
case Intrinsic::experimental_constrained_fadd: {
65416535
auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
6542-
return simplifyFAddInst(
6543-
FPI->getArgOperand(0), FPI->getArgOperand(1), FPI->getFastMathFlags(),
6544-
Q, *FPI->getExceptionBehavior(), *FPI->getRoundingMode());
6536+
return simplifyFAddInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6537+
*FPI->getExceptionBehavior(),
6538+
*FPI->getRoundingMode());
65456539
}
65466540
case Intrinsic::experimental_constrained_fsub: {
65476541
auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
6548-
return simplifyFSubInst(
6549-
FPI->getArgOperand(0), FPI->getArgOperand(1), FPI->getFastMathFlags(),
6550-
Q, *FPI->getExceptionBehavior(), *FPI->getRoundingMode());
6542+
return simplifyFSubInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6543+
*FPI->getExceptionBehavior(),
6544+
*FPI->getRoundingMode());
65516545
}
65526546
case Intrinsic::experimental_constrained_fmul: {
65536547
auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
6554-
return simplifyFMulInst(
6555-
FPI->getArgOperand(0), FPI->getArgOperand(1), FPI->getFastMathFlags(),
6556-
Q, *FPI->getExceptionBehavior(), *FPI->getRoundingMode());
6548+
return simplifyFMulInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6549+
*FPI->getExceptionBehavior(),
6550+
*FPI->getRoundingMode());
65576551
}
65586552
case Intrinsic::experimental_constrained_fdiv: {
65596553
auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
6560-
return simplifyFDivInst(
6561-
FPI->getArgOperand(0), FPI->getArgOperand(1), FPI->getFastMathFlags(),
6562-
Q, *FPI->getExceptionBehavior(), *FPI->getRoundingMode());
6554+
return simplifyFDivInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6555+
*FPI->getExceptionBehavior(),
6556+
*FPI->getRoundingMode());
65636557
}
65646558
case Intrinsic::experimental_constrained_frem: {
65656559
auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
6566-
return simplifyFRemInst(
6567-
FPI->getArgOperand(0), FPI->getArgOperand(1), FPI->getFastMathFlags(),
6568-
Q, *FPI->getExceptionBehavior(), *FPI->getRoundingMode());
6560+
return simplifyFRemInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
6561+
*FPI->getExceptionBehavior(),
6562+
*FPI->getRoundingMode());
65696563
}
65706564
default:
65716565
return nullptr;
65726566
}
65736567
}
65746568

6575-
static Value *tryConstantFoldCall(CallBase *Call, const SimplifyQuery &Q) {
6576-
auto *F = dyn_cast<Function>(Call->getCalledOperand());
6569+
static Value *tryConstantFoldCall(CallBase *Call, Value *Callee,
6570+
ArrayRef<Value *> Args,
6571+
const SimplifyQuery &Q) {
6572+
auto *F = dyn_cast<Function>(Callee);
65776573
if (!F || !canConstantFoldCallTo(Call, F))
65786574
return nullptr;
65796575

65806576
SmallVector<Constant *, 4> ConstantArgs;
6581-
unsigned NumArgs = Call->arg_size();
6582-
ConstantArgs.reserve(NumArgs);
6583-
for (auto &Arg : Call->args()) {
6584-
Constant *C = dyn_cast<Constant>(&Arg);
6577+
ConstantArgs.reserve(Args.size());
6578+
for (Value *Arg : Args) {
6579+
Constant *C = dyn_cast<Constant>(Arg);
65856580
if (!C) {
6586-
if (isa<MetadataAsValue>(Arg.get()))
6581+
if (isa<MetadataAsValue>(Arg))
65876582
continue;
65886583
return nullptr;
65896584
}
@@ -6593,34 +6588,38 @@ static Value *tryConstantFoldCall(CallBase *Call, const SimplifyQuery &Q) {
65936588
return ConstantFoldCall(Call, F, ConstantArgs, Q.TLI);
65946589
}
65956590

6596-
Value *llvm::simplifyCall(CallBase *Call, const SimplifyQuery &Q) {
6591+
Value *llvm::simplifyCall(CallBase *Call, Value *Callee, ArrayRef<Value *> Args,
6592+
const SimplifyQuery &Q) {
6593+
// Args should not contain operand bundle operands.
6594+
assert(Call->arg_size() == Args.size());
6595+
65976596
// musttail calls can only be simplified if they are also DCEd.
65986597
// As we can't guarantee this here, don't simplify them.
65996598
if (Call->isMustTailCall())
66006599
return nullptr;
66016600

66026601
// call undef -> poison
66036602
// call null -> poison
6604-
Value *Callee = Call->getCalledOperand();
66056603
if (isa<UndefValue>(Callee) || isa<ConstantPointerNull>(Callee))
66066604
return PoisonValue::get(Call->getType());
66076605

6608-
if (Value *V = tryConstantFoldCall(Call, Q))
6606+
if (Value *V = tryConstantFoldCall(Call, Callee, Args, Q))
66096607
return V;
66106608

66116609
auto *F = dyn_cast<Function>(Callee);
66126610
if (F && F->isIntrinsic())
6613-
if (Value *Ret = simplifyIntrinsic(Call, Q))
6611+
if (Value *Ret = simplifyIntrinsic(Call, Callee, Args, Q))
66146612
return Ret;
66156613

66166614
return nullptr;
66176615
}
66186616

66196617
Value *llvm::simplifyConstrainedFPCall(CallBase *Call, const SimplifyQuery &Q) {
66206618
assert(isa<ConstrainedFPIntrinsic>(Call));
6621-
if (Value *V = tryConstantFoldCall(Call, Q))
6619+
SmallVector<Value *, 4> Args(Call->args());
6620+
if (Value *V = tryConstantFoldCall(Call, Call->getCalledOperand(), Args, Q))
66226621
return V;
6623-
if (Value *Ret = simplifyIntrinsic(Call, Q))
6622+
if (Value *Ret = simplifyIntrinsic(Call, Call->getCalledOperand(), Args, Q))
66246623
return Ret;
66256624
return nullptr;
66266625
}
@@ -6775,8 +6774,9 @@ static Value *simplifyInstructionWithOperands(Instruction *I,
67756774
case Instruction::PHI:
67766775
return simplifyPHINode(cast<PHINode>(I), NewOps, Q);
67776776
case Instruction::Call:
6778-
// TODO: Use NewOps
6779-
return simplifyCall(cast<CallInst>(I), Q);
6777+
return simplifyCall(
6778+
cast<CallInst>(I), NewOps.back(),
6779+
NewOps.drop_back(1 + cast<CallInst>(I)->getNumTotalBundleOperands()), Q);
67806780
case Instruction::Freeze:
67816781
return llvm::simplifyFreezeInst(NewOps[0], Q);
67826782
#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,9 +1288,15 @@ foldShuffledIntrinsicOperands(IntrinsicInst *II,
12881288
Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
12891289
// Don't try to simplify calls without uses. It will not do anything useful,
12901290
// but will result in the following folds being skipped.
1291-
if (!CI.use_empty())
1292-
if (Value *V = simplifyCall(&CI, SQ.getWithInstruction(&CI)))
1291+
if (!CI.use_empty()) {
1292+
SmallVector<Value *, 4> Args;
1293+
Args.reserve(CI.arg_size());
1294+
for (Value *Op : CI.args())
1295+
Args.push_back(Op);
1296+
if (Value *V = simplifyCall(&CI, CI.getCalledOperand(), Args,
1297+
SQ.getWithInstruction(&CI)))
12931298
return replaceInstUsesWith(CI, V);
1299+
}
12941300

12951301
if (Value *FreedOp = getFreedOperand(&CI, &TLI))
12961302
return visitFree(CI, FreedOp);

llvm/unittests/Transforms/Utils/LocalTest.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,8 @@ TEST(Local, SimplifyVScaleWithRange) {
598598

599599
// Test that simplifyCall won't try to query it's parent function for
600600
// vscale_range attributes in order to simplify llvm.vscale -> constant.
601-
EXPECT_EQ(simplifyCall(CI, SimplifyQuery(M.getDataLayout())), nullptr);
601+
EXPECT_EQ(simplifyCall(CI, VScale, {}, SimplifyQuery(M.getDataLayout())),
602+
nullptr);
602603
delete CI;
603604
}
604605

0 commit comments

Comments
 (0)