Skip to content

Commit 0ac1e3f

Browse files
committed
Ensure integer min/max magnitude is handled
1 parent 6a5f1a7 commit 0ac1e3f

File tree

2 files changed

+59
-18
lines changed

2 files changed

+59
-18
lines changed

src/coreclr/jit/gentree.cpp

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24711,15 +24711,13 @@ GenTree* Compiler::gtNewSimdMinMaxNode(var_types type,
2471124711

2471224712
if (isMax)
2471324713
{
24714-
signMask = gtNewSimdIsPositiveNode(type, gtCloneExpr(op1Dup), simdBaseJitType, simdSize);
24715-
cmpMask = gtNewSimdCmpOpNode(GT_GT, type, gtCloneExpr(absOp1Dup), gtCloneExpr(absOp2Dup),
24716-
simdBaseJitType, simdSize);
24714+
signMask = gtNewSimdIsPositiveNode(type, op1Dup, simdBaseJitType, simdSize);
24715+
cmpMask = gtNewSimdCmpOpNode(GT_GT, type, absOp1Dup, absOp2Dup, simdBaseJitType, simdSize);
2471724716
}
2471824717
else
2471924718
{
24720-
signMask = gtNewSimdIsNegativeNode(type, gtCloneExpr(op1Dup), simdBaseJitType, simdSize);
24721-
cmpMask = gtNewSimdCmpOpNode(GT_LT, type, gtCloneExpr(absOp1Dup), gtCloneExpr(absOp2Dup),
24722-
simdBaseJitType, simdSize);
24719+
signMask = gtNewSimdIsNegativeNode(type, op1Dup, simdBaseJitType, simdSize);
24720+
cmpMask = gtNewSimdCmpOpNode(GT_LT, type, absOp1Dup, absOp2Dup, simdBaseJitType, simdSize);
2472324721
}
2472424722

2472524723
if (isNumber)
@@ -24737,15 +24735,13 @@ GenTree* Compiler::gtNewSimdMinMaxNode(var_types type,
2473724735

2473824736
if (isMax)
2473924737
{
24740-
signMask = gtNewSimdIsNegativeNode(type, gtCloneExpr(op2Dup), simdBaseJitType, simdSize);
24741-
cmpMask = gtNewSimdCmpOpNode(GT_LT, type, gtCloneExpr(op2Dup), gtCloneExpr(op1Dup), simdBaseJitType,
24742-
simdSize);
24738+
signMask = gtNewSimdIsNegativeNode(type, op2Dup, simdBaseJitType, simdSize);
24739+
cmpMask = gtNewSimdCmpOpNode(GT_LT, type, gtCloneExpr(op2Dup), op1Dup, simdBaseJitType, simdSize);
2474324740
}
2474424741
else
2474524742
{
24746-
signMask = gtNewSimdIsNegativeNode(type, gtCloneExpr(op1Dup), simdBaseJitType, simdSize);
24747-
cmpMask = gtNewSimdCmpOpNode(GT_LT, type, gtCloneExpr(op1Dup), gtCloneExpr(op2Dup), simdBaseJitType,
24748-
simdSize);
24743+
signMask = gtNewSimdIsNegativeNode(type, op1Dup, simdBaseJitType, simdSize);
24744+
cmpMask = gtNewSimdCmpOpNode(GT_LT, type, gtCloneExpr(op1Dup), op2Dup, simdBaseJitType, simdSize);
2474924745
}
2475024746

2475124747
if (isNumber)
@@ -24756,14 +24752,15 @@ GenTree* Compiler::gtNewSimdMinMaxNode(var_types type,
2475624752
{
2475724753
nanMask = gtNewSimdIsNaNNode(type, gtCloneExpr(op1Dup), simdBaseJitType, simdSize);
2475824754
}
24755+
24756+
op2Dup = gtCloneExpr(op2Dup);
2475924757
}
2476024758

2476124759
GenTree* mask = gtNewSimdBinOpNode(GT_AND, type, equalsMask, signMask, simdBaseJitType, simdSize);
2476224760
mask = gtNewSimdBinOpNode(GT_OR, type, mask, nanMask, simdBaseJitType, simdSize);
2476324761
mask = gtNewSimdBinOpNode(GT_OR, type, mask, cmpMask, simdBaseJitType, simdSize);
2476424762

24765-
retNode =
24766-
gtNewSimdCndSelNode(type, mask, gtCloneExpr(op1Dup), gtCloneExpr(op2Dup), simdBaseJitType, simdSize);
24763+
retNode = gtNewSimdCndSelNode(type, mask, gtCloneExpr(op1Dup), op2Dup, simdBaseJitType, simdSize);
2476724764
}
2476824765
assert(retNode != nullptr);
2476924766

@@ -24773,6 +24770,51 @@ GenTree* Compiler::gtNewSimdMinMaxNode(var_types type,
2477324770
}
2477424771
return retNode;
2477524772
}
24773+
24774+
assert(!isScalar);
24775+
24776+
if (isMagnitude)
24777+
{
24778+
GenTree* op1Dup = fgMakeMultiUse(&op1);
24779+
GenTree* op2Dup = fgMakeMultiUse(&op2);
24780+
24781+
GenTree* absOp1 = gtNewSimdAbsNode(type, op1, simdBaseJitType, simdSize);
24782+
GenTree* absOp2 = gtNewSimdAbsNode(type, op2, simdBaseJitType, simdSize);
24783+
24784+
GenTree* absOp1Dup = fgMakeMultiUse(&absOp1);
24785+
GenTree* absOp2Dup = fgMakeMultiUse(&absOp2);
24786+
24787+
GenTree* equalsMask = gtNewSimdCmpOpNode(GT_EQ, type, absOp1, absOp2, simdBaseJitType, simdSize);
24788+
;
24789+
GenTree* signMask1 = nullptr;
24790+
GenTree* signMask2 = nullptr;
24791+
GenTree* signMask3 = nullptr;
24792+
GenTree* cmpMask = nullptr;
24793+
24794+
if (isMax)
24795+
{
24796+
signMask1 = gtNewSimdIsNegativeNode(type, op2Dup, simdBaseJitType, simdSize);
24797+
signMask2 = gtNewSimdIsPositiveNode(type, absOp2Dup, simdBaseJitType, simdSize);
24798+
signMask3 = gtNewSimdIsNegativeNode(type, absOp1Dup, simdBaseJitType, simdSize);
24799+
cmpMask = gtNewSimdCmpOpNode(GT_GT, type, gtCloneExpr(absOp1Dup), gtCloneExpr(absOp2Dup), simdBaseJitType,
24800+
simdSize);
24801+
}
24802+
else
24803+
{
24804+
signMask1 = gtNewSimdIsNegativeNode(type, op1Dup, simdBaseJitType, simdSize);
24805+
signMask2 = gtNewSimdIsPositiveNode(type, absOp1Dup, simdBaseJitType, simdSize);
24806+
signMask3 = gtNewSimdIsNegativeNode(type, absOp2Dup, simdBaseJitType, simdSize);
24807+
cmpMask = gtNewSimdCmpOpNode(GT_LT, type, gtCloneExpr(absOp1Dup), gtCloneExpr(absOp2Dup), simdBaseJitType,
24808+
simdSize);
24809+
}
24810+
24811+
GenTree* mask1 = gtNewSimdBinOpNode(GT_AND, type, equalsMask, signMask1, simdBaseJitType, simdSize);
24812+
GenTree* mask2 = gtNewSimdBinOpNode(GT_AND, type, cmpMask, signMask2, simdBaseJitType, simdSize);
24813+
GenTree* mask3 = gtNewSimdBinOpNode(GT_OR, type, mask1, mask2, simdBaseJitType, simdSize);
24814+
mask3 = gtNewSimdBinOpNode(GT_OR, type, mask3, signMask3, simdBaseJitType, simdSize);
24815+
24816+
return gtNewSimdCndSelNode(type, mask3, gtCloneExpr(op1Dup), gtCloneExpr(op2Dup), simdBaseJitType, simdSize);
24817+
}
2477624818
return gtNewSimdMinMaxNativeNode(type, op1, op2, simdBaseJitType, simdSize, isMax);
2477724819
}
2477824820

src/coreclr/jit/importercalls.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4969,7 +4969,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
49694969
GenTreeIntrinsic(callType, op2, NI_System_Math_Abs, nullptr R2RARG(nullEntry));
49704970
}
49714971
ni = isMax ? NI_System_Math_MaxNumber : NI_System_Math_MinNumber;
4972-
GenTree* minMax =
4972+
GenTree* minMax =
49734973
new (this, GT_INTRINSIC) GenTreeIntrinsic(callType, op1, op2, ni, nullptr R2RARG(nullEntry));
49744974

49754975
if (!isNumber)
@@ -5018,9 +5018,8 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
50185018
if (varTypeIsUnsigned(preciseType))
50195019
ni = isMax ? NI_System_Math_MaxUnsigned : NI_System_Math_MinUnsigned;
50205020

5021-
GenTreeIntrinsic* minMax =
5022-
new (this, GT_INTRINSIC) GenTreeIntrinsic(TYP_I_IMPL, op1, op2, ni,
5023-
nullptr R2RARG(CORINFO_CONST_LOOKUP{IAT_VALUE}));
5021+
GenTreeIntrinsic* minMax = new (this, GT_INTRINSIC)
5022+
GenTreeIntrinsic(TYP_I_IMPL, op1, op2, ni, nullptr R2RARG(CORINFO_CONST_LOOKUP{IAT_VALUE}));
50245023

50255024
return minMax;
50265025
}

0 commit comments

Comments
 (0)