Skip to content

Commit bfa124f

Browse files
authored
JIT: Speed up floating to integer casts on x86/x64 (#114410)
* speed up floating to integer conversion * fix linux build * fix double->uint SSE, don't use fixupimm
1 parent 8b00880 commit bfa124f

File tree

7 files changed

+460
-434
lines changed

7 files changed

+460
-434
lines changed

src/coreclr/jit/lower.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -550,13 +550,9 @@ GenTree* Lowering::LowerNode(GenTree* node)
550550
return nextNode;
551551
}
552552

553-
nextNode = LowerCast(node);
554-
if (nextNode != nullptr)
555-
{
556-
return nextNode;
557-
}
553+
LowerCast(node);
554+
break;
558555
}
559-
break;
560556

561557
case GT_BITCAST:
562558
{

src/coreclr/jit/lower.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ class Lowering final : public Phase
427427
GenTree* switchValue,
428428
weight_t defaultLikelihood);
429429

430-
GenTree* LowerCast(GenTree* node);
430+
void LowerCast(GenTree* node);
431431

432432
#if !CPU_LOAD_STORE_ARCH
433433
bool IsRMWIndirCandidate(GenTree* operand, GenTree* storeInd);

src/coreclr/jit/lowerarmarch.cpp

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -968,22 +968,11 @@ void Lowering::LowerPutArgStkOrSplit(GenTreePutArgStk* putArgNode)
968968
// tree - GT_CAST node to be lowered
969969
//
970970
// Return Value:
971-
// nextNode to be lowered if tree is modified else returns nullptr
972-
//
973-
// Notes:
974-
// Casts from float/double to a smaller int type are transformed as follows:
975-
// GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte)
976-
// GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte)
977-
// GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16)
978-
// GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16)
979-
//
980-
// Note that for the overflow conversions we still depend on helper calls and
981-
// don't expect to see them here.
982-
// i) GT_CAST(float/double, int type with overflow detection)
971+
// None.
983972
//
984-
GenTree* Lowering::LowerCast(GenTree* tree)
973+
void Lowering::LowerCast(GenTree* tree)
985974
{
986-
assert(tree->OperGet() == GT_CAST);
975+
assert(tree->OperIs(GT_CAST));
987976

988977
JITDUMP("LowerCast for: ");
989978
DISPNODE(tree);
@@ -995,17 +984,16 @@ GenTree* Lowering::LowerCast(GenTree* tree)
995984

996985
if (varTypeIsFloating(srcType))
997986
{
987+
// Overflow casts should have been converted to helper call in morph.
998988
noway_assert(!tree->gtOverflow());
999-
assert(!varTypeIsSmall(dstType)); // fgMorphCast creates intermediate casts when converting from float to small
1000-
// int.
989+
// Small types should have had an intermediate int cast inserted in morph.
990+
assert(!varTypeIsSmall(dstType));
1001991
}
1002992

1003993
assert(!varTypeIsSmall(srcType));
1004994

1005995
// Now determine if we have operands that should be contained.
1006996
ContainCheckCast(tree->AsCast());
1007-
1008-
return nullptr;
1009997
}
1010998

1011999
//------------------------------------------------------------------------

src/coreclr/jit/lowerloongarch64.cpp

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -515,21 +515,9 @@ void Lowering::LowerPutArgStkOrSplit(GenTreePutArgStk* putArgNode)
515515
// Return Value:
516516
// None.
517517
//
518-
// Notes:
519-
// Casts from float/double to a smaller int type are transformed as follows:
520-
// GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte)
521-
// GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte)
522-
// GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16)
523-
// GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16)
524-
//
525-
// Note that for the overflow conversions we still depend on helper calls and
526-
// don't expect to see them here.
527-
// i) GT_CAST(float/double, int type with overflow detection)
528-
//
529-
530-
GenTree* Lowering::LowerCast(GenTree* tree)
518+
void Lowering::LowerCast(GenTree* tree)
531519
{
532-
assert(tree->OperGet() == GT_CAST);
520+
assert(tree->OperIs(GT_CAST));
533521

534522
JITDUMP("LowerCast for: ");
535523
DISPNODE(tree);
@@ -541,17 +529,16 @@ GenTree* Lowering::LowerCast(GenTree* tree)
541529

542530
if (varTypeIsFloating(srcType))
543531
{
532+
// Overflow casts should have been converted to helper call in morph.
544533
noway_assert(!tree->gtOverflow());
545-
assert(!varTypeIsSmall(dstType)); // fgMorphCast creates intermediate casts when converting from float to small
546-
// int.
534+
// Small types should have had an intermediate int cast inserted in morph.
535+
assert(!varTypeIsSmall(dstType));
547536
}
548537

549538
assert(!varTypeIsSmall(srcType));
550539

551540
// Now determine if we have operands that should be contained.
552541
ContainCheckCast(tree->AsCast());
553-
554-
return nullptr;
555542
}
556543

557544
//------------------------------------------------------------------------

src/coreclr/jit/lowerriscv64.cpp

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -504,21 +504,9 @@ void Lowering::LowerPutArgStkOrSplit(GenTreePutArgStk* putArgNode)
504504
// Return Value:
505505
// None.
506506
//
507-
// Notes:
508-
// Casts from float/double to a smaller int type are transformed as follows:
509-
// GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte)
510-
// GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte)
511-
// GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16)
512-
// GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16)
513-
//
514-
// Note that for the overflow conversions we still depend on helper calls and
515-
// don't expect to see them here.
516-
// i) GT_CAST(float/double, int type with overflow detection)
517-
//
518-
519-
GenTree* Lowering::LowerCast(GenTree* tree)
507+
void Lowering::LowerCast(GenTree* tree)
520508
{
521-
assert(tree->OperGet() == GT_CAST);
509+
assert(tree->OperIs(GT_CAST));
522510

523511
JITDUMP("LowerCast for: ");
524512
DISPNODE(tree);
@@ -530,17 +518,16 @@ GenTree* Lowering::LowerCast(GenTree* tree)
530518

531519
if (varTypeIsFloating(srcType))
532520
{
521+
// Overflow casts should have been converted to helper call in morph.
533522
noway_assert(!tree->gtOverflow());
534-
assert(!varTypeIsSmall(dstType)); // fgMorphCast creates intermediate casts when converting from float to small
535-
// int.
523+
// Small types should have had an intermediate int cast inserted in morph.
524+
assert(!varTypeIsSmall(dstType));
536525
}
537526

538527
assert(!varTypeIsSmall(srcType));
539528

540529
// Now determine if we have operands that should be contained.
541530
ContainCheckCast(tree->AsCast());
542-
543-
return nullptr;
544531
}
545532

546533
//------------------------------------------------------------------------

0 commit comments

Comments
 (0)