Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: Quiet NaNs on x86 hosts #75338

Merged
merged 1 commit into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1618,11 +1618,11 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1,
{
noway_assert(op2->gtOper == GT_CNS_DBL);
/* If we have an NaN value then don't record it */
if (_isnan(op2->AsDblCon()->gtDconVal))
if (_isnan(op2->AsDblCon()->DconValue()))
{
goto DONE_ASSERTION; // Don't make an assertion
}
assertion.op2.dconVal = op2->AsDblCon()->gtDconVal;
assertion.op2.dconVal = op2->AsDblCon()->DconValue();
}

//
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
case GT_CNS_DBL:
{
GenTreeDblCon* dblConst = tree->AsDblCon();
double constValue = dblConst->AsDblCon()->gtDconVal;
double constValue = dblConst->AsDblCon()->DconValue();
// TODO-ARM-CQ: Do we have a faster/smaller way to generate 0.0 in thumb2 ISA ?
if (targetType == TYP_FLOAT)
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2334,7 +2334,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
{
emitter* emit = GetEmitter();
emitAttr size = emitActualTypeSize(tree);
double constValue = tree->AsDblCon()->gtDconVal;
double constValue = tree->AsDblCon()->DconValue();

// Make sure we use "movi reg, 0x00" only for positive zero (0.0) and not for negative zero (-0.0)
if (*(__int64*)&constValue == 0)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1800,7 +1800,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
{
emitter* emit = GetEmitter();
emitAttr size = emitActualTypeSize(tree);
double constValue = tree->AsDblCon()->gtDconVal;
double constValue = tree->AsDblCon()->DconValue();

// Make sure we use "daddiu reg, zero, 0x00" only for positive zero (0.0)
// and not for negative zero (-0.0)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
}
else
{
double cns = tree->AsDblCon()->gtDconVal;
double cns = tree->AsDblCon()->DconValue();
CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns, size);

emit->emitIns_R_C(ins_Load(targetType), size, targetReg, hnd, 0);
Expand Down Expand Up @@ -7507,7 +7507,7 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
case GT_CNS_DBL:
{
GenTreeDblCon* dblConst = srcNode->AsDblCon();
CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(dblConst->gtDconVal, emitTypeSize(dblConst));
CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(dblConst->DconValue(), emitTypeSize(dblConst));

emit->emitIns_R_C_I(ins, size, dstReg, hnd, 0, ival);
return;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,7 @@ void GenTree::BashToConst(T value, var_types type /* = TYP_UNDEF */)

case GT_CNS_DBL:
assert(varTypeIsFloating(type));
AsDblCon()->gtDconVal = static_cast<double>(value);
AsDblCon()->SetDconValue(static_cast<double>(value));
break;

default:
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3874,7 +3874,7 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
assert(src->IsCnsFltOrDbl());
GenTreeDblCon* dblCns = src->AsDblCon();

CORINFO_FIELD_HANDLE hnd = emitFltOrDblConst(dblCns->gtDconVal, emitTypeSize(dblCns));
CORINFO_FIELD_HANDLE hnd = emitFltOrDblConst(dblCns->DconValue(), emitTypeSize(dblCns));
emitIns_R_C(ins, attr, dst->GetRegNum(), hnd, 0);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ void Compiler::fgDumpTree(FILE* fgxFile, GenTree* const tree)
}
else if (tree->IsCnsFltOrDbl())
{
fprintf(fgxFile, "%g", tree->AsDblCon()->gtDconVal);
fprintf(fgxFile, "%g", tree->AsDblCon()->DconValue());
}
else if (tree->IsLocal())
{
Expand Down
37 changes: 25 additions & 12 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2401,7 +2401,7 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK)
break;

case GT_CNS_DBL:
if (op1->AsDblCon()->gtDconVal == op2->AsDblCon()->gtDconVal)
if (op1->AsDblCon()->DconValue() == op2->AsDblCon()->DconValue())
return true;
break;
#endif
Expand Down Expand Up @@ -2841,13 +2841,16 @@ unsigned Compiler::gtHashValue(GenTree* tree)
#endif
break;
case GT_CNS_DBL:
bits = *(UINT64*)(&tree->AsDblCon()->gtDconVal);
{
double dcon = tree->AsDblCon()->DconValue();
memcpy(&bits, &dcon, sizeof(dcon));
#ifdef HOST_64BIT
add = bits;
#else // 32-bit host
add = genTreeHashAdd(uhi32(bits), ulo32(bits));
#endif
break;
}
case GT_CNS_STR:
add = tree->AsStrCon()->gtSconCPX;
break;
Expand Down Expand Up @@ -4616,7 +4619,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
costSz = 2 + 8;
}
#elif defined(TARGET_ARM64)
if (tree->IsFloatPositiveZero() || emitter::emitIns_valid_imm_for_fmov(tree->AsDblCon()->gtDconVal))
if (tree->IsFloatPositiveZero() || emitter::emitIns_valid_imm_for_fmov(tree->AsDblCon()->DconValue()))
{
// Zero and certain other immediates can be specially created with a single instruction
// These can be cheaply reconstituted but still take up 4-bytes of native codegen
Expand Down Expand Up @@ -8149,7 +8152,7 @@ GenTree* Compiler::gtClone(GenTree* tree, bool complexOK)

case GT_CNS_DBL:
{
copy = gtNewDconNode(tree->AsDblCon()->gtDconVal, tree->TypeGet());
copy = gtNewDconNode(tree->AsDblCon()->DconValue(), tree->TypeGet());
break;
}

Expand Down Expand Up @@ -8325,7 +8328,7 @@ GenTree* Compiler::gtCloneExpr(

case GT_CNS_DBL:
{
copy = gtNewDconNode(tree->AsDblCon()->gtDconVal, tree->TypeGet());
copy = gtNewDconNode(tree->AsDblCon()->DconValue(), tree->TypeGet());
goto DONE;
}

Expand Down Expand Up @@ -11227,15 +11230,25 @@ void Compiler::gtDispConst(GenTree* tree)
break;

case GT_CNS_DBL:
if (*((__int64*)&tree->AsDblCon()->gtDconVal) == (__int64)I64(0x8000000000000000))
{
double dcon = tree->AsDblCon()->DconValue();
if (FloatingPointUtils::isNegativeZero(dcon))
{
printf(" -0.00000");
}
else if (FloatingPointUtils::isNaN(dcon))
{
uint64_t bits;
static_assert_no_msg(sizeof(bits) == sizeof(dcon));
memcpy(&bits, &dcon, sizeof(dcon));
printf(" %#.17g(0x%llx)\n", dcon, bits);
}
else
{
printf(" %#.17g", tree->AsDblCon()->gtDconVal);
printf(" %#.17g", dcon);
}
break;
}

case GT_CNS_STR:
printf("<string constant>");
Expand Down Expand Up @@ -14388,7 +14401,7 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree)

// Fold constant DOUBLE unary operator.

d1 = op1->AsDblCon()->gtDconVal;
d1 = op1->AsDblCon()->DconValue();

switch (tree->OperGet())
{
Expand Down Expand Up @@ -15024,11 +15037,11 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree)
}

assert(op1->OperIs(GT_CNS_DBL));
d1 = op1->AsDblCon()->gtDconVal;
d1 = op1->AsDblCon()->DconValue();

assert(varTypeIsFloating(op2->TypeGet()));
assert(op2->OperIs(GT_CNS_DBL));
d2 = op2->AsDblCon()->gtDconVal;
d2 = op2->AsDblCon()->DconValue();

// Special case - check if we have NaN operands.
// For comparisons if not an unordered operation always return 0.
Expand Down Expand Up @@ -17199,7 +17212,7 @@ bool GenTreeVecCon::HandleArgForHWIntrinsicCreate(GenTree* arg, int argIdx, simd
{
if (arg->IsCnsFltOrDbl())
{
simd32Val.f32[argIdx] = static_cast<float>(arg->AsDblCon()->gtDconVal);
simd32Val.f32[argIdx] = static_cast<float>(arg->AsDblCon()->DconValue());
return true;
}
else
Expand All @@ -17215,7 +17228,7 @@ bool GenTreeVecCon::HandleArgForHWIntrinsicCreate(GenTree* arg, int argIdx, simd
{
if (arg->IsCnsFltOrDbl())
{
simd32Val.f64[argIdx] = static_cast<double>(arg->AsDblCon()->gtDconVal);
simd32Val.f64[argIdx] = static_cast<double>(arg->AsDblCon()->DconValue());
return true;
}
else
Expand Down
25 changes: 19 additions & 6 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3306,18 +3306,31 @@ inline void GenTreeIntConCommon::SetValueTruncating(T value)

struct GenTreeDblCon : public GenTree
{
private:
double gtDconVal;

public:
double DconValue() const
{
return gtDconVal;
}

void SetDconValue(double value)
{
gtDconVal = FloatingPointUtils::normalize(value);
}

bool isBitwiseEqual(GenTreeDblCon* other)
{
unsigned __int64 bits = *(unsigned __int64*)(&gtDconVal);
unsigned __int64 otherBits = *(unsigned __int64*)(&(other->gtDconVal));
return (bits == otherBits);
}

GenTreeDblCon(double val, var_types type = TYP_DOUBLE) : GenTree(GT_CNS_DBL, type), gtDconVal(val)
GenTreeDblCon(double val, var_types type = TYP_DOUBLE) : GenTree(GT_CNS_DBL, type)
{
assert(varTypeIsFloating(type));
SetDconValue(val);
}
#if DEBUGGABLE_GENTREE
GenTreeDblCon() : GenTree()
Expand Down Expand Up @@ -8446,7 +8459,7 @@ inline bool GenTree::IsFloatAllBitsSet() const
{
if (IsCnsFltOrDbl())
{
double constValue = AsDblCon()->gtDconVal;
double constValue = AsDblCon()->DconValue();

if (TypeIs(TYP_FLOAT))
{
Expand All @@ -8473,7 +8486,7 @@ inline bool GenTree::IsFloatNaN() const
{
if (IsCnsFltOrDbl())
{
double constValue = AsDblCon()->gtDconVal;
double constValue = AsDblCon()->DconValue();
return FloatingPointUtils::isNaN(constValue);
}

Expand All @@ -8491,7 +8504,7 @@ inline bool GenTree::IsFloatNegativeZero() const
{
if (IsCnsFltOrDbl())
{
double constValue = AsDblCon()->gtDconVal;
double constValue = AsDblCon()->DconValue();
return FloatingPointUtils::isNegativeZero(constValue);
}

Expand All @@ -8512,7 +8525,7 @@ inline bool GenTree::IsFloatPositiveZero() const
// This implementation is almost identical to IsCnsNonZeroFltOrDbl
// but it is easier to parse out
// rather than using !IsCnsNonZeroFltOrDbl.
double constValue = AsDblCon()->gtDconVal;
double constValue = AsDblCon()->DconValue();
return FloatingPointUtils::isPositiveZero(constValue);
}

Expand Down Expand Up @@ -9300,7 +9313,7 @@ inline bool GenTree::IsCnsNonZeroFltOrDbl() const
{
if (IsCnsFltOrDbl())
{
double constValue = AsDblCon()->gtDconVal;
double constValue = AsDblCon()->DconValue();
return *(__int64*)&constValue != 0;
}

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/hwintrinsicarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,

for (uint32_t index = 0; index < sig->numArgs; index++)
{
cnsVal = static_cast<float>(impPopStack().val->AsDblCon()->gtDconVal);
cnsVal = static_cast<float>(impPopStack().val->AsDblCon()->DconValue());
vecCon->gtSimd16Val.f32[simdLength - 1 - index] = cnsVal;
}

Expand All @@ -709,7 +709,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,

for (uint32_t index = 0; index < sig->numArgs; index++)
{
cnsVal = static_cast<double>(impPopStack().val->AsDblCon()->gtDconVal);
cnsVal = static_cast<double>(impPopStack().val->AsDblCon()->DconValue());
vecCon->gtSimd16Val.f64[simdLength - 1 - index] = cnsVal;
}

Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/hwintrinsiccodegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
assert(intrin.op2->isContainedIntOrIImmed());
assert(intrin.op2->AsIntCon()->gtIconVal == 0);

const double dataValue = intrin.op3->AsDblCon()->gtDconVal;
const double dataValue = intrin.op3->AsDblCon()->DconValue();
GetEmitter()->emitIns_R_F(INS_fmov, emitSize, targetReg, dataValue, opt);
}
else
Expand Down Expand Up @@ -736,7 +736,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
if (intrin.op1->isContainedFltOrDblImmed())
{
// fmov reg, #imm8
const double dataValue = intrin.op1->AsDblCon()->gtDconVal;
const double dataValue = intrin.op1->AsDblCon()->DconValue();
GetEmitter()->emitIns_R_F(ins, emitTypeSize(intrin.baseType), targetReg, dataValue, INS_OPTS_NONE);
}
else if (varTypeIsFloating(intrin.baseType))
Expand Down Expand Up @@ -799,7 +799,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
{
if (intrin.op1->isContainedFltOrDblImmed())
{
const double dataValue = intrin.op1->AsDblCon()->gtDconVal;
const double dataValue = intrin.op1->AsDblCon()->DconValue();
GetEmitter()->emitIns_R_F(INS_fmov, emitSize, targetReg, dataValue, opt);
}
else if (intrin.id == NI_AdvSimd_Arm64_DuplicateToVector64)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/hwintrinsicxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,

for (uint32_t index = 0; index < sig->numArgs; index++)
{
cnsVal = static_cast<float>(impPopStack().val->AsDblCon()->gtDconVal);
cnsVal = static_cast<float>(impPopStack().val->AsDblCon()->DconValue());
vecCon->gtSimd32Val.f32[simdLength - 1 - index] = cnsVal;
}

Expand All @@ -1060,7 +1060,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,

for (uint32_t index = 0; index < sig->numArgs; index++)
{
cnsVal = static_cast<double>(impPopStack().val->AsDblCon()->gtDconVal);
cnsVal = static_cast<double>(impPopStack().val->AsDblCon()->DconValue());
vecCon->gtSimd32Val.f64[simdLength - 1 - index] = cnsVal;
}

Expand Down
Loading