@@ -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
@@ -17160,6 +17161,7 @@ GenTree* Compiler::gtFoldExprUnaryConstInt(GenTreeUnOp* tree, GenTreeIntCon* int
1716017161 return tree;
1716117162 }
1716217163 }
17164+ break;
1716317165 }
1716417166
1716517167 default:
@@ -17172,7 +17174,7 @@ GenTree* Compiler::gtFoldExprUnaryConstInt(GenTreeUnOp* tree, GenTreeIntCon* int
1717217174}
1717317175
1717417176//------------------------------------------------------------------------
17175- // gtFoldExprUnaryConst: see if an unary const operation for TYP_LONG is foldable
17177+ // gtFoldExprUnaryConst: see if a unary const operation for TYP_LONG is foldable
1717617178//
1717717179// Arguments:
1717817180// tree - tree to examine
@@ -17209,16 +17211,17 @@ GenTree* Compiler::gtFoldExprUnaryConstLng(GenTreeUnOp* tree, GenTreeIntConCommo
1720917211
1721017212 case GT_NEG:
1721117213 {
17212- lconVal = - lconVal;
17214+ lconVal = static_cast<int64_t>(0 - static_cast<uint64_t>( lconVal)) ;
1721317215 break;
1721417216 }
1721517217
1721617218 case GT_BSWAP:
1721717219 {
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);
17220+ uint64_t uconVal = static_cast<uint64_t>(lconVal);
17221+ lconVal = static_cast<int64_t>(
17222+ ((uconVal >> 56) & 0xFF) | ((uconVal >> 40) & 0xFF00) | ((uconVal >> 24) & 0xFF0000) |
17223+ ((uconVal >> 8) & 0xFF000000) | ((uconVal << 8) & 0xFF00000000) | ((uconVal << 24) & 0xFF0000000000) |
17224+ ((uconVal << 40) & 0xFF000000000000) | ((uconVal << 56) & 0xFF00000000000000));
1722217225 break;
1722317226 }
1722417227
@@ -17326,7 +17329,7 @@ GenTree* Compiler::gtFoldExprUnaryConstLng(GenTreeUnOp* tree, GenTreeIntConCommo
1732617329}
1732717330
1732817331//------------------------------------------------------------------------
17329- // gtFoldExprUnaryConstDbl: see if an unary const operation for TYP_DOUBLE or TYP_FLOAT is foldable
17332+ // gtFoldExprUnaryConstDbl: see if a unary const operation for TYP_DOUBLE or TYP_FLOAT is foldable
1733017333//
1733117334// Arguments:
1733217335// tree - tree to examine
@@ -17744,7 +17747,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1774417747 return gtFoldExprForOverflow(tree);
1774517748 }
1774617749
17747- iconVal1 += iconVal2;
17750+ iconVal1 = static_cast<int32_t>(static_cast<uint32_t>(iconVal1) + static_cast<uint32_t>( iconVal2)) ;
1774817751
1774917752 FieldSeq* fieldSeq = GetFieldSeqStore()->Append(intCon1->gtFieldSeq, intCon2->gtFieldSeq);
1775017753 return gtBashTreeToConstInt(tree, iconVal1, fieldSeq);
@@ -17757,7 +17760,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1775717760 return gtFoldExprForOverflow(tree);
1775817761 }
1775917762
17760- iconVal1 -= iconVal2;
17763+ iconVal1 = static_cast<int32_t>(static_cast<uint32_t>(iconVal1) - static_cast<uint32_t>( iconVal2)) ;
1776117764 break;
1776217765 }
1776317766
@@ -17768,7 +17771,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1776817771 return gtFoldExprForOverflow(tree);
1776917772 }
1777017773
17771- iconVal1 *= iconVal2;
17774+ iconVal1 = static_cast<int32_t>(static_cast<uint32_t>(iconVal1) * static_cast<uint32_t>( iconVal2)) ;
1777217775 break;
1777317776 }
1777417777
@@ -17792,7 +17795,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1779217795
1779317796 case GT_LSH:
1779417797 {
17795- iconVal1 <<= (iconVal2 & 0x1F);
17798+ iconVal1 = static_cast<int32_t>(static_cast<uint32_t>(iconVal1) << (iconVal2 & 0x1F) );
1779617799 break;
1779717800 }
1779817801
@@ -17810,17 +17813,17 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1781017813
1781117814 case GT_ROL:
1781217815 {
17816+ uint32_t uconVal1 = static_cast<uint32_t>(iconVal1);
1781317817 iconVal2 &= 0x1F;
17814- iconVal1 = (iconVal1 << iconVal2) |
17815- static_cast<int32_t>(static_cast<uint32_t>(iconVal1) >> ((32 - iconVal2) & 0x1F));
17818+ iconVal1 = static_cast<int32_t>((uconVal1 << iconVal2) | (uconVal1 >> ((32 - iconVal2) & 0x1F)));
1781617819 break;
1781717820 }
1781817821
1781917822 case GT_ROR:
1782017823 {
17824+ uint32_t uconVal1 = static_cast<uint32_t>(iconVal1);
1782117825 iconVal2 &= 0x1F;
17822- iconVal1 = (iconVal1 << ((32 - iconVal2) & 0x1F)) |
17823- static_cast<int32_t>(static_cast<uint32_t>(iconVal1) >> iconVal2);
17826+ iconVal1 = static_cast<int32_t>((uconVal1 << ((32 - iconVal2) & 0x1F)) | (uconVal1 >> iconVal2));
1782417827 break;
1782517828 }
1782617829
@@ -17872,7 +17875,7 @@ GenTree* Compiler::gtFoldExprBinaryConstInt(GenTreeOp* tree, GenTreeIntCon* intC
1787217875}
1787317876
1787417877//------------------------------------------------------------------------
17875- // gtFoldExprBinaryConstInt : see if a binary const operation for TYP_LONG is foldable
17878+ // gtFoldExprBinaryConstLng : see if a binary const operation for TYP_LONG is foldable
1787617879//
1787717880// Arguments:
1787817881// tree - tree to examine
@@ -17993,7 +17996,7 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1799317996 return gtFoldExprForOverflow(tree);
1799417997 }
1799517998
17996- lconVal1 += lconVal2;
17999+ lconVal1 = static_cast<int64_t>(static_cast<uint64_t>(lconVal1) + static_cast<uint64_t>( lconVal2)) ;
1799718000
1799818001#if defined(TARGET_64BIT)
1799918002 FieldSeq* fieldSeq = GetFieldSeqStore()->Append(intConCommon1->AsIntCon()->gtFieldSeq,
@@ -18011,7 +18014,7 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1801118014 return gtFoldExprForOverflow(tree);
1801218015 }
1801318016
18014- lconVal1 -= lconVal2;
18017+ lconVal1 = static_cast<int64_t>(static_cast<uint64_t>(lconVal1) - static_cast<uint64_t>( lconVal2)) ;
1801518018 break;
1801618019 }
1801718020
@@ -18022,7 +18025,7 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1802218025 return gtFoldExprForOverflow(tree);
1802318026 }
1802418027
18025- lconVal1 *= lconVal2;
18028+ lconVal1 = static_cast<int64_t>(static_cast<uint64_t>(lconVal1) * static_cast<uint64_t>( lconVal2)) ;
1802618029 break;
1802718030 }
1802818031
@@ -18046,7 +18049,7 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1804618049
1804718050 case GT_LSH:
1804818051 {
18049- lconVal1 <<= (lconVal2 & 0x3F);
18052+ lconVal1 = static_cast<int64_t>(static_cast<uint64_t>(lconVal1) << (lconVal2 & 0x3F) );
1805018053 break;
1805118054 }
1805218055
@@ -18064,17 +18067,17 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1806418067
1806518068 case GT_ROL:
1806618069 {
18070+ uint64_t uconVal1 = static_cast<uint64_t>(lconVal1);
1806718071 lconVal2 &= 0x3F;
18068- lconVal1 = (lconVal1 << lconVal2) |
18069- static_cast<int64_t>(static_cast<uint64_t>(lconVal1) >> ((64 - lconVal2) & 0x3F));
18072+ lconVal1 = static_cast<int64_t>((uconVal1 << lconVal2) | (uconVal1 >> ((64 - lconVal2) & 0x3F)));
1807018073 break;
1807118074 }
1807218075
1807318076 case GT_ROR:
1807418077 {
18078+ uint64_t uconVal1 = static_cast<uint64_t>(lconVal1);
1807518079 lconVal2 &= 0x3F;
18076- lconVal1 = (lconVal1 << ((64 - lconVal2) & 0x3F)) |
18077- static_cast<int64_t>(static_cast<uint64_t>(lconVal1) >> lconVal2);
18080+ lconVal1 = static_cast<int64_t>((uconVal1 << ((64 - lconVal2) & 0x3F)) | (uconVal1 >> lconVal2));
1807818081 break;
1807918082 }
1808018083
@@ -18126,12 +18129,12 @@ GenTree* Compiler::gtFoldExprBinaryConstLng(GenTreeOp* tree,
1812618129}
1812718130
1812818131//------------------------------------------------------------------------
18129- // gtFoldExprBinaryConstInt : see if a binary const operation for TYP_INT is foldable
18132+ // gtFoldExprBinaryConstDbl : see if a binary const operation for TYP_DOUBLE or TYP_FLOAT is foldable
1813018133//
1813118134// Arguments:
1813218135// tree - tree to examine
18133- // intCon1 - the first integer constant operand for tree
18134- // intCon2 - the second integer constant operand for tree
18136+ // dblCon1 - the first floating-point constant operand for tree
18137+ // dblCon2 - the second floating-point constant operand for tree
1813518138//
1813618139// Returns:
1813718140// The original tree if no folding happened.
@@ -18234,6 +18237,12 @@ GenTree* Compiler::gtFoldExprBinaryConstDbl(GenTreeOp* tree, GenTreeDblCon* dblC
1823418237
1823518238 case GT_DIV:
1823618239 {
18240+ if (dconVal2 == 0)
18241+ {
18242+ // We do not fold division by zero, even for floating point.
18243+ // This is because the result will be platform-dependent for an expression like 0d / 0d.
18244+ return tree;
18245+ }
1823718246 dconVal1 /= dconVal2;
1823818247 break;
1823918248 }
@@ -18325,7 +18334,6 @@ GenTree* Compiler::gtBashTreeToConstLng(GenTree* tree, int64_t lconVal, FieldSeq
1832518334// Arguments:
1832618335// tree - the tree to bash
1832718336// dconVal - the value of the constant
18328- // fieldSeq - the field sequence, if any
1832918337//
1833018338// Returns:
1833118339// tree, bashed to GT_CNS_DBL node
@@ -33315,7 +33323,7 @@ bool GenTree::IsVectorPerElementMask(var_types simdBaseType, unsigned simdSize)
3331533323
3331633324 case GT_NOT:
3331733325 {
33318- // We are an unary bitwise operation where the input is a per-element mask
33326+ // We are a unary bitwise operation where the input is a per-element mask
3331933327 return intrinsic->Op(1)->IsVectorPerElementMask(simdBaseType, simdSize);
3332033328 }
3332133329
0 commit comments