<div dir="ltr"><div>Unfortunately, I haven't checked carefully this example, so I can't pinpoint the wrong instructions.</div><div>However, you can use Software Development Emulator (SDE) for emulation program with AVX2 code, it will be helpful for you.<br>
</div><div>Link to emulator's page: <a href="https://software.intel.com/en-us/articles/intel-software-development-emulator">https://software.intel.com/en-us/articles/intel-software-development-emulator</a></div><div>To run it: path-to-kit/sde -hsw -- program.out</div>
<div><br></div><div>-- Robert</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-07-08 20:45 GMT+04:00 Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@gmail.com" target="_blank">benny.kra@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">On Tue, Jul 8, 2014 at 6:32 PM, Robert Khasanov <<a href="mailto:rob.khasanov@gmail.com">rob.khasanov@gmail.com</a>> wrote:<br>

> Hi, Benjamin<br>
><br>
> Could you look at bug <a href="http://llvm.org/bugs/show_bug.cgi?id=20118" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=20118</a>?<br>
> Since this commit bug is reproduced.<br>
<br>
</div>Sadly I don't have access to a machine that has AVX2 currently and I<br>
fail to see what's wrong by just looking at the assembly. If anyone<br>
could pinpoint the wrong instructions (there's probably something<br>
wrong with the shuffles as that's where the AVX2 code diverges from<br>
the SSE4.1 path), that would be really helpful.<br>
<br>
- Ben<br>
<div class="HOEnZb"><div class="h5"><br>
><br>
> Regards,<br>
> Robert<br>
><br>
><br>
> 2014-04-26 18:12 GMT+04:00 Benjamin Kramer <<a href="mailto:benny.kra@googlemail.com">benny.kra@googlemail.com</a>>:<br>
><br>
>> Author: d0k<br>
>> Date: Sat Apr 26 09:12:19 2014<br>
>> New Revision: 207318<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=207318&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=207318&view=rev</a><br>
>> Log:<br>
>> X86: Lower SMUL_LOHI of v4i32 to pmuldq when SSE4.1 is available.<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>
>>     llvm/trunk/test/CodeGen/X86/vector-idiv.ll<br>
>><br>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=207318&r1=207317&r2=207318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=207318&r1=207317&r2=207318&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Apr 26 09:12:19 2014<br>
>> @@ -1062,6 +1062,7 @@ void X86TargetLowering::resetOperationAc<br>
>><br>
>>      // FIXME: Do we need to handle scalar-to-vector here?<br>
>>      setOperationAction(ISD::MUL,                MVT::v4i32, Legal);<br>
>> +    setOperationAction(ISD::SMUL_LOHI,          MVT::v4i32, Custom);<br>
>><br>
>>      setOperationAction(ISD::VSELECT,            MVT::v2f64, Legal);<br>
>>      setOperationAction(ISD::VSELECT,            MVT::v2i64, Legal);<br>
>> @@ -1227,6 +1228,7 @@ void X86TargetLowering::resetOperationAc<br>
>>        // Don't lower v32i8 because there is no 128-bit byte mul<br>
>><br>
>>        setOperationAction(ISD::UMUL_LOHI,       MVT::v8i32, Custom);<br>
>> +      setOperationAction(ISD::SMUL_LOHI,       MVT::v8i32, Custom);<br>
>>        setOperationAction(ISD::MULHU,           MVT::v16i16, Legal);<br>
>>        setOperationAction(ISD::MULHS,           MVT::v16i16, Legal);<br>
>><br>
>> @@ -11729,6 +11731,11 @@ static SDValue LowerINTRINSIC_WO_CHAIN(S<br>
>>      return DAG.getNode(X86ISD::PMULUDQ, dl, Op.getValueType(),<br>
>>                         Op.getOperand(1), Op.getOperand(2));<br>
>><br>
>> +  case Intrinsic::x86_sse41_pmuldq:<br>
>> +  case Intrinsic::x86_avx2_pmul_dq:<br>
>> +    return DAG.getNode(X86ISD::PMULDQ, dl, Op.getValueType(),<br>
>> +                       Op.getOperand(1), Op.getOperand(2));<br>
>> +<br>
>>    case Intrinsic::x86_sse2_pmulhu_w:<br>
>>    case Intrinsic::x86_avx2_pmulhu_w:<br>
>>      return DAG.getNode(ISD::MULHU, dl, Op.getValueType(),<br>
>> @@ -13168,8 +13175,8 @@ static SDValue LowerMUL(SDValue Op, cons<br>
>>    return DAG.getNode(ISD::ADD, dl, VT, Res, AhiBlo);<br>
>>  }<br>
>><br>
>> -static SDValue LowerUMUL_LOHI(SDValue Op, const X86Subtarget *Subtarget,<br>
>> -                              SelectionDAG &DAG) {<br>
>> +static SDValue LowerMUL_LOHI(SDValue Op, const X86Subtarget *Subtarget,<br>
>> +                             SelectionDAG &DAG) {<br>
>>    SDValue Op0 = Op.getOperand(0), Op1 = Op.getOperand(1);<br>
>>    EVT VT = Op0.getValueType();<br>
>>    SDLoc dl(Op);<br>
>> @@ -13185,15 +13192,17 @@ static SDValue LowerUMUL_LOHI(SDValue Op<br>
>>    // Emit two multiplies, one for the lower 2 ints and one for the higher<br>
>> 2<br>
>>    // ints.<br>
>>    MVT MulVT = VT == MVT::v4i32 ? MVT::v2i64 : MVT::v4i64;<br>
>> +  unsigned Opcode =<br>
>> +      Op->getOpcode() == ISD::UMUL_LOHI ? X86ISD::PMULUDQ :<br>
>> X86ISD::PMULDQ;<br>
>>    SDValue Mul1 = DAG.getNode(ISD::BITCAST, dl, VT,<br>
>> -                             DAG.getNode(X86ISD::PMULUDQ, dl, MulVT, Op0,<br>
>> Op1));<br>
>> +                             DAG.getNode(Opcode, dl, MulVT, Op0, Op1));<br>
>>    SDValue Mul2 = DAG.getNode(ISD::BITCAST, dl, VT,<br>
>> -                             DAG.getNode(X86ISD::PMULUDQ, dl, MulVT, Hi0,<br>
>> Hi1));<br>
>> +                             DAG.getNode(Opcode, dl, MulVT, Hi0, Hi1));<br>
>><br>
>>    // Shuffle it back into the right order.<br>
>> -  const int HighMask[] = {1, 3, 5, 7, 9, 11, 13, 15};<br>
>> +  const int HighMask[] = {1, 5, 3, 7, 9, 13, 11, 15};<br>
>>    SDValue Highs = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, HighMask);<br>
>> -  const int LowMask[] = {0, 2, 4, 6, 8, 10, 12, 14};<br>
>> +  const int LowMask[] = {0, 4, 2, 6, 8, 12, 10, 14};<br>
>>    SDValue Lows = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, LowMask);<br>
>><br>
>>    return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getValueType(), Highs,<br>
>> Lows);<br>
>> @@ -14188,7 +14197,8 @@ SDValue X86TargetLowering::LowerOperatio<br>
>>    case ISD::CTLZ_ZERO_UNDEF:    return LowerCTLZ_ZERO_UNDEF(Op, DAG);<br>
>>    case ISD::CTTZ:               return LowerCTTZ(Op, DAG);<br>
>>    case ISD::MUL:                return LowerMUL(Op, Subtarget, DAG);<br>
>> -  case ISD::UMUL_LOHI:          return LowerUMUL_LOHI(Op, Subtarget,<br>
>> DAG);<br>
>> +  case ISD::UMUL_LOHI:<br>
>> +  case ISD::SMUL_LOHI:          return LowerMUL_LOHI(Op, Subtarget, DAG);<br>
>>    case ISD::SRA:<br>
>>    case ISD::SRL:<br>
>>    case ISD::SHL:                return LowerShift(Op, Subtarget, DAG);<br>
>><br>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=207318&r1=207317&r2=207318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=207318&r1=207317&r2=207318&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)<br>
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Sat Apr 26 09:12:19 2014<br>
>> @@ -347,6 +347,8 @@ namespace llvm {<br>
>><br>
>>        // PMULUDQ - Vector multiply packed unsigned doubleword integers<br>
>>        PMULUDQ,<br>
>> +      // PMULUDQ - Vector multiply packed signed doubleword integers<br>
>> +      PMULDQ,<br>
>><br>
>>        // FMA nodes<br>
>>        FMADD,<br>
>><br>
>> Modified: llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=207318&r1=207317&r2=207318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=207318&r1=207317&r2=207318&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td (original)<br>
>> +++ llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td Sat Apr 26 09:12:19<br>
>> 2014<br>
>> @@ -175,6 +175,9 @@ def X86select  : SDNode<"X86ISD::SELECT"<br>
>>  def X86pmuludq : SDNode<"X86ISD::PMULUDQ",<br>
>>                          SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,<br>
>>                                        SDTCisSameAs<1,2>]>>;<br>
>> +def X86pmuldq  : SDNode<"X86ISD::PMULDQ",<br>
>> +                         SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,<br>
>> +                                       SDTCisSameAs<1,2>]>>;<br>
>><br>
>>  // Specific shuffle nodes - At some point ISD::VECTOR_SHUFFLE will always<br>
>> get<br>
>>  // translated into one of the target nodes below during lowering.<br>
>><br>
>> Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=207318&r1=207317&r2=207318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=207318&r1=207317&r2=207318&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)<br>
>> +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Sat Apr 26 09:12:19 2014<br>
>> @@ -7003,6 +7003,31 @@ multiclass SS48I_binop_rm<bits<8> opc, s<br>
>>         Sched<[itins.Sched.Folded, ReadAfterLd]>;<br>
>>  }<br>
>><br>
>> +/// SS48I_binop_rm2 - Simple SSE41 binary operator with different src and<br>
>> dst<br>
>> +/// types.<br>
>> +multiclass SS48I_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,<br>
>> +                         ValueType DstVT, ValueType SrcVT, RegisterClass<br>
>> RC,<br>
>> +                         PatFrag memop_frag, X86MemOperand x86memop,<br>
>> +                         OpndItins itins,<br>
>> +                         bit IsCommutable = 0, bit Is2Addr = 1> {<br>
>> +  let isCommutable = IsCommutable in<br>
>> +  def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),<br>
>> +       (ins RC:$src1, RC:$src2),<br>
>> +       !if(Is2Addr,<br>
>> +           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),<br>
>> +           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1,<br>
>> $src2}")),<br>
>> +       [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,<br>
>> +       Sched<[itins.Sched]>;<br>
>> +  def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),<br>
>> +       (ins RC:$src1, x86memop:$src2),<br>
>> +       !if(Is2Addr,<br>
>> +           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),<br>
>> +           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1,<br>
>> $src2}")),<br>
>> +       [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),<br>
>> +                                     (bitconvert (memop_frag<br>
>> addr:$src2)))))]>,<br>
>> +       Sched<[itins.Sched.Folded, ReadAfterLd]>;<br>
>> +}<br>
>> +<br>
>>  let Predicates = [HasAVX] in {<br>
>>    let isCommutable = 0 in<br>
>>    defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw",<br>
>> int_x86_sse41_packusdw,<br>
>> @@ -7031,8 +7056,9 @@ let Predicates = [HasAVX] in {<br>
>>    defm VPMAXUW   : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v8i16, VR128,<br>
>>                                    loadv2i64, i128mem, 0,<br>
>> SSE_INTALU_ITINS_P>,<br>
>>                                    VEX_4V;<br>
>> -  defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",<br>
>> int_x86_sse41_pmuldq,<br>
>> -                                      0, DEFAULT_ITINS_VECIMULSCHED>,<br>
>> VEX_4V;<br>
>> +  defm VPMULDQ   : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v2i64,<br>
>> v4i32,<br>
>> +                                   VR128, loadv2i64, i128mem,<br>
>> +                                   SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V;<br>
>>  }<br>
>><br>
>>  let Predicates = [HasAVX2] in {<br>
>> @@ -7064,9 +7090,9 @@ let Predicates = [HasAVX2] in {<br>
>>    defm VPMAXUWY  : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v16i16,<br>
>> VR256,<br>
>>                                    loadv4i64, i256mem, 0,<br>
>> SSE_INTALU_ITINS_P>,<br>
>>                                    VEX_4V, VEX_L;<br>
>> -  defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",<br>
>> -                                        int_x86_avx2_pmul_dq,<br>
>> WriteVecIMul>,<br>
>> -                                        VEX_4V, VEX_L;<br>
>> +  defm VPMULDQY : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v4i64,<br>
>> v8i32,<br>
>> +                                  VR256, loadv4i64, i256mem,<br>
>> +                                  SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V,<br>
>> VEX_L;<br>
>>  }<br>
>><br>
>>  let Constraints = "$src1 = $dst" in {<br>
>> @@ -7089,8 +7115,9 @@ let Constraints = "$src1 = $dst" in {<br>
>>                                   memopv2i64, i128mem, 1,<br>
>> SSE_INTALU_ITINS_P>;<br>
>>    defm PMAXUW   : SS48I_binop_rm<0x3E, "pmaxuw", X86umax, v8i16, VR128,<br>
>>                                   memopv2i64, i128mem, 1,<br>
>> SSE_INTALU_ITINS_P>;<br>
>> -  defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",<br>
>> int_x86_sse41_pmuldq,<br>
>> -                                     1, SSE_INTMUL_ITINS_P>;<br>
>> +  defm PMULDQ   : SS48I_binop_rm2<0x28, "pmuldq", X86pmuldq, v2i64,<br>
>> v4i32,<br>
>> +                                  VR128, memopv2i64, i128mem,<br>
>> +                                  SSE_INTMUL_ITINS_P, 1>;<br>
>>  }<br>
>><br>
>>  let Predicates = [HasAVX] in {<br>
>><br>
>> Modified: llvm/trunk/test/CodeGen/X86/vector-idiv.ll<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-idiv.ll?rev=207318&r1=207317&r2=207318&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-idiv.ll?rev=207318&r1=207317&r2=207318&view=diff</a><br>

>><br>
>> ==============================================================================<br>
>> --- llvm/trunk/test/CodeGen/X86/vector-idiv.ll (original)<br>
>> +++ llvm/trunk/test/CodeGen/X86/vector-idiv.ll Sat Apr 26 09:12:19 2014<br>
>> @@ -1,4 +1,4 @@<br>
>> -; RUN: llc -march=x86-64 -mcpu=core2 < %s | FileCheck %s<br>
>> -check-prefix=SSE<br>
>> +; RUN: llc -march=x86-64 -mcpu=corei7 < %s | FileCheck %s<br>
>> -check-prefix=SSE<br>
>>  ; RUN: llc -march=x86-64 -mcpu=core-avx2 < %s | FileCheck %s<br>
>> -check-prefix=AVX<br>
>><br>
>>  define <4 x i32> @test1(<4 x i32> %a) {<br>
>> @@ -103,4 +103,51 @@ define <16 x i16> @test6(<16 x i16> %a)<br>
>>  ; AVX-NOT: vpmulhw<br>
>>  }<br>
>><br>
>> -; TODO: sdiv -> pmuldq<br>
>> +define <16 x i8> @test7(<16 x i8> %a) {<br>
>> +  %div = sdiv <16 x i8> %a, <i8 7, i8 7, i8 7, i8 7,i8 7, i8 7, i8 7, i8<br>
>> 7, i8 7, i8 7, i8 7, i8 7,i8 7, i8 7, i8 7, i8 7><br>
>> +  ret <16 x i8> %div<br>
>> +}<br>
>> +<br>
>> +define <4 x i32> @test8(<4 x i32> %a) {<br>
>> +  %div = sdiv <4 x i32> %a, <i32 7, i32 7, i32 7, i32 7><br>
>> +  ret <4 x i32> %div<br>
>> +<br>
>> +; SSE-LABEL: test8:<br>
>> +; SSE: pmuldq<br>
>> +; SSE: pshufd  $57<br>
>> +; SSE: pmuldq<br>
>> +; SSE: shufps  $-35<br>
>> +; SSE: pshufd  $-40<br>
>> +; SSE: padd<br>
>> +; SSE: psrld $31<br>
>> +; SSE: psrad $2<br>
>> +; SSE: padd<br>
>> +<br>
>> +; AVX-LABEL: test8:<br>
>> +; AVX: vpmuldq<br>
>> +; AVX: vpshufd $57<br>
>> +; AVX: vpmuldq<br>
>> +; AVX: vshufps $-35<br>
>> +; AVX: vpshufd $-40<br>
>> +; AVX: vpadd<br>
>> +; AVX: vpsrld $31<br>
>> +; AVX: vpsrad $2<br>
>> +; AVX: vpadd<br>
>> +}<br>
>> +<br>
>> +define <8 x i32> @test9(<8 x i32> %a) {<br>
>> +  %div = sdiv <8 x i32> %a, <i32 7, i32 7, i32 7, i32 7,i32 7, i32 7, i32<br>
>> 7, i32 7><br>
>> +  ret <8 x i32> %div<br>
>> +<br>
>> +; AVX-LABEL: test9:<br>
>> +; AVX: vpermd<br>
>> +; AVX: vpmuldq<br>
>> +; AVX: vshufps $-35<br>
>> +; AVX: vpmuldq<br>
>> +; AVX: vshufps $-35<br>
>> +; AVX: vpshufd $-40<br>
>> +; AVX: vpadd<br>
>> +; AVX: vpsrld $31<br>
>> +; AVX: vpsrad $2<br>
>> +; AVX: vpadd<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>
</div></div></blockquote></div><br></div>