Skip to content

Commit 6464b53

Browse files
Eliminate intermediate casts to double on ARM64
Enables the same optimization that has been there for a while for AArch32 for AArch64 too.
1 parent 44f050a commit 6464b53

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

src/coreclr/jit/morph.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,17 +258,26 @@ GenTree* Compiler::fgMorphCast(GenTree* tree)
258258
}
259259
#endif //! TARGET_64BIT
260260

261+
#ifdef TARGET_ARMARCH
262+
// AArch, unlike x86/amd64, has instructions that can cast directly from
263+
// all integers (except for longs on AArch32 of course) to floats.
264+
// Because there is no IL instruction conv.r4.un, uint/ulong -> float
265+
// casts are always inported as CAST(float <- CAST(double <- uint/ulong)).
266+
// We can eliminate the redundant intermediate cast as an optimization.
267+
else if ((dstType == TYP_FLOAT) && (srcType == TYP_DOUBLE) && oper->OperIs(GT_CAST)
261268
#ifdef TARGET_ARM
262-
else if ((dstType == TYP_FLOAT) && (srcType == TYP_DOUBLE) && (oper->gtOper == GT_CAST) &&
263-
!varTypeIsLong(oper->AsCast()->CastOp()))
269+
&& !varTypeIsLong(oper->AsCast()->CastOp())
270+
#endif
271+
)
264272
{
265-
// optimization: conv.r4(conv.r8(?)) -> conv.r4(d)
266-
// except when the ultimate source is a long because there is no long-to-float helper, so it must be 2 step.
267-
// This happens semi-frequently because there is no IL 'conv.r4.un'
268273
oper->gtType = TYP_FLOAT;
269274
oper->CastToType() = TYP_FLOAT;
275+
270276
return fgMorphTree(oper);
271277
}
278+
#endif // TARGET_ARMARCH
279+
280+
#ifdef TARGET_ARM
272281
// converts long/ulong --> float/double casts into helper calls.
273282
else if (varTypeIsFloating(dstType) && varTypeIsLong(srcType))
274283
{

0 commit comments

Comments
 (0)