Skip to content

Commit a44b7c2

Browse files
Make System.Math/MathF.Truncate an intrinsic (#65014)
1 parent a01be04 commit a44b7c2

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
@@ -3862,6 +3862,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
38623862
case NI_System_Math_Sqrt:
38633863
case NI_System_Math_Tan:
38643864
case NI_System_Math_Tanh:
3865+
case NI_System_Math_Truncate:
38653866
{
38663867
// Giving intrinsics a large fixed execution cost is because we'd like to CSE
38673868
// them, even if they are implemented by calls. This is different from modeling
@@ -10891,6 +10892,9 @@ void Compiler::gtDispTree(GenTree* tree,
1089110892
case NI_System_Math_Tanh:
1089210893
printf(" tanh");
1089310894
break;
10895+
case NI_System_Math_Truncate:
10896+
printf(" truncate");
10897+
break;
1089410898
case NI_System_Object_GetType:
1089510899
printf(" objGetType");
1089610900
break;

src/coreclr/jit/importer.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -4447,6 +4447,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
44474447
case NI_System_Math_Sqrt:
44484448
case NI_System_Math_Tan:
44494449
case NI_System_Math_Tanh:
4450+
case NI_System_Math_Truncate:
44504451
{
44514452
retNode = impMathIntrinsic(method, sig, callType, ni, tailCall);
44524453
break;
@@ -5093,6 +5094,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
50935094
{
50945095
result = NI_System_Math_Tanh;
50955096
}
5097+
else if (strcmp(methodName, "Truncate") == 0)
5098+
{
5099+
result = NI_System_Math_Truncate;
5100+
}
50965101
}
50975102
else if (strcmp(className, "GC") == 0)
50985103
{
@@ -20448,14 +20453,15 @@ bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName)
2044820453
switch (intrinsicName)
2044920454
{
2045020455
// AMD64/x86 has SSE2 instructions to directly compute sqrt/abs and SSE4.1
20451-
// instructions to directly compute round/ceiling/floor.
20456+
// instructions to directly compute round/ceiling/floor/truncate.
2045220457

2045320458
case NI_System_Math_Abs:
2045420459
case NI_System_Math_Sqrt:
2045520460
return true;
2045620461

2045720462
case NI_System_Math_Ceiling:
2045820463
case NI_System_Math_Floor:
20464+
case NI_System_Math_Truncate:
2045920465
case NI_System_Math_Round:
2046020466
return compOpportunisticallyDependsOn(InstructionSet_SSE41);
2046120467

@@ -20471,6 +20477,7 @@ bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName)
2047120477
case NI_System_Math_Abs:
2047220478
case NI_System_Math_Ceiling:
2047320479
case NI_System_Math_Floor:
20480+
case NI_System_Math_Truncate:
2047420481
case NI_System_Math_Round:
2047520482
case NI_System_Math_Sqrt:
2047620483
return true;
@@ -20544,6 +20551,7 @@ bool Compiler::IsMathIntrinsic(NamedIntrinsic intrinsicName)
2054420551
case NI_System_Math_Sqrt:
2054520552
case NI_System_Math_Tan:
2054620553
case NI_System_Math_Tanh:
20554+
case NI_System_Math_Truncate:
2054720555
{
2054820556
assert((intrinsicName > NI_SYSTEM_MATH_START) && (intrinsicName < NI_SYSTEM_MATH_END));
2054920557
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
@@ -1826,6 +1826,7 @@ int LinearScan::BuildIntrinsic(GenTree* tree)
18261826

18271827
case NI_System_Math_Ceiling:
18281828
case NI_System_Math_Floor:
1829+
case NI_System_Math_Truncate:
18291830
case NI_System_Math_Round:
18301831
case NI_System_Math_Sqrt:
18311832
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)