diff options
author | Michelle McDaniel <adiaaida@gmail.com> | 2016-05-02 13:52:39 -0700 |
---|---|---|
committer | Michelle McDaniel <adiaaida@gmail.com> | 2016-05-03 13:47:15 -0700 |
commit | 230d693afc8b253df012fb4569e42ba731e6f5d2 (patch) | |
tree | 7f7340582cf2ca377e208d101d5dfab34a579dbe /src | |
parent | cb42cbf1dca78a548deca358764500fb8a48e06b (diff) | |
download | coreclr-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.cpp | 5 | ||||
-rw-r--r-- | src/jit/compiler.hpp | 10 | ||||
-rw-r--r-- | src/jit/lower.cpp | 12 |
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. } |