Skip to content

Commit f10d4c3

Browse files
authored
Add long/ulong->float cast helpers (#114597)
* add long/ulong->float cast helpers * fix const folding
1 parent b4bd13d commit f10d4c3

File tree

22 files changed

+115
-75
lines changed

22 files changed

+115
-75
lines changed

docs/design/coreclr/botr/readytorun-format.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ enum ReadyToRunHelper
814814
READYTORUN_HELPER_GetString = 0x50,
815815

816816
// Used by /Tuning for Profile optimizations
817-
READYTORUN_HELPER_LogMethodEnter = 0x51,
817+
READYTORUN_HELPER_LogMethodEnter = 0x51, // Unused since READYTORUN_MAJOR_VERSION 10.0
818818

819819
// Reflection helpers
820820
READYTORUN_HELPER_GetRuntimeTypeHandle = 0x54,
@@ -870,12 +870,14 @@ enum ReadyToRunHelper
870870
READYTORUN_HELPER_Dbl2UIntOvf = 0xD5,
871871
READYTORUN_HELPER_Dbl2ULng = 0xD6,
872872
READYTORUN_HELPER_Dbl2ULngOvf = 0xD7,
873+
READYTORUN_HELPER_Lng2Flt = 0xD8,
874+
READYTORUN_HELPER_ULng2Flt = 0xD9,
873875

874876
// Floating point ops
875877
READYTORUN_HELPER_DblRem = 0xE0,
876878
READYTORUN_HELPER_FltRem = 0xE1,
877-
READYTORUN_HELPER_DblRound = 0xE2,
878-
READYTORUN_HELPER_FltRound = 0xE3,
879+
READYTORUN_HELPER_DblRound = 0xE2, // Unused since READYTORUN_MAJOR_VERSION 10.0
880+
READYTORUN_HELPER_FltRound = 0xE3, // Unused since READYTORUN_MAJOR_VERSION 10.0
879881

880882
#ifndef _TARGET_X86_
881883
// Personality routines

src/coreclr/inc/corinfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,9 @@ enum CorInfoHelpFunc
336336
CORINFO_HELP_LMOD,
337337
CORINFO_HELP_ULDIV,
338338
CORINFO_HELP_ULMOD,
339+
CORINFO_HELP_LNG2FLT, // Convert a signed int64 to a float
339340
CORINFO_HELP_LNG2DBL, // Convert a signed int64 to a double
341+
CORINFO_HELP_ULNG2FLT, // Convert a unsigned int64 to a float
340342
CORINFO_HELP_ULNG2DBL, // Convert a unsigned int64 to a double
341343
CORINFO_HELP_DBL2INT,
342344
CORINFO_HELP_DBL2INT_OVF,

src/coreclr/inc/jiteeversionguid.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737

3838
#include <minipal/guid.h>
3939

40-
constexpr GUID JITEEVersionIdentifier = { /* 26d0dde8-bc9d-4543-9b9a-57ad8b1acdc0 */
41-
0x26d0dde8,
42-
0xbc9d,
43-
0x4543,
44-
{0x9b, 0x9a, 0x57, 0xad, 0x8b, 0x1a, 0xcd, 0xc0}
40+
constexpr GUID JITEEVersionIdentifier = { /* 7ce8764d-ac60-4e05-a6e4-448c1eb8cf35 */
41+
0x7ce8764d,
42+
0xac60,
43+
0x4e05,
44+
{0xa6, 0xe4, 0x44, 0x8c, 0x1e, 0xb8, 0xcf, 0x35}
4545
};
4646

4747
#endif // JIT_EE_VERSIONING_GUID_H

src/coreclr/inc/jithelpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@
8484
JITHELPER(CORINFO_HELP_ULDIV, NULL, METHOD__NIL)
8585
JITHELPER(CORINFO_HELP_ULMOD, NULL, METHOD__NIL)
8686
#endif // TARGET_64BIT
87+
JITHELPER(CORINFO_HELP_LNG2FLT, JIT_Lng2Flt, METHOD__NIL)
8788
JITHELPER(CORINFO_HELP_LNG2DBL, JIT_Lng2Dbl, METHOD__NIL)
89+
JITHELPER(CORINFO_HELP_ULNG2FLT, JIT_ULng2Flt, METHOD__NIL)
8890
JITHELPER(CORINFO_HELP_ULNG2DBL, JIT_ULng2Dbl, METHOD__NIL)
8991
JITHELPER(CORINFO_HELP_DBL2INT, JIT_Dbl2Int, METHOD__NIL)
9092
DYNAMICJITHELPER(CORINFO_HELP_DBL2INT_OVF, NULL, METHOD__MATH__CONVERT_TO_INT32_CHECKED)

src/coreclr/inc/readytorun.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
// If you update this, ensure you run `git grep MINIMUM_READYTORUN_MAJOR_VERSION`
2121
// and handle pending work.
2222
#define READYTORUN_MAJOR_VERSION 13
23-
#define READYTORUN_MINOR_VERSION 0x0000
23+
#define READYTORUN_MINOR_VERSION 0x0001
2424

2525
#define MINIMUM_READYTORUN_MAJOR_VERSION 13
2626

@@ -408,6 +408,8 @@ enum ReadyToRunHelper
408408
READYTORUN_HELPER_Dbl2UIntOvf = 0xD5,
409409
READYTORUN_HELPER_Dbl2ULng = 0xD6,
410410
READYTORUN_HELPER_Dbl2ULngOvf = 0xD7,
411+
READYTORUN_HELPER_Lng2Flt = 0xD8,
412+
READYTORUN_HELPER_ULng2Flt = 0xD9,
411413

412414
// Floating point ops
413415
READYTORUN_HELPER_DblRem = 0xE0,

src/coreclr/inc/readytorunhelpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ HELPER(READYTORUN_HELPER_Dbl2UInt, CORINFO_HELP_DBL2UINT,
8686
HELPER(READYTORUN_HELPER_Dbl2UIntOvf, CORINFO_HELP_DBL2UINT_OVF, )
8787
HELPER(READYTORUN_HELPER_Dbl2ULng, CORINFO_HELP_DBL2ULNG, )
8888
HELPER(READYTORUN_HELPER_Dbl2ULngOvf, CORINFO_HELP_DBL2ULNG_OVF, )
89+
HELPER(READYTORUN_HELPER_Lng2Flt, CORINFO_HELP_LNG2FLT, )
90+
HELPER(READYTORUN_HELPER_ULng2Flt, CORINFO_HELP_ULNG2FLT, )
8991

9092
HELPER(READYTORUN_HELPER_FltRem, CORINFO_HELP_FLTREM, )
9193
HELPER(READYTORUN_HELPER_DblRem, CORINFO_HELP_DBLREM, )

src/coreclr/jit/gentree.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15689,7 +15689,6 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree)
1568915689

1569015690
case TYP_FLOAT:
1569115691
{
15692-
#ifdef TARGET_64BIT
1569315692
if (tree->IsUnsigned() && (lval1 < 0))
1569415693
{
1569515694
f1 = FloatingPointUtils::convertUInt64ToFloat((uint64_t)lval1);
@@ -15698,20 +15697,6 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree)
1569815697
{
1569915698
f1 = (float)lval1;
1570015699
}
15701-
#else
15702-
// 32-bit currently does a 2-step conversion, which is incorrect
15703-
// but which we are going to take a breaking change around early
15704-
// in a release cycle.
15705-
15706-
if (tree->IsUnsigned() && (lval1 < 0))
15707-
{
15708-
f1 = forceCastToFloat(FloatingPointUtils::convertUInt64ToDouble((uint64_t)lval1));
15709-
}
15710-
else
15711-
{
15712-
f1 = forceCastToFloat((double)lval1);
15713-
}
15714-
#endif
1571515700

1571615701
d1 = f1;
1571715702
goto CNS_DOUBLE;

src/coreclr/jit/importer.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8221,7 +8221,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
82218221
goto CONV;
82228222

82238223
case CEE_CONV_R_UN:
8224-
lclTyp = TYP_DOUBLE;
8224+
// Because there is no IL instruction conv.r4.un, compilers consistently
8225+
// emit conv.r.un followed immediately by conv.r4 for unsigned->float casts.
8226+
// We recognize this pattern and create the intended cast.
8227+
// Otherwise, conv.r.un is treated as a cast to double.
8228+
lclTyp = ((OPCODE)getU1LittleEndian(codeAddr) == CEE_CONV_R4) ? TYP_FLOAT : TYP_DOUBLE;
82258229
goto CONV_UN;
82268230

82278231
CONV_UN:

src/coreclr/jit/morph.cpp

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -427,22 +427,16 @@ GenTree* Compiler::fgMorphExpandCast(GenTreeCast* tree)
427427
// converts long/ulong --> float/double casts into helper calls.
428428
else if (varTypeIsFloating(dstType) && varTypeIsLong(srcType))
429429
{
430+
CorInfoHelpFunc helper = CORINFO_HELP_UNDEF;
430431
if (dstType == TYP_FLOAT)
431432
{
432-
// there is only a double helper, so we
433-
// - change the dsttype to double
434-
// - insert a cast from double to float
435-
// - recurse into the resulting tree
436-
tree->CastToType() = TYP_DOUBLE;
437-
tree->gtType = TYP_DOUBLE;
438-
439-
tree = gtNewCastNode(TYP_FLOAT, tree, false, TYP_FLOAT);
440-
441-
return fgMorphTree(tree);
433+
helper = tree->IsUnsigned() ? CORINFO_HELP_ULNG2FLT : CORINFO_HELP_LNG2FLT;
434+
}
435+
else
436+
{
437+
helper = tree->IsUnsigned() ? CORINFO_HELP_ULNG2DBL : CORINFO_HELP_LNG2DBL;
442438
}
443-
if (tree->gtFlags & GTF_UNSIGNED)
444-
return fgMorphCastIntoHelper(tree, CORINFO_HELP_ULNG2DBL, oper);
445-
return fgMorphCastIntoHelper(tree, CORINFO_HELP_LNG2DBL, oper);
439+
return fgMorphCastIntoHelper(tree, helper, oper);
446440
}
447441
#endif // TARGET_ARM
448442

@@ -482,41 +476,23 @@ GenTree* Compiler::fgMorphExpandCast(GenTreeCast* tree)
482476

483477
if (srcType == TYP_ULONG)
484478
{
485-
return fgMorphCastIntoHelper(tree, CORINFO_HELP_ULNG2DBL, oper);
479+
CorInfoHelpFunc helper = (dstType == TYP_FLOAT) ? CORINFO_HELP_ULNG2FLT : CORINFO_HELP_ULNG2DBL;
480+
return fgMorphCastIntoHelper(tree, helper, oper);
486481
}
487482
else if (srcType == TYP_UINT && !canUseEvexEncoding())
488483
{
489484
oper = gtNewCastNode(TYP_LONG, oper, true, TYP_LONG);
490485
oper->gtFlags |= (tree->gtFlags & (GTF_OVERFLOW | GTF_EXCEPT));
491486
tree->ClearUnsigned();
492-
return fgMorphCastIntoHelper(tree, CORINFO_HELP_LNG2DBL, oper);
487+
488+
CorInfoHelpFunc helper = (dstType == TYP_FLOAT) ? CORINFO_HELP_LNG2FLT : CORINFO_HELP_LNG2DBL;
489+
return fgMorphCastIntoHelper(tree, helper, oper);
493490
}
494491
}
495492
else if (!tree->IsUnsigned() && (srcType == TYP_LONG) && varTypeIsFloating(dstType))
496493
{
497-
oper = fgMorphCastIntoHelper(tree, CORINFO_HELP_LNG2DBL, oper);
498-
499-
// Since we don't have a Jit Helper that converts to a TYP_FLOAT
500-
// we just use the one that converts to a TYP_DOUBLE
501-
// and then add a cast to TYP_FLOAT
502-
//
503-
if ((dstType == TYP_FLOAT) && oper->OperIs(GT_CALL))
504-
{
505-
// Fix the return type to be TYP_DOUBLE
506-
//
507-
oper->gtType = TYP_DOUBLE;
508-
oper->SetMorphed(this);
509-
510-
// Add a Cast to TYP_FLOAT
511-
//
512-
tree = gtNewCastNode(TYP_FLOAT, oper, false, TYP_FLOAT);
513-
tree->SetMorphed(this);
514-
return tree;
515-
}
516-
else
517-
{
518-
return oper;
519-
}
494+
CorInfoHelpFunc helper = (dstType == TYP_FLOAT) ? CORINFO_HELP_LNG2FLT : CORINFO_HELP_LNG2DBL;
495+
return fgMorphCastIntoHelper(tree, helper, oper);
520496
}
521497
#endif // TARGET_X86
522498
else if (varTypeIsGC(srcType) != varTypeIsGC(dstType))

src/coreclr/jit/utils.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,9 @@ void HelperCallProperties::init()
15301530
isNoGC = true;
15311531
FALLTHROUGH;
15321532
case CORINFO_HELP_LMUL:
1533+
case CORINFO_HELP_LNG2FLT:
15331534
case CORINFO_HELP_LNG2DBL:
1535+
case CORINFO_HELP_ULNG2FLT:
15341536
case CORINFO_HELP_ULNG2DBL:
15351537
case CORINFO_HELP_DBL2INT:
15361538
case CORINFO_HELP_DBL2LNG:

0 commit comments

Comments
 (0)