Skip to content

Commit 196eafe

Browse files
committed
Make System.Math/MathF.Truncate an intrinsic
1 parent fe24ab3 commit 196eafe

File tree

14 files changed

+51
-5
lines changed

14 files changed

+51
-5
lines changed

src/coreclr/jit/codegenarmarch.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ void CodeGen::genIntrinsic(GenTree* treeNode)
622622
assert(varTypeIsFloating(srcNode));
623623
assert(srcNode->TypeGet() == treeNode->TypeGet());
624624

625-
// Right now only Abs/Ceiling/Floor/Round/Sqrt are treated as math intrinsics.
625+
// Right now only Abs/Ceiling/Floor/Truncate/Round/Sqrt are treated as math intrinsics.
626626
//
627627
switch (treeNode->AsIntrinsic()->gtIntrinsicName)
628628
{
@@ -642,6 +642,11 @@ void CodeGen::genIntrinsic(GenTree* treeNode)
642642
GetEmitter()->emitInsBinary(INS_frintm, emitActualTypeSize(treeNode), treeNode, srcNode);
643643
break;
644644

645+
case NI_System_Math_Truncate:
646+
genConsumeOperands(treeNode->AsOp());
647+
GetEmitter()->emitInsBinary(INS_frintz, emitActualTypeSize(treeNode), treeNode, srcNode);
648+
break;
649+
645650
case NI_System_Math_Round:
646651
genConsumeOperands(treeNode->AsOp());
647652
GetEmitter()->emitInsBinary(INS_frintn, emitActualTypeSize(treeNode), treeNode, srcNode);

src/coreclr/jit/codegenxarch.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -7027,7 +7027,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode)
70277027
// ii) treeNode oper is a GT_INTRINSIC
70287028
// iii) treeNode type is a floating point type
70297029
// iv) treeNode is not used from memory
7030-
// v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor
7030+
// v) tree oper is NI_System_Math{F}_Round, _Ceiling, _Floor, or _Truncate
70317031
// vi) caller of this routine needs to call genProduceReg()
70327032
void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
70337033
{
@@ -7055,7 +7055,7 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
70557055

70567056
unsigned ival = 0;
70577057

7058-
// v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor
7058+
// v) tree oper is NI_System_Math{F}_Round, _Ceiling, _Floor, or _Truncate
70597059
switch (treeNode->AsIntrinsic()->gtIntrinsicName)
70607060
{
70617061
case NI_System_Math_Round:
@@ -7070,6 +7070,10 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
70707070
ival = 9;
70717071
break;
70727072

7073+
case NI_System_Math_Truncate:
7074+
ival = 11;
7075+
break;
7076+
70737077
default:
70747078
ins = INS_invalid;
70757079
assert(!"genSSE41RoundOp: unsupported intrinsic");
@@ -7197,6 +7201,7 @@ void CodeGen::genIntrinsic(GenTree* treeNode)
71977201

71987202
case NI_System_Math_Ceiling:
71997203
case NI_System_Math_Floor:
7204+
case NI_System_Math_Truncate:
72007205
case NI_System_Math_Round:
72017206
genSSE41RoundOp(treeNode->AsOp());
72027207
break;

src/coreclr/jit/gentree.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -3735,6 +3735,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
37353735
case NI_System_Math_Sqrt:
37363736
case NI_System_Math_Tan:
37373737
case NI_System_Math_Tanh:
3738+
case NI_System_Math_Truncate:
37383739
{
37393740
// Giving intrinsics a large fixed execution cost is because we'd like to CSE
37403741
// them, even if they are implemented by calls. This is different from modeling
@@ -10764,6 +10765,9 @@ void Compiler::gtDispTree(GenTree* tree,
1076410765
case NI_System_Math_Tanh:
1076510766
printf(" tanh");
1076610767
break;
10768+
case NI_System_Math_Truncate:
10769+
printf(" truncate");
10770+
break;
1076710771
case NI_System_Object_GetType:
1076810772
printf(" objGetType");
1076910773
break;

src/coreclr/jit/importer.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -4424,6 +4424,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
44244424
case NI_System_Math_Sqrt:
44254425
case NI_System_Math_Tan:
44264426
case NI_System_Math_Tanh:
4427+
case NI_System_Math_Truncate:
44274428
{
44284429
retNode = impMathIntrinsic(method, sig, callType, ni, tailCall);
44294430
break;
@@ -5070,6 +5071,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
50705071
{
50715072
result = NI_System_Math_Tanh;
50725073
}
5074+
else if (strcmp(methodName, "Truncate") == 0)
5075+
{
5076+
result = NI_System_Math_Truncate;
5077+
}
50735078
}
50745079
else if (strcmp(className, "GC") == 0)
50755080
{
@@ -20425,14 +20430,15 @@ bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName)
2042520430
switch (intrinsicName)
2042620431
{
2042720432
// AMD64/x86 has SSE2 instructions to directly compute sqrt/abs and SSE4.1
20428-
// instructions to directly compute round/ceiling/floor.
20433+
// instructions to directly compute round/ceiling/floor/truncate.
2042920434

2043020435
case NI_System_Math_Abs:
2043120436
case NI_System_Math_Sqrt:
2043220437
return true;
2043320438

2043420439
case NI_System_Math_Ceiling:
2043520440
case NI_System_Math_Floor:
20441+
case NI_System_Math_Truncate:
2043620442
case NI_System_Math_Round:
2043720443
return compOpportunisticallyDependsOn(InstructionSet_SSE41);
2043820444

@@ -20448,6 +20454,7 @@ bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName)
2044820454
case NI_System_Math_Abs:
2044920455
case NI_System_Math_Ceiling:
2045020456
case NI_System_Math_Floor:
20457+
case NI_System_Math_Truncate:
2045120458
case NI_System_Math_Round:
2045220459
case NI_System_Math_Sqrt:
2045320460
return true;
@@ -20521,6 +20528,7 @@ bool Compiler::IsMathIntrinsic(NamedIntrinsic intrinsicName)
2052120528
case NI_System_Math_Sqrt:
2052220529
case NI_System_Math_Tan:
2052320530
case NI_System_Math_Tanh:
20531+
case NI_System_Math_Truncate:
2052420532
{
2052520533
assert((intrinsicName > NI_SYSTEM_MATH_START) && (intrinsicName < NI_SYSTEM_MATH_END));
2052620534
return true;

src/coreclr/jit/lowerxarch.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -5275,7 +5275,8 @@ void Lowering::ContainCheckIntrinsic(GenTreeOp* node)
52755275
NamedIntrinsic intrinsicName = node->AsIntrinsic()->gtIntrinsicName;
52765276

52775277
if ((intrinsicName == NI_System_Math_Ceiling) || (intrinsicName == NI_System_Math_Floor) ||
5278-
(intrinsicName == NI_System_Math_Round) || (intrinsicName == NI_System_Math_Sqrt))
5278+
(intrinsicName == NI_System_Math_Truncate) || (intrinsicName == NI_System_Math_Round) ||
5279+
(intrinsicName == NI_System_Math_Sqrt))
52795280
{
52805281
GenTree* op1 = node->gtGetOp1();
52815282

src/coreclr/jit/lsraarm64.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ int LinearScan::BuildNode(GenTree* tree)
329329
noway_assert((tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Abs) ||
330330
(tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Ceiling) ||
331331
(tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Floor) ||
332+
(tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Truncate) ||
332333
(tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Round) ||
333334
(tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Sqrt));
334335

src/coreclr/jit/lsraxarch.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1817,6 +1817,7 @@ int LinearScan::BuildIntrinsic(GenTree* tree)
18171817

18181818
case NI_System_Math_Ceiling:
18191819
case NI_System_Math_Floor:
1820+
case NI_System_Math_Truncate:
18201821
case NI_System_Math_Round:
18211822
case NI_System_Math_Sqrt:
18221823
break;

src/coreclr/jit/namedintrinsiclist.h

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum NamedIntrinsic : unsigned short
4343
NI_System_Math_Sqrt,
4444
NI_System_Math_Tan,
4545
NI_System_Math_Tanh,
46+
NI_System_Math_Truncate,
4647
NI_SYSTEM_MATH_END,
4748

4849
NI_System_Collections_Generic_Comparer_get_Default,

src/coreclr/jit/valuenum.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -5294,6 +5294,10 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN
52945294
res = tanh(arg0Val);
52955295
break;
52965296

5297+
case NI_System_Math_Truncate:
5298+
res = trunc(arg0Val);
5299+
break;
5300+
52975301
default:
52985302
// the above are the only math intrinsics at the time of this writing.
52995303
unreached();
@@ -5398,6 +5402,10 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN
53985402
res = tanhf(arg0Val);
53995403
break;
54005404

5405+
case NI_System_Math_Truncate:
5406+
res = truncf(arg0Val);
5407+
break;
5408+
54015409
default:
54025410
// the above are the only math intrinsics at the time of this writing.
54035411
unreached();
@@ -5552,6 +5560,9 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN
55525560
case NI_System_Math_Tanh:
55535561
vnf = VNF_Tanh;
55545562
break;
5563+
case NI_System_Math_Truncate:
5564+
vnf = VNF_Truncate;
5565+
break;
55555566
default:
55565567
unreached(); // the above are the only math intrinsics at the time of this writing.
55575568
}

src/coreclr/jit/valuenumfuncs.h

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ ValueNumFuncDef(Sinh, 1, false, false, false)
101101
ValueNumFuncDef(Sqrt, 1, false, false, false)
102102
ValueNumFuncDef(Tan, 1, false, false, false)
103103
ValueNumFuncDef(Tanh, 1, false, false, false)
104+
ValueNumFuncDef(Truncate, 1, false, false, false)
104105

105106
ValueNumFuncDef(ManagedThreadId, 0, false, false, false)
106107

src/coreclr/pal/inc/pal.h

+2
Original file line numberDiff line numberDiff line change
@@ -4222,6 +4222,7 @@ PALIMPORT double __cdecl sinh(double);
42224222
PALIMPORT double __cdecl sqrt(double);
42234223
PALIMPORT double __cdecl tan(double);
42244224
PALIMPORT double __cdecl tanh(double);
4225+
PALIMPORT double __cdecl trunc(double);
42254226

42264227
PALIMPORT int __cdecl _finitef(float);
42274228
PALIMPORT int __cdecl _isnanf(float);
@@ -4254,6 +4255,7 @@ PALIMPORT float __cdecl sinhf(float);
42544255
PALIMPORT float __cdecl sqrtf(float);
42554256
PALIMPORT float __cdecl tanf(float);
42564257
PALIMPORT float __cdecl tanhf(float);
4258+
PALIMPORT float __cdecl truncf(float);
42574259
#endif // !PAL_STDCPP_COMPAT
42584260

42594261
#ifndef PAL_STDCPP_COMPAT

src/coreclr/pal/src/include/pal/palinternal.h

+4
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ function_name() to call the system's implementation
221221
#define sqrt DUMMY_sqrt
222222
#define tan DUMMY_tan
223223
#define tanh DUMMY_tanh
224+
#define trunc DUMMY_trunc
224225
#define ceilf DUMMY_ceilf
225226
#define cosf DUMMY_cosf
226227
#define coshf DUMMY_coshf
@@ -233,6 +234,7 @@ function_name() to call the system's implementation
233234
#define sqrtf DUMMY_sqrtf
234235
#define tanf DUMMY_tanf
235236
#define tanhf DUMMY_tanhf
237+
#define truncf DUMMY_truncf
236238

237239
/* RAND_MAX needed to be renamed to avoid duplicate definition when including
238240
stdlib.h header files. PAL_RAND_MAX should have the same value as RAND_MAX
@@ -464,6 +466,7 @@ function_name() to call the system's implementation
464466
#undef sqrt
465467
#undef tan
466468
#undef tanh
469+
#undef trunc
467470
#undef acosf
468471
#undef acoshf
469472
#undef asinf
@@ -492,6 +495,7 @@ function_name() to call the system's implementation
492495
#undef sqrtf
493496
#undef tanf
494497
#undef tanhf
498+
#undef truncf
495499
#undef rand
496500
#undef srand
497501
#undef errno

src/libraries/System.Private.CoreLib/src/System/Math.cs

+1
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,7 @@ public static decimal Truncate(decimal d)
14521452
return decimal.Truncate(d);
14531453
}
14541454

1455+
[Intrinsic]
14551456
public static unsafe double Truncate(double d)
14561457
{
14571458
ModF(d, &d);

src/libraries/System.Private.CoreLib/src/System/MathF.cs

+1
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ public static int Sign(float x)
508508
return Math.Sign(x);
509509
}
510510

511+
[Intrinsic]
511512
public static unsafe float Truncate(float x)
512513
{
513514
ModF(x, &x);

0 commit comments

Comments
 (0)