[clang][Interp] Implement __builtin_isinf

Differential Revision: https://reviews.llvm.org/D155371
This commit is contained in:
Timm Bäder 2023-07-15 17:47:00 +02:00
parent d9847cde48
commit 72450a7793
3 changed files with 30 additions and 0 deletions

View File

@ -87,6 +87,7 @@ public:
bool isMin() const { return F.isSmallest(); }
bool isMinusOne() const { return F.isExactlyValue(-1.0); }
bool isNan() const { return F.isNaN(); }
bool isInf() const { return F.isInfinity(); }
bool isFinite() const { return F.isFinite(); }
ComparisonCategoryResult compare(const Floating &RHS) const {

View File

@ -173,6 +173,20 @@ static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC,
return true;
}
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame, const Function *F,
bool CheckSign) {
const Floating &Arg = S.Stk.peek<Floating>();
bool IsInf = Arg.isInf();
if (CheckSign)
S.Stk.push<Integral<32, true>>(
Integral<32, true>::from(IsInf ? (Arg.isNegative() ? -1 : 1) : 0));
else
S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Arg.isInf()));
return true;
}
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
InterpFrame *Frame = S.Current;
APValue Dummy;
@ -239,6 +253,16 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
return Ret<PT_Sint32>(S, OpPC, Dummy);
break;
case Builtin::BI__builtin_isinf:
if (interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/false))
return Ret<PT_Sint32>(S, OpPC, Dummy);
break;
case Builtin::BI__builtin_isinf_sign:
if (interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/true))
return Ret<PT_Sint32>(S, OpPC, Dummy);
break;
default:
return false;
}

View File

@ -72,3 +72,8 @@ namespace fmin {
constexpr float min3 = __builtin_fmin(__builtin_inf(), __builtin_nan(""));
static_assert(min3 == __builtin_inf(), "");
}
namespace inf {
static_assert(__builtin_isinf(__builtin_inf()), "");
static_assert(!__builtin_isinf(1.0), "");
}