diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1299,6 +1299,10 @@ setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i16, Legal); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i32, Legal); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i64, Legal); + + setOperationAction(ISD::ABDU, MVT::v16i8, Legal); + setOperationAction(ISD::ABDU, MVT::v8i16, Legal); + setOperationAction(ISD::ABDU, MVT::v4i32, Legal); } if (Subtarget.hasP10Vector()) { @@ -17437,24 +17441,6 @@ SDLoc dl(N); SDValue Op0 = N->getOperand(0); - // fold (truncate (abs (sub (zext a), (zext b)))) -> (vabsd a, b) - if (Subtarget.hasP9Altivec() && Op0.getOpcode() == ISD::ABS) { - EVT VT = N->getValueType(0); - if (VT != MVT::v4i32 && VT != MVT::v8i16 && VT != MVT::v16i8) - return SDValue(); - SDValue Sub = Op0.getOperand(0); - if (Sub.getOpcode() == ISD::SUB) { - SDValue SubOp0 = Sub.getOperand(0); - SDValue SubOp1 = Sub.getOperand(1); - if ((SubOp0.getOpcode() == ISD::ZERO_EXTEND) && - (SubOp1.getOpcode() == ISD::ZERO_EXTEND)) { - return DCI.DAG.getNode(PPCISD::VABSD, dl, VT, SubOp0.getOperand(0), - SubOp1.getOperand(0), - DCI.DAG.getTargetConstant(0, dl, MVT::i32)); - } - } - } - // Looking for a truncate of i128 to i64. if (Op0.getValueType() != MVT::i128 || N->getValueType(0) != MVT::i64) return SDValue(); @@ -17664,10 +17650,6 @@ return true; } -// Transform (abs (sub (zext a), (zext b))) to (vabsd a b 0) -// Transform (abs (sub (zext a), (zext_invec b))) to (vabsd a b 0) -// Transform (abs (sub (zext_invec a), (zext_invec b))) to (vabsd a b 0) -// Transform (abs (sub (zext_invec a), (zext b))) to (vabsd a b 0) // Transform (abs (sub a, b) to (vabsd a b 1)) if a & b of type v4i32 SDValue PPCTargetLowering::combineABS(SDNode *N, DAGCombinerInfo &DCI) const { assert((N->getOpcode() == ISD::ABS) && "Need ABS node here"); @@ -17680,20 +17662,6 @@ SelectionDAG &DAG = DCI.DAG; SDLoc dl(N); if (N->getOperand(0).getOpcode() == ISD::SUB) { - // Even for signed integers, if it's known to be positive (as signed - // integer) due to zero-extended inputs. - unsigned SubOpcd0 = N->getOperand(0)->getOperand(0).getOpcode(); - unsigned SubOpcd1 = N->getOperand(0)->getOperand(1).getOpcode(); - if ((SubOpcd0 == ISD::ZERO_EXTEND || - SubOpcd0 == ISD::ZERO_EXTEND_VECTOR_INREG) && - (SubOpcd1 == ISD::ZERO_EXTEND || - SubOpcd1 == ISD::ZERO_EXTEND_VECTOR_INREG)) { - return DAG.getNode(PPCISD::VABSD, dl, N->getOperand(0).getValueType(), - N->getOperand(0)->getOperand(0), - N->getOperand(0)->getOperand(1), - DAG.getTargetConstant(0, dl, MVT::i32)); - } - // For type v4i32, it can be optimized with xvnegsp + vabsduw if (N->getOperand(0).getValueType() == MVT::v4i32 && N->getOperand(0).hasOneUse()) { @@ -17708,10 +17676,11 @@ } // For type v4i32/v8ii16/v16i8, transform -// from (vselect (setcc a, b, setugt), (sub a, b), (sub b, a)) to (vabsd a, b) -// from (vselect (setcc a, b, setuge), (sub a, b), (sub b, a)) to (vabsd a, b) -// from (vselect (setcc a, b, setult), (sub b, a), (sub a, b)) to (vabsd a, b) -// from (vselect (setcc a, b, setule), (sub b, a), (sub a, b)) to (vabsd a, b) +// from (vselect (setcc a, b, setugt), (sub a, b), (sub b, a)) to (abdu a, b) +// from (vselect (setcc a, b, setuge), (sub a, b), (sub b, a)) to (abdu a, b) +// from (vselect (setcc a, b, setult), (sub b, a), (sub a, b)) to (abdu a, b) +// from (vselect (setcc a, b, setule), (sub b, a), (sub a, b)) to (abdu a, b) +// TODO: Move this to DAGCombiner? SDValue PPCTargetLowering::combineVSelect(SDNode *N, DAGCombinerInfo &DCI) const { assert((N->getOpcode() == ISD::VSELECT) && "Need VSELECT node here"); @@ -17762,9 +17731,8 @@ TrueOpnd.getOperand(1) == CmpOpnd2 && FalseOpnd.getOperand(0) == CmpOpnd2 && FalseOpnd.getOperand(1) == CmpOpnd1) { - return DAG.getNode(PPCISD::VABSD, dl, N->getOperand(1).getValueType(), - CmpOpnd1, CmpOpnd2, - DAG.getTargetConstant(0, dl, MVT::i32)); + return DAG.getNode(ISD::ABDU, dl, N->getOperand(1).getValueType(), CmpOpnd1, + CmpOpnd2, DAG.getTargetConstant(0, dl, MVT::i32)); } return SDValue(); diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -4810,13 +4810,13 @@ let Predicates = [HasVSX, HasP9Altivec] in { // Put this P9Altivec related definition here since it's possible to be // selected to VSX instruction xvnegsp, avoid possible undef. -def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))), +def : Pat<(v4i32 (abdu v4i32:$A, v4i32:$B)), (v4i32 (VABSDUW $A, $B))>; -def : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))), +def : Pat<(v8i16 (abdu v8i16:$A, v8i16:$B)), (v8i16 (VABSDUH $A, $B))>; -def : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))), +def : Pat<(v16i8 (abdu v16i8:$A, v16i8:$B)), (v16i8 (VABSDUB $A, $B))>; // As PPCVABSD description, the last operand indicates whether do the