From 0eccd9580acf7db48d9940e64bbb3a783e867944 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 10 Sep 2025 11:50:41 -0700 Subject: [PATCH] Implement CEE_CKFINITE in the interpreter --- src/coreclr/interpreter/compiler.cpp | 26 ++++++++++++++++++++++++++ src/coreclr/interpreter/inc/intops.def | 3 +++ src/coreclr/vm/interpexec.cpp | 23 +++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 26cd08599b9c3e..31d2954f82618e 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -4353,6 +4353,32 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) m_ip++; break; } + + case CEE_CKFINITE: + { + CHECK_STACK(1); + int sVar = m_pStackPointer[-1].var; + StackType argType = m_pStackPointer[-1].type; + switch (argType) + { + case StackTypeR4: + AddIns(INTOP_CKFINITE_R4); + break; + case StackTypeR8: + AddIns(INTOP_CKFINITE_R8); + break; + default: + BADCODE("ckfinite operand must be R4 or R8"); + break; + } + m_pStackPointer--; + PushStackType(argType, nullptr); + m_pLastNewIns->SetSVar(sVar); + m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); + m_ip++; + break; + } + case CEE_CONV_U1: CHECK_STACK(1); switch (m_pStackPointer[-1].type) diff --git a/src/coreclr/interpreter/inc/intops.def b/src/coreclr/interpreter/inc/intops.def index f8ca4befbc9a42..99dd4cf1a6feb7 100644 --- a/src/coreclr/interpreter/inc/intops.def +++ b/src/coreclr/interpreter/inc/intops.def @@ -128,6 +128,9 @@ OPDEF(INTOP_NEG_R8, "neg.r8", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_NOT_I4, "not.i4", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_NOT_I8, "not.i8", 3, 1, 1, InterpOpNoArgs) +OPDEF(INTOP_CKFINITE_R4, "ckfinite.r4", 3, 1, 1, InterpOpNoArgs) +OPDEF(INTOP_CKFINITE_R8, "ckfinite.r8", 3, 1, 1, InterpOpNoArgs) + OPDEF(INTOP_CONV_R_UN_I4, "conv.r.un.i4", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_CONV_R_UN_I8, "conv.r.un.i8", 3, 1, 1, InterpOpNoArgs) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index e5bd23c538a2cf..29c23d2e7b43c4 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -527,6 +527,20 @@ template void ConvOvfHelper(int8_t *stack, } } +static float CkfiniteHelper(float value) +{ + if (!std::isfinite(value)) + COMPlusThrow(kArithmeticException); + return value; +} + +static double CkfiniteHelper(double value) +{ + if (!std::isfinite(value)) + COMPlusThrow(kArithmeticException); + return value; +} + void* DoGenericLookup(void* genericVarAsPtr, InterpGenericLookup* pLookup) { // TODO! If this becomes a performance bottleneck, we could expand out the various permutations of this @@ -804,6 +818,15 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 4; break; + case INTOP_CKFINITE_R4: + LOCAL_VAR(ip[1], float) = CkfiniteHelper(LOCAL_VAR(ip[2], float)); + ip += 3; + break; + case INTOP_CKFINITE_R8: + LOCAL_VAR(ip[1], double) = CkfiniteHelper(LOCAL_VAR(ip[2], double)); + ip += 3; + break; + case INTOP_CONV_R_UN_I4: LOCAL_VAR(ip[1], double) = (double)LOCAL_VAR(ip[2], uint32_t); ip += 3;