add fast math support to fcmp
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -1215,8 +1215,15 @@ void FCmp::print(ostream &os) const {
case UNE: condtxt = "une "; break;
case UNO: condtxt = "uno "; break;
}
- os << getName() << " = fcmp " << condtxt << print_type(getType())
- << a->getName() << ", " << b->getName();
+ os << getName() << " = fcmp ";
+ if (flags & NNaN)
+ os << "nnan ";
+ if (flags & NInf)
+ os << "ninf ";
+ if (flags & Reassoc)
+ os << "reassoc ";
+ os << condtxt << print_type(getType()) << a->getName() << ", "
+ << b->getName();
}
StateValue FCmp::toSMT(State &s) const {
@@ -1242,7 +1249,15 @@ StateValue FCmp::toSMT(State &s) const {
case UNE: val = av.fune(bv); break;
case UNO: val = av.funo(bv); break;
}
- return { val.toBVBool(), a.non_poison && b.non_poison };
+ expr np = a.non_poison && b.non_poison;
+ if (flags & NNaN)
+ np &= !av.isNaN() && !bv.isNaN();
+ if (flags & NInf)
+ np &= !av.isInf() && !bv.isInf();
+ if (flags & Reassoc)
+ np &= expr(); // TODO
+
+ return { val.toBVBool(), move(np) };
};
if (auto agg = a->getType().getAsAggregateType()) {
@@ -1264,7 +1279,7 @@ expr FCmp::getTypeConstraints(const Function &f) const {
}
unique_ptr<Instr> FCmp::dup(const string &suffix) const {
- return make_unique<FCmp>(getType(), getName() + suffix, cond, *a, *b);
+ return make_unique<FCmp>(getType(), getName() + suffix, cond, *a, *b, flags);
}

MODIFY
ir/instr.h
ir/instr.h
@@ -198,14 +198,17 @@ class FCmp final : public Instr {
public:
enum Cond { OEQ, OGT, OGE, OLT, OLE, ONE, ORD,
UEQ, UGT, UGE, ULT, ULE, UNE, UNO };
+ enum Flags { None = 0, NNaN = 1, NInf = 2, Reassoc = 4 };
private:
Value *a, *b;
Cond cond;
+ unsigned flags = 0;
public:
- FCmp(Type &type, std::string &&name, Cond cond, Value &a, Value &b)
- : Instr(type, move(name)), a(&a), b(&b), cond(cond) {}
+ FCmp(Type &type, std::string &&name, Cond cond, Value &a, Value &b,
+ unsigned flags)
+ : Instr(type, move(name)), a(&a), b(&b), cond(cond), flags(flags) {}
std::vector<Value*> operands() const override;
void rauw(const Value &what, Value &with) override;

MODIFY
llvm_util/llvm2alive.cpp
llvm_util/llvm2alive.cpp
@@ -270,11 +270,16 @@ public:
UNREACHABLE();
}
- // TODO: support FP fast-math stuff
- if (i.getFastMathFlags().any())
- return error(i);
-
- RETURN_IDENTIFIER(make_unique<FCmp>(*ty, value_name(i), cond, *a, *b));
+ unsigned flags = 0;
+ if (i.getFastMathFlags().noNaNs())
+ flags |= FCmp::NNaN;
+ if (i.getFastMathFlags().noInfs())
+ flags |= FCmp::NInf;
+ if (i.getFastMathFlags().allowReassoc())
+ flags |= FCmp::Reassoc;
+
+ RETURN_IDENTIFIER(make_unique<FCmp>(*ty, value_name(i), cond, *a, *b,
+ flags));
}
RetTy visitSelectInst(llvm::SelectInst &i) {

MODIFY
tools/alive_parser.cpp
tools/alive_parser.cpp
@@ -844,7 +844,7 @@ static unique_ptr<Instr> parse_fcmp(string_view name) {
get_constant(cond_t == TRUE, bool_ty),
UnaryOp::Copy);
default:
- return make_unique<FCmp>(bool_ty, string(name), cond, a, b);
+ return make_unique<FCmp>(bool_ty, string(name), cond, a, b, 0);
}
UNREACHABLE();
}

add fast math support to fcmp