Skip to content

Commit 57a7f7b

Browse files
committed
stub support for FP exceptions (WIP)
1 parent 50f04c9 commit 57a7f7b

File tree

7 files changed

+62
-21
lines changed

7 files changed

+62
-21
lines changed

ir/attrs.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,14 @@ ostream& operator<<(std::ostream &os, FpRoundingMode rounding) {
240240
return os << str;
241241
}
242242

243+
ostream& operator<<(std::ostream &os, FpExceptionMode ex) {
244+
const char *str;
245+
switch (ex.mode) {
246+
case FpExceptionMode::Ignore: str = "ignore"; break;
247+
case FpExceptionMode::MayTrap: str = "maytrap"; break;
248+
case FpExceptionMode::Strict: str = "strict"; break;
249+
}
250+
return os << str;
251+
}
252+
243253
}

ir/attrs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,13 @@ struct FpRoundingMode final {
107107
friend std::ostream& operator<<(std::ostream &os, FpRoundingMode rounding);
108108
};
109109

110+
111+
struct FpExceptionMode final {
112+
enum Mode { Ignore, MayTrap, Strict } mode;
113+
FpExceptionMode() : mode(Ignore) {}
114+
FpExceptionMode(Mode mode) : mode(mode) {}
115+
Mode getMode() const { return mode; }
116+
friend std::ostream& operator<<(std::ostream &os, FpExceptionMode ex);
117+
};
118+
110119
}

ir/instr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,7 @@ void FpBinOp::print(ostream &os) const {
601601
os << getName() << " = " << str << fmath << *lhs << ", " << rhs->getName();
602602
if (!rm.isDefault())
603603
os << ", rounding=" << rm;
604+
os << ", exceptions=" << ex;
604605
}
605606

606607
static expr any_fp_zero(State &s, const expr &v) {
@@ -990,6 +991,7 @@ void FpUnaryOp::print(ostream &os) const {
990991
os << getName() << " = " << str << fmath << *val;
991992
if (!rm.isDefault())
992993
os << ", rounding=" << rm;
994+
os << ", exceptions=" << ex;
993995
}
994996

995997
StateValue FpUnaryOp::toSMT(State &s) const {
@@ -1263,6 +1265,7 @@ void FpTernaryOp::print(ostream &os) const {
12631265
os << getName() << " = " << str << fmath << *a << ", " << *b << ", " << *c;
12641266
if (!rm.isDefault())
12651267
os << ", rounding=" << rm;
1268+
os << ", exceptions=" << ex;
12661269
}
12671270

12681271
StateValue FpTernaryOp::toSMT(State &s) const {
@@ -1496,6 +1499,7 @@ void FpConversionOp::print(ostream &os) const {
14961499
os << getName() << " = " << str << *val << print_type(getType(), " to ", "");
14971500
if (!rm.isDefault())
14981501
os << ", rounding=" << rm;
1502+
os << ", exceptions=" << ex;
14991503
}
15001504

15011505
StateValue FpConversionOp::toSMT(State &s) const {

ir/instr.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ class FpBinOp final : public Instr {
6666
Op op;
6767
FastMathFlags fmath;
6868
FpRoundingMode rm;
69+
FpExceptionMode ex;
6970

7071
public:
7172
FpBinOp(Type &type, std::string &&name, Value &lhs, Value &rhs, Op op,
72-
FastMathFlags fmath, FpRoundingMode rm = {})
73+
FastMathFlags fmath, FpRoundingMode rm = {}, FpExceptionMode ex = {})
7374
: Instr(type, std::move(name)), lhs(&lhs), rhs(&rhs), op(op), fmath(fmath),
74-
rm(rm) {}
75+
rm(rm), ex(ex) {}
7576

7677
std::vector<Value*> operands() const override;
7778
bool propagatesPoison() const override;
@@ -120,11 +121,14 @@ class FpUnaryOp final : public Instr {
120121
Op op;
121122
FastMathFlags fmath;
122123
FpRoundingMode rm;
124+
FpExceptionMode ex;
123125

124126
public:
125127
FpUnaryOp(Type &type, std::string &&name, Value &val, Op op,
126-
FastMathFlags fmath, FpRoundingMode rm = {})
127-
: Instr(type, std::move(name)), val(&val), op(op), fmath(fmath), rm(rm) {}
128+
FastMathFlags fmath, FpRoundingMode rm = {},
129+
FpExceptionMode ex = {})
130+
: Instr(type, std::move(name)), val(&val), op(op), fmath(fmath), rm(rm),
131+
ex(ex) {}
128132

129133
std::vector<Value*> operands() const override;
130134
bool propagatesPoison() const override;
@@ -193,12 +197,14 @@ class FpTernaryOp final : public Instr {
193197
Op op;
194198
FastMathFlags fmath;
195199
FpRoundingMode rm;
200+
FpExceptionMode ex;
196201

197202
public:
198203
FpTernaryOp(Type &type, std::string &&name, Value &a, Value &b, Value &c,
199-
Op op, FastMathFlags fmath, FpRoundingMode rm = {})
204+
Op op, FastMathFlags fmath, FpRoundingMode rm = {},
205+
FpExceptionMode ex = {})
200206
: Instr(type, std::move(name)), a(&a), b(&b), c(&c), op(op), fmath(fmath),
201-
rm(rm) {}
207+
rm(rm), ex(ex) {}
202208

203209
std::vector<Value*> operands() const override;
204210
bool propagatesPoison() const override;
@@ -243,11 +249,12 @@ class FpConversionOp final : public Instr {
243249
Value *val;
244250
Op op;
245251
FpRoundingMode rm;
252+
FpExceptionMode ex;
246253

247254
public:
248255
FpConversionOp(Type &type, std::string &&name, Value &val, Op op,
249-
FpRoundingMode rm = {})
250-
: Instr(type, std::move(name)), val(&val), op(op), rm(rm) {}
256+
FpRoundingMode rm = {}, FpExceptionMode ex = {})
257+
: Instr(type, std::move(name)), val(&val), op(op), rm(rm), ex(ex) {}
251258

252259
std::vector<Value*> operands() const override;
253260
bool propagatesPoison() const override;

llvm_util/llvm2alive.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ FpRoundingMode parse_rounding(llvm::Instruction &i) {
4343
}
4444
}
4545

46+
FpExceptionMode parse_exceptions(llvm::Instruction &i) {
47+
auto *fp = dyn_cast<llvm::ConstrainedFPIntrinsic>(&i);
48+
if (!fp || !fp->getExceptionBehavior().hasValue())
49+
return {};
50+
switch (fp->getExceptionBehavior().getValue()) {
51+
case llvm::fp::ebIgnore: return FpExceptionMode::Ignore;
52+
case llvm::fp::ebMayTrap: return FpExceptionMode::MayTrap;
53+
case llvm::fp::ebStrict: return FpExceptionMode::Strict;
54+
default: UNREACHABLE();
55+
}
56+
}
57+
4658
unsigned constexpr_idx;
4759
unsigned copy_idx;
4860
unsigned alignopbundle_idx;
@@ -918,7 +930,8 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
918930
}
919931
RETURN_IDENTIFIER(
920932
make_unique<FpTernaryOp>(*ty, value_name(i), *a, *b, *c, op,
921-
parse_fmath(i), parse_rounding(i)));
933+
parse_fmath(i), parse_rounding(i),
934+
parse_exceptions(i)));
922935
}
923936
case llvm::Intrinsic::copysign:
924937
case llvm::Intrinsic::minnum:
@@ -952,10 +965,9 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
952965
case llvm::Intrinsic::experimental_constrained_fdiv: op = FpBinOp::FDiv; break;
953966
default: UNREACHABLE();
954967
}
955-
// TODO: missing support for exceptions
956968
RETURN_IDENTIFIER(
957969
make_unique<FpBinOp>(*ty, value_name(i), *a, *b, op, parse_fmath(i),
958-
parse_rounding(i)));
970+
parse_rounding(i), parse_exceptions(i)));
959971
}
960972
case llvm::Intrinsic::fabs:
961973
case llvm::Intrinsic::ceil:
@@ -997,10 +1009,9 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
9971009
case llvm::Intrinsic::experimental_constrained_trunc: op = FpUnaryOp::Trunc; break;
9981010
default: UNREACHABLE();
9991011
}
1000-
// TODO: missing support for exceptions
10011012
RETURN_IDENTIFIER(
10021013
make_unique<FpUnaryOp>(*ty, value_name(i), *val, op, parse_fmath(i),
1003-
parse_rounding(i)));
1014+
parse_rounding(i), parse_exceptions(i)));
10041015
}
10051016
case llvm::Intrinsic::experimental_constrained_sitofp:
10061017
case llvm::Intrinsic::experimental_constrained_uitofp:
@@ -1037,9 +1048,9 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
10371048
default:
10381049
return error(i);
10391050
}
1040-
// TODO: missing support for exceptions
10411051
RETURN_IDENTIFIER(make_unique<FpConversionOp>(*ty, value_name(i), *val,
1042-
op, parse_rounding(i)));
1052+
op, parse_rounding(i),
1053+
parse_exceptions(i)));
10431054
}
10441055
case llvm::Intrinsic::lifetime_start:
10451056
case llvm::Intrinsic::lifetime_end:

tests/alive-tv/fp/fadd3-fail.srctgt.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
; ERROR: Target is more poisonous than source
22

33
define float @src(float noundef %a) {
4-
%x = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.upward", metadata !"fpexcept.strict")
5-
%y = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.upward", metadata !"fpexcept.strict")
6-
%ret = call float @llvm.experimental.constrained.fsub.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.strict")
4+
%x = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.upward", metadata !"fpexcept.ignore")
5+
%y = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.upward", metadata !"fpexcept.ignore")
6+
%ret = call float @llvm.experimental.constrained.fsub.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.ignore")
77
ret float %ret
88
}
99

tests/alive-tv/fp/fadd3.srctgt.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
define float @src(float %a) {
2-
%x = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.upward", metadata !"fpexcept.strict")
3-
%y = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.downward", metadata !"fpexcept.strict")
4-
%ret = call float @llvm.experimental.constrained.fsub.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.strict")
2+
%x = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.upward", metadata !"fpexcept.ignore")
3+
%y = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.downward", metadata !"fpexcept.ignore")
4+
%ret = call float @llvm.experimental.constrained.fsub.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.ignore")
55
ret float %ret
66
}
77

0 commit comments

Comments
 (0)