Skip to content

Commit 235cea7

Browse files
[NFC][LLVM] Refactor rounding mode detection of constrained fp intrinsic IDs (#90854)
I've refactored the code to genericise the implementation to better allow for target specific constrained fp intrinsics.
1 parent e232659 commit 235cea7

File tree

9 files changed

+51
-95
lines changed

9 files changed

+51
-95
lines changed

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -707,8 +707,7 @@ class VPBinOpIntrinsic : public VPIntrinsic {
707707
/// This is the common base class for constrained floating point intrinsics.
708708
class ConstrainedFPIntrinsic : public IntrinsicInst {
709709
public:
710-
bool isUnaryOp() const;
711-
bool isTernaryOp() const;
710+
unsigned getNonMetadataArgCount() const;
712711
std::optional<RoundingMode> getRoundingMode() const;
713712
std::optional<fp::ExceptionBehavior> getExceptionBehavior() const;
714713
bool isDefaultFPEnvironment() const;

llvm/include/llvm/IR/Intrinsics.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ namespace Intrinsic {
109109
/// Floating-Point Intrinsics".
110110
bool isConstrainedFPIntrinsic(ID QID);
111111

112+
/// Returns true if the intrinsic ID is for one of the "Constrained
113+
/// Floating-Point Intrinsics" that take rounding mode metadata.
114+
bool hasConstrainedFPRoundingModeOperand(ID QID);
115+
112116
/// This is a type descriptor which explains the type requirements of an
113117
/// intrinsic. This is returned by getIntrinsicInfoTableEntries.
114118
struct IITDescriptor {

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,11 +2053,8 @@ bool IRTranslator::translateConstrainedFPIntrinsic(
20532053
Flags |= MachineInstr::NoFPExcept;
20542054

20552055
SmallVector<llvm::SrcOp, 4> VRegs;
2056-
VRegs.push_back(getOrCreateVReg(*FPI.getArgOperand(0)));
2057-
if (!FPI.isUnaryOp())
2058-
VRegs.push_back(getOrCreateVReg(*FPI.getArgOperand(1)));
2059-
if (FPI.isTernaryOp())
2060-
VRegs.push_back(getOrCreateVReg(*FPI.getArgOperand(2)));
2056+
for (unsigned I = 0, E = FPI.getNonMetadataArgCount(); I != E; ++I)
2057+
VRegs.push_back(getOrCreateVReg(*FPI.getArgOperand(I)));
20612058

20622059
MIRBuilder.buildInstr(Opcode, {getOrCreateVReg(FPI)}, VRegs, Flags);
20632060
return true;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7962,16 +7962,8 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
79627962
SDValue Chain = DAG.getRoot();
79637963
SmallVector<SDValue, 4> Opers;
79647964
Opers.push_back(Chain);
7965-
if (FPI.isUnaryOp()) {
7966-
Opers.push_back(getValue(FPI.getArgOperand(0)));
7967-
} else if (FPI.isTernaryOp()) {
7968-
Opers.push_back(getValue(FPI.getArgOperand(0)));
7969-
Opers.push_back(getValue(FPI.getArgOperand(1)));
7970-
Opers.push_back(getValue(FPI.getArgOperand(2)));
7971-
} else {
7972-
Opers.push_back(getValue(FPI.getArgOperand(0)));
7973-
Opers.push_back(getValue(FPI.getArgOperand(1)));
7974-
}
7965+
for (unsigned I = 0, E = FPI.getNonMetadataArgCount(); I != E; ++I)
7966+
Opers.push_back(getValue(FPI.getArgOperand(I)));
79757967

79767968
auto pushOutChain = [this](SDValue Result, fp::ExceptionBehavior EB) {
79777969
assert(Result.getNode()->getNumValues() == 2);

llvm/lib/IR/Function.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,19 @@ bool Intrinsic::isConstrainedFPIntrinsic(ID QID) {
14931493
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
14941494
case Intrinsic::INTRINSIC:
14951495
#include "llvm/IR/ConstrainedOps.def"
1496+
#undef INSTRUCTION
14961497
return true;
1498+
default:
1499+
return false;
1500+
}
1501+
}
1502+
1503+
bool Intrinsic::hasConstrainedFPRoundingModeOperand(Intrinsic::ID QID) {
1504+
switch (QID) {
1505+
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
1506+
case Intrinsic::INTRINSIC: \
1507+
return ROUND_MODE == 1;
1508+
#include "llvm/IR/ConstrainedOps.def"
14971509
#undef INSTRUCTION
14981510
default:
14991511
return false;

llvm/lib/IR/IRBuilder.cpp

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,17 +1029,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCast(
10291029
UseFMF = FMFSource->getFastMathFlags();
10301030

10311031
CallInst *C;
1032-
bool HasRoundingMD = false;
1033-
switch (ID) {
1034-
default:
1035-
break;
1036-
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
1037-
case Intrinsic::INTRINSIC: \
1038-
HasRoundingMD = ROUND_MODE; \
1039-
break;
1040-
#include "llvm/IR/ConstrainedOps.def"
1041-
}
1042-
if (HasRoundingMD) {
1032+
if (Intrinsic::hasConstrainedFPRoundingModeOperand(ID)) {
10431033
Value *RoundingV = getConstrainedFPRounding(Rounding);
10441034
C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV},
10451035
nullptr, Name);
@@ -1088,17 +1078,8 @@ CallInst *IRBuilderBase::CreateConstrainedFPCall(
10881078
llvm::SmallVector<Value *, 6> UseArgs;
10891079

10901080
append_range(UseArgs, Args);
1091-
bool HasRoundingMD = false;
1092-
switch (Callee->getIntrinsicID()) {
1093-
default:
1094-
break;
1095-
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
1096-
case Intrinsic::INTRINSIC: \
1097-
HasRoundingMD = ROUND_MODE; \
1098-
break;
1099-
#include "llvm/IR/ConstrainedOps.def"
1100-
}
1101-
if (HasRoundingMD)
1081+
1082+
if (Intrinsic::hasConstrainedFPRoundingModeOperand(Callee->getIntrinsicID()))
11021083
UseArgs.push_back(getConstrainedFPRounding(Rounding));
11031084
UseArgs.push_back(getConstrainedFPExcept(Except));
11041085

llvm/lib/IR/IntrinsicInst.cpp

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -365,37 +365,23 @@ FCmpInst::Predicate ConstrainedFPCmpIntrinsic::getPredicate() const {
365365
return getFPPredicateFromMD(getArgOperand(2));
366366
}
367367

368-
bool ConstrainedFPIntrinsic::isUnaryOp() const {
369-
switch (getIntrinsicID()) {
370-
default:
371-
return false;
372-
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
373-
case Intrinsic::INTRINSIC: \
374-
return NARG == 1;
375-
#include "llvm/IR/ConstrainedOps.def"
376-
}
377-
}
368+
unsigned ConstrainedFPIntrinsic::getNonMetadataArgCount() const {
369+
// All constrained fp intrinsics have "fpexcept" metadata.
370+
unsigned NumArgs = arg_size() - 1;
378371

379-
bool ConstrainedFPIntrinsic::isTernaryOp() const {
380-
switch (getIntrinsicID()) {
381-
default:
382-
return false;
383-
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
384-
case Intrinsic::INTRINSIC: \
385-
return NARG == 3;
386-
#include "llvm/IR/ConstrainedOps.def"
387-
}
372+
// Some intrinsics have "round" metadata.
373+
if (Intrinsic::hasConstrainedFPRoundingModeOperand(getIntrinsicID()))
374+
NumArgs -= 1;
375+
376+
// Compare intrinsics take their predicate as metadata.
377+
if (isa<ConstrainedFPCmpIntrinsic>(this))
378+
NumArgs -= 1;
379+
380+
return NumArgs;
388381
}
389382

390383
bool ConstrainedFPIntrinsic::classof(const IntrinsicInst *I) {
391-
switch (I->getIntrinsicID()) {
392-
#define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC) \
393-
case Intrinsic::INTRINSIC:
394-
#include "llvm/IR/ConstrainedOps.def"
395-
return true;
396-
default:
397-
return false;
398-
}
384+
return Intrinsic::isConstrainedFPIntrinsic(I->getIntrinsicID());
399385
}
400386

401387
ElementCount VPIntrinsic::getStaticVectorLength() const {

llvm/lib/IR/Verifier.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5384,11 +5384,13 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
53845384
}
53855385
#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
53865386
#include "llvm/IR/VPIntrinsics.def"
5387+
#undef BEGIN_REGISTER_VP_INTRINSIC
53875388
visitVPIntrinsic(cast<VPIntrinsic>(Call));
53885389
break;
53895390
#define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC) \
53905391
case Intrinsic::INTRINSIC:
53915392
#include "llvm/IR/ConstrainedOps.def"
5393+
#undef INSTRUCTION
53925394
visitConstrainedFPIntrinsic(cast<ConstrainedFPIntrinsic>(Call));
53935395
break;
53945396
case Intrinsic::dbg_declare: // llvm.dbg.declare
@@ -6527,19 +6529,13 @@ void Verifier::visitVPIntrinsic(VPIntrinsic &VPI) {
65276529
}
65286530

65296531
void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
6530-
unsigned NumOperands;
6531-
bool HasRoundingMD;
6532-
switch (FPI.getIntrinsicID()) {
6533-
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
6534-
case Intrinsic::INTRINSIC: \
6535-
NumOperands = NARG; \
6536-
HasRoundingMD = ROUND_MODE; \
6537-
break;
6538-
#include "llvm/IR/ConstrainedOps.def"
6539-
default:
6540-
llvm_unreachable("Invalid constrained FP intrinsic!");
6541-
}
6532+
unsigned NumOperands = FPI.getNonMetadataArgCount();
6533+
bool HasRoundingMD =
6534+
Intrinsic::hasConstrainedFPRoundingModeOperand(FPI.getIntrinsicID());
6535+
6536+
// Add the expected number of metadata operands.
65426537
NumOperands += (1 + HasRoundingMD);
6538+
65436539
// Compare intrinsics carry an extra predicate metadata operand.
65446540
if (isa<ConstrainedFPCmpIntrinsic>(FPI))
65456541
NumOperands += 1;
@@ -6553,8 +6549,8 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
65536549
Type *ResultTy = FPI.getType();
65546550
Check(!ValTy->isVectorTy() && !ResultTy->isVectorTy(),
65556551
"Intrinsic does not support vectors", &FPI);
6556-
}
65576552
break;
6553+
}
65586554

65596555
case Intrinsic::experimental_constrained_lround:
65606556
case Intrinsic::experimental_constrained_llround: {
@@ -6593,8 +6589,8 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
65936589
"Intrinsic first argument and result vector lengths must be equal",
65946590
&FPI);
65956591
}
6596-
}
65976592
break;
6593+
}
65986594

65996595
case Intrinsic::experimental_constrained_sitofp:
66006596
case Intrinsic::experimental_constrained_uitofp: {
@@ -6616,7 +6612,8 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
66166612
"Intrinsic first argument and result vector lengths must be equal",
66176613
&FPI);
66186614
}
6619-
} break;
6615+
break;
6616+
}
66206617

66216618
case Intrinsic::experimental_constrained_fptrunc:
66226619
case Intrinsic::experimental_constrained_fpext: {
@@ -6645,8 +6642,8 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
66456642
"Intrinsic first argument's type must be smaller than result type",
66466643
&FPI);
66476644
}
6648-
}
66496645
break;
6646+
}
66506647

66516648
default:
66526649
break;

llvm/lib/Transforms/Utils/CloneFunction.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -386,18 +386,6 @@ struct PruningFunctionCloner {
386386
};
387387
} // namespace
388388

389-
static bool hasRoundingModeOperand(Intrinsic::ID CIID) {
390-
switch (CIID) {
391-
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
392-
case Intrinsic::INTRINSIC: \
393-
return ROUND_MODE == 1;
394-
#define FUNCTION INSTRUCTION
395-
#include "llvm/IR/ConstrainedOps.def"
396-
default:
397-
llvm_unreachable("Unexpected constrained intrinsic id");
398-
}
399-
}
400-
401389
Instruction *
402390
PruningFunctionCloner::cloneInstruction(BasicBlock::const_iterator II) {
403391
const Instruction &OldInst = *II;
@@ -455,7 +443,7 @@ PruningFunctionCloner::cloneInstruction(BasicBlock::const_iterator II) {
455443
// The last arguments of a constrained intrinsic are metadata that
456444
// represent rounding mode (absents in some intrinsics) and exception
457445
// behavior. The inlined function uses default settings.
458-
if (hasRoundingModeOperand(CIID))
446+
if (Intrinsic::hasConstrainedFPRoundingModeOperand(CIID))
459447
Args.push_back(
460448
MetadataAsValue::get(Ctx, MDString::get(Ctx, "round.tonearest")));
461449
Args.push_back(

0 commit comments

Comments
 (0)