Skip to content

Commit a24a420

Browse files
authored
[SandboxIR] Implement FPMathOperator (#112921)
This patch implements sandboxir::FPMathOperator mirroring llvm::FPMathOperator
1 parent 6a623e8 commit a24a420

File tree

4 files changed

+98
-2
lines changed

4 files changed

+98
-2
lines changed

llvm/include/llvm/SandboxIR/Operator.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,45 @@ class OverflowingBinaryOperator : public Operator {
5555
return llvm::OverflowingBinaryOperator::classof(From->Val);
5656
}
5757
};
58+
59+
class FPMathOperator : public Operator {
60+
public:
61+
bool isFast() const { return cast<llvm::FPMathOperator>(Val)->isFast(); }
62+
bool hasAllowReassoc() const {
63+
return cast<llvm::FPMathOperator>(Val)->hasAllowReassoc();
64+
}
65+
bool hasNoNaNs() const {
66+
return cast<llvm::FPMathOperator>(Val)->hasNoNaNs();
67+
}
68+
bool hasNoInfs() const {
69+
return cast<llvm::FPMathOperator>(Val)->hasNoInfs();
70+
}
71+
bool hasNoSignedZeros() const {
72+
return cast<llvm::FPMathOperator>(Val)->hasNoSignedZeros();
73+
}
74+
bool hasAllowReciprocal() const {
75+
return cast<llvm::FPMathOperator>(Val)->hasAllowReciprocal();
76+
}
77+
bool hasAllowContract() const {
78+
return cast<llvm::FPMathOperator>(Val)->hasAllowContract();
79+
}
80+
bool hasApproxFunc() const {
81+
return cast<llvm::FPMathOperator>(Val)->hasApproxFunc();
82+
}
83+
FastMathFlags getFastMathFlags() const {
84+
return cast<llvm::FPMathOperator>(Val)->getFastMathFlags();
85+
}
86+
float getFPAccuracy() const {
87+
return cast<llvm::FPMathOperator>(Val)->getFPAccuracy();
88+
}
89+
static bool isSupportedFloatingPointType(Type *Ty) {
90+
return llvm::FPMathOperator::isSupportedFloatingPointType(Ty->LLVMTy);
91+
}
92+
static bool classof(const Value *V) {
93+
return llvm::FPMathOperator::classof(V->Val);
94+
}
95+
};
96+
5897
} // namespace llvm::sandboxir
5998

6099
#endif // LLVM_SANDBOXIR_OPERATOR_H

llvm/include/llvm/SandboxIR/Type.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ class ArrayType;
3333
class StructType;
3434
class TargetExtType;
3535
class Module;
36+
class FPMathOperator;
3637
#define DEF_INSTR(ID, OPCODE, CLASS) class CLASS;
3738
#define DEF_CONST(ID, CLASS) class CLASS;
3839
#include "llvm/SandboxIR/Values.def"
3940

40-
/// Just like llvm::Type these are immutable, unique, never get freed and can
41-
/// only be created via static factory methods.
41+
/// Just like llvm::Type these are immutable, unique, never get freed and
42+
/// can only be created via static factory methods.
4243
class Type {
4344
protected:
4445
llvm::Type *LLVMTy;
@@ -61,6 +62,7 @@ class Type {
6162
friend class Utils; // for LLVMTy
6263
friend class TargetExtType; // For LLVMTy.
6364
friend class Module; // For LLVMTy.
65+
friend class FPMathOperator; // For LLVMTy.
6466

6567
// Friend all instruction classes because `create()` functions use LLVMTy.
6668
#define DEF_INSTR(ID, OPCODE, CLASS) friend class CLASS;

llvm/include/llvm/SandboxIR/Value.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class CmpInst;
3030
class IntrinsicInst;
3131
class Operator;
3232
class OverflowingBinaryOperator;
33+
class FPMathOperator;
3334

3435
/// Iterator for the `Use` edges of a Value's users.
3536
/// \Returns a `Use` when dereferenced.
@@ -162,6 +163,7 @@ class Value {
162163
friend class IntrinsicInst; // For `Val`.
163164
friend class Operator; // For `Val`.
164165
friend class OverflowingBinaryOperator; // For `Val`.
166+
friend class FPMathOperator; // For `Val`.
165167
// Region needs to manipulate metadata in the underlying LLVM Value, we don't
166168
// expose metadata in sandboxir.
167169
friend class Region;

llvm/unittests/SandboxIR/OperatorTest.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,56 @@ define void @foo(i8 %v1) {
8686
EXPECT_EQ(AddNUW->getNoWrapKind(),
8787
llvm::OverflowingBinaryOperator::NoUnsignedWrap);
8888
}
89+
90+
TEST_F(OperatorTest, FPMathOperator) {
91+
parseIR(C, R"IR(
92+
define void @foo(float %v1, double %v2) {
93+
%fadd = fadd float %v1, 42.0
94+
%Fast = fadd fast float %v1, 42.0
95+
%Reassoc = fmul reassoc float %v1, 42.0
96+
%NNAN = fmul nnan float %v1, 42.0
97+
%NINF = fmul ninf float %v1, 42.0
98+
%NSZ = fmul nsz float %v1, 42.0
99+
%ARCP = fmul arcp float %v1, 42.0
100+
%CONTRACT = fmul contract float %v1, 42.0
101+
%AFN = fmul afn double %v2, 42.0
102+
ret void
103+
}
104+
)IR");
105+
llvm::Function *LLVMF = &*M->getFunction("foo");
106+
auto *LLVMBB = &*LLVMF->begin();
107+
auto LLVMIt = LLVMBB->begin();
108+
109+
sandboxir::Context Ctx(C);
110+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
111+
auto *BB = &*F->begin();
112+
auto It = BB->begin();
113+
auto TermIt = BB->getTerminator()->getIterator();
114+
while (It != TermIt) {
115+
auto *FPM = cast<sandboxir::FPMathOperator>(&*It++);
116+
auto *LLVMFPM = cast<llvm::FPMathOperator>(&*LLVMIt++);
117+
EXPECT_EQ(FPM->isFast(), LLVMFPM->isFast());
118+
EXPECT_EQ(FPM->hasAllowReassoc(), LLVMFPM->hasAllowReassoc());
119+
EXPECT_EQ(FPM->hasNoNaNs(), LLVMFPM->hasNoNaNs());
120+
EXPECT_EQ(FPM->hasNoInfs(), LLVMFPM->hasNoInfs());
121+
EXPECT_EQ(FPM->hasNoSignedZeros(), LLVMFPM->hasNoSignedZeros());
122+
EXPECT_EQ(FPM->hasAllowReciprocal(), LLVMFPM->hasAllowReciprocal());
123+
EXPECT_EQ(FPM->hasAllowContract(), LLVMFPM->hasAllowContract());
124+
EXPECT_EQ(FPM->hasApproxFunc(), LLVMFPM->hasApproxFunc());
125+
126+
// There doesn't seem to be an operator== for FastMathFlags so let's do a
127+
// string comparison instead.
128+
std::string Str1;
129+
raw_string_ostream SS1(Str1);
130+
std::string Str2;
131+
raw_string_ostream SS2(Str2);
132+
FPM->getFastMathFlags().print(SS1);
133+
LLVMFPM->getFastMathFlags().print(SS2);
134+
EXPECT_EQ(Str1, Str2);
135+
136+
EXPECT_EQ(FPM->getFPAccuracy(), LLVMFPM->getFPAccuracy());
137+
EXPECT_EQ(
138+
sandboxir::FPMathOperator::isSupportedFloatingPointType(FPM->getType()),
139+
llvm::FPMathOperator::isSupportedFloatingPointType(LLVMFPM->getType()));
140+
}
141+
}

0 commit comments

Comments
 (0)