add support for llvm.isnan intrinsic
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -834,6 +834,7 @@ void UnaryOp::print(ostream &os) const {
case BSwap: str = "bswap "; break;
case Ctpop: str = "ctpop "; break;
case IsConstant: str = "is.constant "; break;
+ case IsNaN: str = "isnan "; break;
case FAbs: str = "fabs "; break;
case FNeg: str = "fneg "; break;
case Ceil: str = "ceil "; break;
@@ -883,6 +884,11 @@ StateValue UnaryOp::toSMT(State &s) const {
s.addQuantVar(var);
return { move(var), true };
}
+ case IsNaN:
+ fn = [](auto v, auto np) -> StateValue {
+ return { v.isNaN(), expr(np) };
+ };
+ break;
case FAbs:
fn = [&](auto v, auto np) -> StateValue {
return fm_poison(s, v, np, [](expr &v) { return v.fabs(); }, fmath, true);
@@ -966,6 +972,11 @@ expr UnaryOp::getTypeConstraints(const Function &f) const {
case IsConstant:
instrconstr = getType().enforceIntType(1);
break;
+ case IsNaN:
+ instrconstr = val->getType().enforceFloatOrVectorType() &&
+ getType().enforceIntOrVectorType(1) &&
+ getType().enforceVectorTypeIff(val->getType());
+ break;
case FAbs:
case FNeg:
case Ceil:

MODIFY
ir/instr.h
ir/instr.h
@@ -61,7 +61,7 @@ public:
class UnaryOp final : public Instr {
public:
enum Op {
- Copy, BitReverse, BSwap, Ctpop, IsConstant, FAbs, FNeg,
+ Copy, BitReverse, BSwap, Ctpop, IsConstant, IsNaN, FAbs, FNeg,
Ceil, Floor, Round, RoundEven, Trunc, Sqrt, FFS
};

MODIFY
llvm_util/llvm2alive.cpp
llvm_util/llvm2alive.cpp
@@ -806,6 +806,7 @@ public:
case llvm::Intrinsic::fabs:
case llvm::Intrinsic::floor:
case llvm::Intrinsic::is_constant:
+ case llvm::Intrinsic::isnan:
case llvm::Intrinsic::round:
case llvm::Intrinsic::roundeven:
case llvm::Intrinsic::sqrt:
@@ -823,6 +824,7 @@ public:
case llvm::Intrinsic::fabs: op = UnaryOp::FAbs; break;
case llvm::Intrinsic::floor: op = UnaryOp::Floor; break;
case llvm::Intrinsic::is_constant: op = UnaryOp::IsConstant; break;
+ case llvm::Intrinsic::isnan: op = UnaryOp::IsNaN; break;
case llvm::Intrinsic::round: op = UnaryOp::Round; break;
case llvm::Intrinsic::roundeven: op = UnaryOp::RoundEven; break;
case llvm::Intrinsic::sqrt: op = UnaryOp::Sqrt; break;

add support for llvm.isnan intrinsic