@@ -14985,7 +14985,7 @@ GenTree* Compiler::gtFoldExpr(GenTree* tree)
1498514985}
1498614986
1498714987//------------------------------------------------------------------------
14988- // gtFoldExprUnary: see if an unary operation is foldable
14988+ // gtFoldExprUnary: see if a unary operation is foldable
1498914989//
1499014990// Arguments:
1499114991// tree - tree to examine
@@ -16964,7 +16964,7 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree)
1696416964}
1696516965
1696616966//------------------------------------------------------------------------
16967- // gtFoldExprUnaryConst: see if an unary const operation is foldable
16967+ // gtFoldExprUnaryConst: see if a unary const operation is foldable
1696816968//
1696916969// Arguments:
1697016970// tree - tree to examine
@@ -17013,7 +17013,7 @@ GenTree* Compiler::gtFoldExprUnaryConst(GenTreeUnOp* tree)
1701317013}
1701417014
1701517015//------------------------------------------------------------------------
17016- // gtFoldExprUnaryConst: see if an unary const operation for TYP_INT is foldable
17016+ // gtFoldExprUnaryConst: see if a unary const operation for TYP_INT is foldable
1701717017//
1701817018// Arguments:
1701917019// tree - tree to examine
@@ -17050,14 +17050,15 @@ GenTree* Compiler::gtFoldExprUnaryConstInt(GenTreeUnOp* tree, GenTreeIntCon* int
1705017050
1705117051 case GT_NEG:
1705217052 {
17053- iconVal = - iconVal;
17053+ iconVal = static_cast<int32_t>(0 - static_cast<uint32_t>( iconVal)) ;
1705417054 break;
1705517055 }
1705617056
1705717057 case GT_BSWAP:
1705817058 {
17059- iconVal = ((iconVal >> 24) & 0xFF) | ((iconVal >> 8) & 0xFF00) | ((iconVal << 8) & 0xFF0000) |
17060- ((iconVal << 24) & 0xFF000000);
17059+ uint32_t uconVal = static_cast<uint32_t>(iconVal);
17060+ iconVal = static_cast<int32_t>(((uconVal >> 24) & 0xFF) | ((uconVal >> 8) & 0xFF00) |
17061+ ((uconVal << 8) & 0xFF0000) | ((uconVal << 24) & 0xFF000000));
1706117062 break;
1706217063 }
1706317064
@@ -17172,7 +17173,7 @@ GenTree* Compiler::gtFoldExprUnaryConstInt(GenTreeUnOp* tree, GenTreeIntCon* int
1717217173}
1717317174
1717417175//------------------------------------------------------------------------
17175- // gtFoldExprUnaryConst: see if an unary const operation for TYP_LONG is foldable
17176+ // gtFoldExprUnaryConst: see if a unary const operation for TYP_LONG is foldable
1717617177//
1717717178// Arguments:
1717817179// tree - tree to examine
@@ -17209,16 +17210,17 @@ GenTree* Compiler::gtFoldExprUnaryConstLng(GenTreeUnOp* tree, GenTreeIntConCommo
1720917210
1721017211 case GT_NEG:
1721117212 {
17212- lconVal = - lconVal;
17213+ lconVal = static_cast<int64_t>(0 - static_cast<uint64_t>( lconVal)) ;
1721317214 break;
1721417215 }
1721517216
1721617217 case GT_BSWAP:
1721717218 {
17218- lconVal = ((lconVal >> 56) & 0xFF) | ((lconVal >> 40) & 0xFF00) | ((lconVal >> 24) & 0xFF0000) |
17219- ((lconVal >> 8) & 0xFF000000) | ((lconVal << 8) & 0xFF00000000) |
17220- ((lconVal << 24) & 0xFF0000000000) | ((lconVal << 40) & 0xFF000000000000) |
17221- ((lconVal << 56) & 0xFF00000000000000);
17219+ uint64_t uconVal = static_cast<uint64_t>(lconVal);
17220+ lconVal = static_cast<int64_t>(
17221+ ((uconVal >> 56) & 0xFF) | ((uconVal >> 40) & 0xFF00) | ((uconVal >> 24) & 0xFF0000) |
17222+ ((uconVal >> 8) & 0xFF000000) | ((uconVal << 8) & 0xFF00000000) | ((uconVal << 24) & 0xFF0000000000) |
17223+ ((uconVal << 40) & 0xFF000000000000) | ((uconVal << 56) & 0xFF00000000000000));
1722217224 break;
1722317225 }
1722417226
@@ -17326,7 +17328,7 @@ GenTree* Compiler::gtFoldExprUnaryConstLng(GenTreeUnOp* tree, GenTreeIntConCommo
1732617328}
1732717329
1732817330//------------------------------------------------------------------------
17329- // gtFoldExprUnaryConstDbl: see if an unary const operation for TYP_DOUBLE or TYP_FLOAT is foldable
17331+ // gtFoldExprUnaryConstDbl: see if a unary const operation for TYP_DOUBLE or TYP_FLOAT is foldable
1733017332//
1733117333// Arguments:
1733217334// tree - tree to examine
@@ -17744,7 +17746,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1774417746 return gtFoldExprForOverflow(tree);
1774517747 }
1774617748
17747- iconVal1 += iconVal2;
17749+ iconVal1 = static_cast<int32_t>(static_cast<uint32_t>(iconVal1) + static_cast<uint32_t>( iconVal2)) ;
1774817750
1774917751 FieldSeq* fieldSeq = GetFieldSeqStore()->Append(intCon1->gtFieldSeq, intCon2->gtFieldSeq);
1775017752 return gtBashTreeToConstInt(tree, iconVal1, fieldSeq);
@@ -17757,7 +17759,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1775717759 return gtFoldExprForOverflow(tree);
1775817760 }
1775917761
17760- iconVal1 -= iconVal2;
17762+ iconVal1 = static_cast<int32_t>(static_cast<uint32_t>(iconVal1) - static_cast<uint32_t>( iconVal2)) ;
1776117763 break;
1776217764 }
1776317765
@@ -17768,7 +17770,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1776817770 return gtFoldExprForOverflow(tree);
1776917771 }
1777017772
17771- iconVal1 *= iconVal2;
17773+ iconVal1 = static_cast<int32_t>(static_cast<uint32_t>(iconVal1) * static_cast<uint32_t>( iconVal2)) ;
1777217774 break;
1777317775 }
1777417776
@@ -17810,17 +17812,17 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1781017812
1781117813 case GT_ROL:
1781217814 {
17815+ uint32_t uconVal1 = static_cast<uint32_t>(iconVal1);
1781317816 iconVal2 &= 0x1F;
17814- iconVal1 = (iconVal1 << iconVal2) |
17815- static_cast<int32_t>(static_cast<uint32_t>(iconVal1) >> ((32 - iconVal2) & 0x1F));
17817+ iconVal1 = static_cast<int32_t>((uconVal1 << iconVal2) | (uconVal1 >> ((32 - iconVal2) & 0x1F)));
1781617818 break;
1781717819 }
1781817820
1781917821 case GT_ROR:
1782017822 {
17823+ uint32_t uconVal1 = static_cast<uint32_t>(iconVal1);
1782117824 iconVal2 &= 0x1F;
17822- iconVal1 = (iconVal1 << ((32 - iconVal2) & 0x1F)) |
17823- static_cast<int32_t>(static_cast<uint32_t>(iconVal1) >> iconVal2);
17825+ iconVal1 = static_cast<int32_t>((uconVal1 << ((32 - iconVal2) & 0x1F)) | (uconVal1 >> iconVal2));
1782417826 break;
1782517827 }
1782617828
@@ -17872,7 +17874,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1787217874}
1787317875
1787417876//------------------------------------------------------------------------
17875- // gtFoldExprBinaryConstInt : see if a binary const operation for TYP_LONG is foldable
17877+ // gtFoldExprBinaryConstLng : see if a binary const operation for TYP_LONG is foldable
1787617878//
1787717879// Arguments:
1787817880// tree - tree to examine
@@ -17993,7 +17995,7 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1799317995 return gtFoldExprForOverflow(tree);
1799417996 }
1799517997
17996- lconVal1 += lconVal2;
17998+ lconVal1 = static_cast<int64_t>(static_cast<uint64_t>(lconVal1) + static_cast<uint64_t>( lconVal2)) ;
1799717999
1799818000#if defined(TARGET_64BIT)
1799918001 FieldSeq* fieldSeq = GetFieldSeqStore()->Append(intConCommon1->AsIntCon()->gtFieldSeq,
@@ -18011,7 +18013,7 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1801118013 return gtFoldExprForOverflow(tree);
1801218014 }
1801318015
18014- lconVal1 -= lconVal2;
18016+ lconVal1 = static_cast<int64_t>(static_cast<uint64_t>(lconVal1) - static_cast<uint64_t>( lconVal2)) ;
1801518017 break;
1801618018 }
1801718019
@@ -18022,7 +18024,7 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1802218024 return gtFoldExprForOverflow(tree);
1802318025 }
1802418026
18025- lconVal1 *= lconVal2;
18027+ lconVal1 = static_cast<int64_t>(static_cast<uint64_t>(lconVal1) * static_cast<uint64_t>( lconVal2)) ;
1802618028 break;
1802718029 }
1802818030
@@ -18064,17 +18066,17 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1806418066
1806518067 case GT_ROL:
1806618068 {
18069+ uint64_t uconVal1 = static_cast<uint64_t>(lconVal1);
1806718070 lconVal2 &= 0x3F;
18068- lconVal1 = (lconVal1 << lconVal2) |
18069- static_cast<int64_t>(static_cast<uint64_t>(lconVal1) >> ((64 - lconVal2) & 0x3F));
18071+ lconVal1 = static_cast<int64_t>((uconVal1 << lconVal2) | (uconVal1 >> ((64 - lconVal2) & 0x3F)));
1807018072 break;
1807118073 }
1807218074
1807318075 case GT_ROR:
1807418076 {
18077+ uint64_t uconVal1 = static_cast<uint64_t>(lconVal1);
1807518078 lconVal2 &= 0x3F;
18076- lconVal1 = (lconVal1 << ((64 - lconVal2) & 0x3F)) |
18077- static_cast<int64_t>(static_cast<uint64_t>(lconVal1) >> lconVal2);
18079+ lconVal1 = static_cast<int64_t>((uconVal1 << ((64 - lconVal2) & 0x3F)) | (uconVal1 >> lconVal2));
1807818080 break;
1807918081 }
1808018082
@@ -18126,12 +18128,12 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1812618128}
1812718129
1812818130//------------------------------------------------------------------------
18129- // gtFoldExprBinaryConstInt : see if a binary const operation for TYP_INT is foldable
18131+ // gtFoldExprBinaryConstDbl : see if a binary const operation for TYP_DOUBLE or TYP_FLOAT is foldable
1813018132//
1813118133// Arguments:
1813218134// tree - tree to examine
18133- // intCon1 - the first integer constant operand for tree
18134- // intCon2 - the second integer constant operand for tree
18135+ // dblCon1 - the first floating-point constant operand for tree
18136+ // dblCon2 - the second floating-point constant operand for tree
1813518137//
1813618138// Returns:
1813718139// The original tree if no folding happened.
@@ -18234,6 +18236,12 @@ GenTree* Compiler::gtFoldExprBinaryConstDbl(GenTreeOp* tree, GenTreeDblCon* dblC
1823418236
1823518237 case GT_DIV:
1823618238 {
18239+ if (dconVal2 == 0)
18240+ {
18241+ // We do not fold division by zero, even for floating point.
18242+ // This is because the result will be platform-dependent for an expression like 0d / 0d.
18243+ return tree;
18244+ }
1823718245 dconVal1 /= dconVal2;
1823818246 break;
1823918247 }
@@ -18325,7 +18333,6 @@ GenTree* Compiler::gtBashTreeToConstLng(GenTree* tree, int64_t lconVal, FieldSeq
1832518333// Arguments:
1832618334// tree - the tree to bash
1832718335// dconVal - the value of the constant
18328- // fieldSeq - the field sequence, if any
1832918336//
1833018337// Returns:
1833118338// tree, bashed to GT_CNS_DBL node
@@ -33315,7 +33322,7 @@ bool GenTree::IsVectorPerElementMask(var_types simdBaseType, unsigned simdSize)
3331533322
3331633323 case GT_NOT:
3331733324 {
33318- // We are an unary bitwise operation where the input is a per-element mask
33325+ // We are a unary bitwise operation where the input is a per-element mask
3331933326 return intrinsic->Op(1)->IsVectorPerElementMask(simdBaseType, simdSize);
3332033327 }
3332133328
0 commit comments