diff options
| author | Mohammad Shahid <Asghar-ahmad.Shahid@amd.com> | 2015-09-24 10:35:03 +0000 |
|---|---|---|
| committer | Mohammad Shahid <Asghar-ahmad.Shahid@amd.com> | 2015-09-24 10:35:03 +0000 |
| commit | 13f1dfdf2eada3edd62f2bda6d1387e41f1e2c81 (patch) | |
| tree | 4d0367b3a58579274413c8627eba0af7cffa4e7a /llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | |
| parent | 2720593ab4518012af619c90b45f60ccc4ae4f29 (diff) | |
| download | bcm5719-llvm-13f1dfdf2eada3edd62f2bda6d1387e41f1e2c81.tar.gz bcm5719-llvm-13f1dfdf2eada3edd62f2bda6d1387e41f1e2c81.zip | |
Codegen: Fix llvm.*absdiff semantic.
Fixes the overflow case of llvm.*absdiff intrinsic also updats the tests and LangRef.rst accordingly.
Differential Revision: http://reviews.llvm.org/D11678
llvm-svn: 248483
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index 35ccd13adcc..329a0179178 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -723,24 +723,30 @@ SDValue VectorLegalizer::Expand(SDValue Op) { SDValue VectorLegalizer::ExpandABSDIFF(SDValue Op) { SDLoc dl(Op); - SDValue Tmp1, Tmp2, Tmp3, Tmp4; + SDValue Op0 = Op.getOperand(0); + SDValue Op1 = Op.getOperand(1); EVT VT = Op.getValueType(); + + // For unsigned intrinsic, promote the type to handle unsigned overflow. + bool isUabsdiff = (Op->getOpcode() == ISD::UABSDIFF); + if (isUabsdiff) { + VT = VT.widenIntegerVectorElementType(*DAG.getContext()); + Op0 = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Op0); + Op1 = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Op1); + } + SDNodeFlags Flags; - Flags.setNoSignedWrap(Op->getOpcode() == ISD::SABSDIFF); - - Tmp2 = Op.getOperand(0); - Tmp3 = Op.getOperand(1); - Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Tmp2, Tmp3, &Flags); - Tmp2 = - DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT), Tmp1, &Flags); - Tmp4 = DAG.getNode( - ISD::SETCC, dl, - TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Tmp2, - DAG.getConstant(0, dl, VT), - DAG.getCondCode(Op->getOpcode() == ISD::SABSDIFF ? ISD::SETLT - : ISD::SETULT)); - Tmp1 = DAG.getNode(ISD::VSELECT, dl, VT, Tmp4, Tmp1, Tmp2); - return Tmp1; + Flags.setNoSignedWrap(!isUabsdiff); + SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, Op0, Op1, &Flags); + if (isUabsdiff) + return DAG.getNode(ISD::TRUNCATE, dl, Op.getValueType(), Sub); + + SDValue Cmp = + DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(DAG.getDataLayout(), + *DAG.getContext(), VT), + Sub, DAG.getConstant(0, dl, VT), DAG.getCondCode(ISD::SETGE)); + SDValue Neg = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT), Sub, &Flags); + return DAG.getNode(ISD::VSELECT, dl, VT, Cmp, Sub, Neg); } SDValue VectorLegalizer::ExpandSELECT(SDValue Op) { |

