Skip to content

Commit 698ae66

Browse files
committed
[VPlan] Replace FMF in VPInstruction with VPRecipeWithIRFlags (NFC).
Update VPInstruction to use VPRecipeWithIRFlags to manage FMFs for VPInstruction. Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D157144
1 parent 8926f0f commit 698ae66

File tree

3 files changed

+60
-28
lines changed

3 files changed

+60
-28
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9167,10 +9167,10 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
91679167
// need to create an fmul recipe (multiplying the first two operands of
91689168
// the fmuladd together) to use as the vector operand for the fadd
91699169
// reduction.
9170-
VPInstruction *FMulRecipe =
9171-
new VPInstruction(Instruction::FMul, {CurrentLink->getOperand(0),
9172-
CurrentLink->getOperand(1)});
9173-
FMulRecipe->setFastMathFlags(CurrentLinkI->getFastMathFlags());
9170+
VPInstruction *FMulRecipe = new VPInstruction(
9171+
Instruction::FMul,
9172+
{CurrentLink->getOperand(0), CurrentLink->getOperand(1)},
9173+
CurrentLinkI->getFastMathFlags());
91749174
LinkVPBB->insert(FMulRecipe, CurrentLink->getIterator());
91759175
VecOp = FMulRecipe;
91769176
} else {

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,8 @@ class VPRecipeWithIRFlags : public VPRecipeBase {
844844
char AllowReciprocal : 1;
845845
char AllowContract : 1;
846846
char ApproxFunc : 1;
847+
848+
FastMathFlagsTy(const FastMathFlags &FMF);
847849
};
848850

849851
OperationType OpType;
@@ -878,14 +880,7 @@ class VPRecipeWithIRFlags : public VPRecipeBase {
878880
GEPFlags.IsInBounds = GEP->isInBounds();
879881
} else if (auto *Op = dyn_cast<FPMathOperator>(&I)) {
880882
OpType = OperationType::FPMathOp;
881-
FastMathFlags FMF = Op->getFastMathFlags();
882-
FMFs.AllowReassoc = FMF.allowReassoc();
883-
FMFs.NoNaNs = FMF.noNaNs();
884-
FMFs.NoInfs = FMF.noInfs();
885-
FMFs.NoSignedZeros = FMF.noSignedZeros();
886-
FMFs.AllowReciprocal = FMF.allowReciprocal();
887-
FMFs.AllowContract = FMF.allowContract();
888-
FMFs.ApproxFunc = FMF.approxFunc();
883+
FMFs = Op->getFastMathFlags();
889884
}
890885
}
891886

@@ -895,6 +890,12 @@ class VPRecipeWithIRFlags : public VPRecipeBase {
895890
: VPRecipeBase(SC, Operands), OpType(OperationType::OverflowingBinOp),
896891
WrapFlags(WrapFlags) {}
897892

893+
template <typename IterT>
894+
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
895+
FastMathFlags FMFs)
896+
: VPRecipeBase(SC, Operands), OpType(OperationType::FPMathOp),
897+
FMFs(FMFs) {}
898+
898899
static inline bool classof(const VPRecipeBase *R) {
899900
return R->getVPDefID() == VPRecipeBase::VPInstructionSC ||
900901
R->getVPDefID() == VPRecipeBase::VPWidenSC ||
@@ -959,6 +960,9 @@ class VPRecipeWithIRFlags : public VPRecipeBase {
959960
return GEPFlags.IsInBounds;
960961
}
961962

963+
/// Returns true if the recipe has fast-math flags.
964+
bool hasFastMathFlags() const { return OpType == OperationType::FPMathOp; }
965+
962966
FastMathFlags getFastMathFlags() const;
963967

964968
bool hasNoUnsignedWrap() const {
@@ -1008,7 +1012,6 @@ class VPInstruction : public VPRecipeWithIRFlags, public VPValue {
10081012
private:
10091013
typedef unsigned char OpcodeTy;
10101014
OpcodeTy Opcode;
1011-
FastMathFlags FMF;
10121015
DebugLoc DL;
10131016

10141017
/// An optional name that can be used for the generated IR instruction.
@@ -1020,6 +1023,12 @@ class VPInstruction : public VPRecipeWithIRFlags, public VPValue {
10201023
/// one.
10211024
Value *generateInstruction(VPTransformState &State, unsigned Part);
10221025

1026+
#if !defined(NDEBUG)
1027+
/// Return true if the VPInstruction is a floating point math operation, i.e.
1028+
/// has fast-math flags.
1029+
bool isFPMathOp() const;
1030+
#endif
1031+
10231032
protected:
10241033
void setUnderlyingInstr(Instruction *I) { setUnderlyingValue(I); }
10251034

@@ -1038,6 +1047,9 @@ class VPInstruction : public VPRecipeWithIRFlags, public VPValue {
10381047
: VPRecipeWithIRFlags(VPDef::VPInstructionSC, Operands, WrapFlags),
10391048
VPValue(this), Opcode(Opcode), DL(DL), Name(Name.str()) {}
10401049

1050+
VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands,
1051+
FastMathFlags FMFs, DebugLoc DL = {}, const Twine &Name = "");
1052+
10411053
VP_CLASSOF_IMPL(VPDef::VPInstructionSC)
10421054

10431055
VPInstruction *clone() const {
@@ -1091,9 +1103,6 @@ class VPInstruction : public VPRecipeWithIRFlags, public VPValue {
10911103
}
10921104
}
10931105

1094-
/// Set the fast-math flags.
1095-
void setFastMathFlags(FastMathFlags FMFNew);
1096-
10971106
/// Returns true if the recipe only uses the first lane of operand \p Op.
10981107
bool onlyFirstLaneUsed(const VPValue *Op) const override {
10991108
assert(is_contained(operands(), Op) &&

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ FastMathFlags VPRecipeWithIRFlags::getFastMathFlags() const {
230230
return Res;
231231
}
232232

233+
VPInstruction::VPInstruction(unsigned Opcode,
234+
std::initializer_list<VPValue *> Operands,
235+
FastMathFlags FMFs, DebugLoc DL, const Twine &Name)
236+
: VPRecipeWithIRFlags(VPDef::VPInstructionSC, Operands, FMFs),
237+
VPValue(this), Opcode(Opcode), DL(DL), Name(Name.str()) {
238+
// Make sure the VPInstruction is a floating-point operation.
239+
assert(isFPMathOp() && "this op can't take fast-math flags");
240+
}
241+
233242
Value *VPInstruction::generateInstruction(VPTransformState &State,
234243
unsigned Part) {
235244
IRBuilderBase &Builder = State.Builder;
@@ -373,10 +382,24 @@ Value *VPInstruction::generateInstruction(VPTransformState &State,
373382
}
374383
}
375384

385+
#if !defined(NDEBUG)
386+
bool VPInstruction::isFPMathOp() const {
387+
// Inspired by FPMathOperator::classof. Notable differences are that we don't
388+
// support Call, PHI and Select opcodes here yet.
389+
return Opcode == Instruction::FAdd || Opcode == Instruction::FMul ||
390+
Opcode == Instruction::FNeg || Opcode == Instruction::FSub ||
391+
Opcode == Instruction::FDiv || Opcode == Instruction::FRem ||
392+
Opcode == Instruction::FCmp;
393+
}
394+
#endif
395+
376396
void VPInstruction::execute(VPTransformState &State) {
377397
assert(!State.Instance && "VPInstruction executing an Instance");
378398
IRBuilderBase::FastMathFlagGuard FMFGuard(State.Builder);
379-
State.Builder.setFastMathFlags(FMF);
399+
assert(hasFastMathFlags() == isFPMathOp() &&
400+
"Recipe not a FPMathOp but has fast-math flags?");
401+
if (hasFastMathFlags())
402+
State.Builder.setFastMathFlags(getFastMathFlags());
380403
for (unsigned Part = 0; Part < State.UF; ++Part) {
381404
Value *GeneratedValue = generateInstruction(State, Part);
382405
if (!hasResult())
@@ -439,7 +462,6 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
439462
O << Instruction::getOpcodeName(getOpcode());
440463
}
441464

442-
O << FMF;
443465
printFlags(O);
444466
printOperands(O, SlotTracker);
445467

@@ -450,16 +472,6 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
450472
}
451473
#endif
452474

453-
void VPInstruction::setFastMathFlags(FastMathFlags FMFNew) {
454-
// Make sure the VPInstruction is a floating-point operation.
455-
assert((Opcode == Instruction::FAdd || Opcode == Instruction::FMul ||
456-
Opcode == Instruction::FNeg || Opcode == Instruction::FSub ||
457-
Opcode == Instruction::FDiv || Opcode == Instruction::FRem ||
458-
Opcode == Instruction::FCmp) &&
459-
"this op can't take fast-math flags");
460-
FMF = FMFNew;
461-
}
462-
463475
void VPWidenCallRecipe::execute(VPTransformState &State) {
464476
assert(State.VF.isVector() && "not widening");
465477
auto &CI = *cast<CallInst>(getUnderlyingInstr());
@@ -576,6 +588,17 @@ void VPWidenSelectRecipe::execute(VPTransformState &State) {
576588
}
577589
}
578590

591+
VPRecipeWithIRFlags::FastMathFlagsTy::FastMathFlagsTy(
592+
const FastMathFlags &FMF) {
593+
AllowReassoc = FMF.allowReassoc();
594+
NoNaNs = FMF.noNaNs();
595+
NoInfs = FMF.noInfs();
596+
NoSignedZeros = FMF.noSignedZeros();
597+
AllowReciprocal = FMF.allowReciprocal();
598+
AllowContract = FMF.allowContract();
599+
ApproxFunc = FMF.approxFunc();
600+
}
601+
579602
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
580603
void VPRecipeWithIRFlags::printFlags(raw_ostream &O) const {
581604
switch (OpType) {

0 commit comments

Comments
 (0)