summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichelle McDaniel <adiaaida@gmail.com>2016-05-02 13:52:39 -0700
committerMichelle McDaniel <adiaaida@gmail.com>2016-05-03 13:47:15 -0700
commit230d693afc8b253df012fb4569e42ba731e6f5d2 (patch)
tree7f7340582cf2ca377e208d101d5dfab34a579dbe /src
parentcb42cbf1dca78a548deca358764500fb8a48e06b (diff)
downloadcoreclr-230d693afc8b253df012fb4569e42ba731e6f5d2.tar.gz
coreclr-230d693afc8b253df012fb4569e42ba731e6f5d2.tar.bz2
coreclr-230d693afc8b253df012fb4569e42ba731e6f5d2.zip
Set overflow flag for add/sub hi on x86 TYP_LONG
When we create the hi operation for add and sub on TYP_LONG, we don't carry the overflow flag to the hi operation. This change sets the overflow flag on hiResult in lower if it was set on loResult, and adds GT_ADD_HI and GT_SUB_HI to the operations that can have overflow. We also need to pass the unsigned flag to the high part in the instance that we are dealing with an add or subtract with overflow. Fixes #4596.
Diffstat (limited to 'src')
-rw-r--r--src/jit/codegenxarch.cpp5
-rw-r--r--src/jit/compiler.hpp10
-rw-r--r--src/jit/lower.cpp12
3 files changed, 27 insertions, 0 deletions
diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp
index b75dc9fa2d..edd485bc7f 100644
--- a/src/jit/codegenxarch.cpp
+++ b/src/jit/codegenxarch.cpp
@@ -1464,7 +1464,12 @@ void CodeGen::genCodeForBinary(GenTree* treeNode)
if (treeNode->gtOverflowEx())
{
+#if !defined(_TARGET_64BIT_)
+ assert(oper == GT_ADD || oper == GT_SUB ||
+ oper == GT_ADD_HI || oper == GT_SUB_HI);
+#else
assert(oper == GT_ADD || oper == GT_SUB);
+#endif
genCheckOverflow(treeNode);
}
genProduceReg(treeNode);
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp
index ec9cba33cb..d8cb64042c 100644
--- a/src/jit/compiler.hpp
+++ b/src/jit/compiler.hpp
@@ -1525,9 +1525,16 @@ bool GenTree::IsVarAddr() const
inline
bool GenTree::gtOverflow() const
{
+#if !defined(_TARGET_64BIT_) && !defined(LEGACY_BACKEND)
+ assert(gtOper == GT_MUL || gtOper == GT_CAST ||
+ gtOper == GT_ADD || gtOper == GT_SUB ||
+ gtOper == GT_ASG_ADD || gtOper == GT_ASG_SUB ||
+ gtOper == GT_ADD_HI || gtOper == GT_SUB_HI);
+#else
assert(gtOper == GT_MUL || gtOper == GT_CAST ||
gtOper == GT_ADD || gtOper == GT_SUB ||
gtOper == GT_ASG_ADD || gtOper == GT_ASG_SUB);
+#endif
if (gtFlags & GTF_OVERFLOW)
{
@@ -1546,6 +1553,9 @@ bool GenTree::gtOverflowEx() const
{
if ( gtOper == GT_MUL || gtOper == GT_CAST ||
gtOper == GT_ADD || gtOper == GT_SUB ||
+#if !defined(_TARGET_64BIT_) && !defined(LEGACY_BACKEND)
+ gtOper == GT_ADD_HI || gtOper == GT_SUB_HI ||
+#endif
gtOper == GT_ASG_ADD || gtOper == GT_ASG_SUB)
{
return gtOverflow();
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index b742f0197b..03c47e0b6e 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -469,6 +469,18 @@ void Lowering::DecomposeNode(GenTreePtr* pTree, Compiler::fgWalkData* data)
hiOp2->gtNext = hiResult;
hiResult->gtPrev = hiOp2;
+ if (oper == GT_ADD || oper == GT_SUB)
+ {
+ if (loResult->gtOverflow())
+ {
+ hiResult->gtFlags |= GTF_OVERFLOW;
+ loResult->gtFlags &= ~GTF_OVERFLOW;
+ }
+ if (loResult->gtFlags & GTF_UNSIGNED)
+ {
+ hiResult->gtFlags |= GTF_UNSIGNED;
+ }
+ }
// Below, we'll put the loResult and hiResult trees together, using the more
// general fgInsertTreeInListAfter() method.
}