Test case is in r144990. I forgot to add the file in the first commit.<br><br>~Craig<br><br><div class="gmail_quote">On Sat, Nov 19, 2011 at 5:47 AM, Duncan Sands <span dir="ltr"><<a href="mailto:baldrick@free.fr">baldrick@free.fr</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi Craig,<br>
<br>
> Synthesize SSSE3/AVX 128-bit horizontal integer add/sub instructions from add/sub of appropriate shuffle vectors.<br>
<br>
testcase?<br>
<br>
Ciao, Duncan.<br>
<br>
><br>
> Modified:<br>
>      llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
>      llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
>      llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td<br>
>      llvm/trunk/lib/Target/X86/X86InstrSSE.td<br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=144989&r1=144988&r2=144989&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=144989&r1=144988&r2=144989&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Nov 19 03:02:40 2011<br>
> @@ -14670,7 +14670,24 @@<br>
>                        DAG.getConstant(0, OtherVal.getValueType()), NewCmp);<br>
>   }<br>
><br>
> -static SDValue PerformSubCombine(SDNode *N, SelectionDAG&DAG) {<br>
> +/// PerformADDCombine - Do target-specific dag combines on integer adds.<br>
> +static SDValue PerformAddCombine(SDNode *N, SelectionDAG&DAG,<br>
> +                                 const X86Subtarget *Subtarget) {<br>
> +  EVT VT = N->getValueType(0);<br>
> +  SDValue Op0 = N->getOperand(0);<br>
> +  SDValue Op1 = N->getOperand(1);<br>
> +<br>
> +  // Try to synthesize horizontal adds from adds of shuffles.<br>
> +  if ((Subtarget->hasSSSE3() || Subtarget->hasAVX())&&<br>
> +      (VT == MVT::v8i16 || VT == MVT::v4i32)&&<br>
> +      isHorizontalBinOp(Op0, Op1, true))<br>
> +    return DAG.getNode(X86ISD::HADD, N->getDebugLoc(), VT, Op0, Op1);<br>
> +<br>
> +  return OptimizeConditionalInDecrement(N, DAG);<br>
> +}<br>
> +<br>
> +static SDValue PerformSubCombine(SDNode *N, SelectionDAG&DAG,<br>
> +                                 const X86Subtarget *Subtarget) {<br>
>     SDValue Op0 = N->getOperand(0);<br>
>     SDValue Op1 = N->getOperand(1);<br>
><br>
> @@ -14692,6 +14709,13 @@<br>
>       }<br>
>     }<br>
><br>
> +  // Try to synthesize horizontal adds from adds of shuffles.<br>
> +  EVT VT = N->getValueType(0);<br>
> +  if ((Subtarget->hasSSSE3() || Subtarget->hasAVX())&&<br>
> +      (VT == MVT::v8i16 || VT == MVT::v4i32)&&<br>
> +      isHorizontalBinOp(Op0, Op1, false))<br>
> +    return DAG.getNode(X86ISD::HSUB, N->getDebugLoc(), VT, Op0, Op1);<br>
> +<br>
>     return OptimizeConditionalInDecrement(N, DAG);<br>
>   }<br>
><br>
> @@ -14705,8 +14729,8 @@<br>
>     case ISD::VSELECT:<br>
>     case ISD::SELECT:         return PerformSELECTCombine(N, DAG, Subtarget);<br>
>     case X86ISD::CMOV:        return PerformCMOVCombine(N, DAG, DCI);<br>
> -  case ISD::ADD:            return OptimizeConditionalInDecrement(N, DAG);<br>
> -  case ISD::SUB:            return PerformSubCombine(N, DAG);<br>
> +  case ISD::ADD:            return PerformAddCombine(N, DAG, Subtarget);<br>
> +  case ISD::SUB:            return PerformSubCombine(N, DAG, Subtarget);<br>
>     case X86ISD::ADC:         return PerformADCCombine(N, DAG, DCI);<br>
>     case ISD::MUL:            return PerformMulCombine(N, DAG, DCI);<br>
>     case ISD::SHL:<br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=144989&r1=144988&r2=144989&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=144989&r1=144988&r2=144989&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Sat Nov 19 03:02:40 2011<br>
> @@ -178,6 +178,12 @@<br>
>         /// BLEND family of opcodes<br>
>         BLENDV,<br>
><br>
> +      /// HADD - Integer horizontal add.<br>
> +      HADD,<br>
> +<br>
> +      /// HSUB - Integer horizontal sub.<br>
> +      HSUB,<br>
> +<br>
>         /// FHADD - Floating point horizontal add.<br>
>         FHADD,<br>
><br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=144989&r1=144988&r2=144989&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=144989&r1=144988&r2=144989&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td Sat Nov 19 03:02:40 2011<br>
> @@ -41,6 +41,8 @@<br>
>   def X86fgetsign: SDNode<"X86ISD::FGETSIGNx86",SDTFPToIntOp>;<br>
>   def X86fhadd   : SDNode<"X86ISD::FHADD",     SDTFPBinOp>;<br>
>   def X86fhsub   : SDNode<"X86ISD::FHSUB",     SDTFPBinOp>;<br>
> +def X86hadd    : SDNode<"X86ISD::HADD",      SDTIntBinOp>;<br>
> +def X86hsub    : SDNode<"X86ISD::HSUB",      SDTIntBinOp>;<br>
>   def X86comi    : SDNode<"X86ISD::COMI",      SDTX86CmpTest>;<br>
>   def X86ucomi   : SDNode<"X86ISD::UCOMI",     SDTX86CmpTest>;<br>
>   def X86cmpss   : SDNode<"X86ISD::FSETCCss",    SDTX86Cmpss>;<br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=144989&r1=144988&r2=144989&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=144989&r1=144988&r2=144989&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Sat Nov 19 03:02:40 2011<br>
> @@ -5369,6 +5369,15 @@<br>
>               (PSIGNWrr128 VR128:$src1, VR128:$src2)>;<br>
>     def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),<br>
>               (PSIGNDrr128 VR128:$src1, VR128:$src2)>;<br>
> +<br>
> +  def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),<br>
> +            (PHADDWrr128 VR128:$src1, VR128:$src2)>;<br>
> +  def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),<br>
> +            (PHADDDrr128 VR128:$src1, VR128:$src2)>;<br>
> +  def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),<br>
> +            (PHSUBWrr128 VR128:$src1, VR128:$src2)>;<br>
> +  def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),<br>
> +            (PHSUBDrr128 VR128:$src1, VR128:$src2)>;<br>
>   }<br>
><br>
>   let Predicates = [HasAVX] in {<br>
> @@ -5383,6 +5392,15 @@<br>
>               (VPSIGNWrr128 VR128:$src1, VR128:$src2)>;<br>
>     def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),<br>
>               (VPSIGNDrr128 VR128:$src1, VR128:$src2)>;<br>
> +<br>
> +  def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),<br>
> +            (VPHADDWrr128 VR128:$src1, VR128:$src2)>;<br>
> +  def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),<br>
> +            (VPHADDDrr128 VR128:$src1, VR128:$src2)>;<br>
> +  def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),<br>
> +            (VPHSUBWrr128 VR128:$src1, VR128:$src2)>;<br>
> +  def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),<br>
> +            (VPHSUBDrr128 VR128:$src1, VR128:$src2)>;<br>
>   }<br>
><br>
>   let Predicates = [HasAVX2] in {<br>
> @@ -5392,6 +5410,15 @@<br>
>               (VPSIGNWrr256 VR256:$src1, VR256:$src2)>;<br>
>     def : Pat<(v8i32 (X86psign VR256:$src1, VR256:$src2)),<br>
>               (VPSIGNDrr256 VR256:$src1, VR256:$src2)>;<br>
> +<br>
> +  def : Pat<(v16i16 (X86hadd VR256:$src1, VR256:$src2)),<br>
> +            (VPHADDWrr256 VR256:$src1, VR256:$src2)>;<br>
> +  def : Pat<(v8i32 (X86hadd VR256:$src1, VR256:$src2)),<br>
> +            (VPHADDDrr256 VR256:$src1, VR256:$src2)>;<br>
> +  def : Pat<(v16i16 (X86hsub VR256:$src1, VR256:$src2)),<br>
> +            (VPHSUBWrr256 VR256:$src1, VR256:$src2)>;<br>
> +  def : Pat<(v8i32 (X86hsub VR256:$src1, VR256:$src2)),<br>
> +            (VPHSUBDrr256 VR256:$src1, VR256:$src2)>;<br>
>   }<br>
><br>
>   //===---------------------------------------------------------------------===//<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><br>-- <br>~Craig<br>