<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Thanks for the test case, looking at this now. Simon.<br>
    </p>
    On 12/02/2017 19:10, Andrew Adams wrote:<br>
    <blockquote
cite="mid:CANSw88r9AWFZZQXiOzZfaAkwdykyG8nvt_3Kz=09o-oYiFg+vw@mail.gmail.com"
      type="cite">
      <div dir="ltr">Hi Simon, 
        <div><br>
        </div>
        <div>
          <div>A commit in between 294848 and 294862 has created a
            problem when no-nans-fp-math is on. I would open a bug, but
            buganizer is down. This commit looks at least related and in
            the right range. Here's a repro:</div>
          <div><br>
          </div>
          <div>test.ll:</div>
          <div><br>
          </div>
          <div>% Computes b = select(a < 0, -1, 1) * b</div>
          <div>define void @fn(<8 x float>* %a_ptr, <8 x
            float>* %b_ptr) {</div>
          <div>       %a = load <8 x float>, <8 x float>*
            %a_ptr</div>
          <div>       %b = load <8 x float>, <8 x float>*
            %b_ptr</div>
          <div>       %cmp = fcmp olt <8 x float> %a,
            zeroinitializer</div>
          <div>       %sel = select <8 x i1> %cmp, <8 x
            float> <float -1.000000e+00, float -1.000000e+00,
            float -1.000000e+00, float -1.000000e+00, float
            -1.000000e+00, float -1.000000e+00, float -1.000000e+00,
            float -1.000000e+00>, <8 x float> <float
            1.000000e+00, float 1.000000e+00, float 1.000000e+00, float
            1.000000e+00, float 1.000000e+00, float 1.000000e+00, float
            1.000000e+00, float 1.000000e+00></div>
          <div>       %c = fmul <8 x float> %sel, %b</div>
          <div>       store <8 x float> %c, <8 x float>*
            %b_ptr</div>
          <div>       ret void</div>
          <div>}</div>
          <div><br>
          </div>
          <div>$ llc test.ll -mcpu=haswell -enable-no-nans-fp-math -O3</div>
          <div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>.section<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>__TEXT,__text,regular,pure_instructions</div>
          <div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>.macosx_version_min
            10, 12</div>
          <div>LLVM ERROR: Cannot select: t43: v8f32 = vselect t7, t35,
            t32</div>
          <div>  t7: v8f32,ch = load<LD32[%a_ptr]> t0, t2,
            undef:i64</div>
          <div>    t2: i64,ch = CopyFromReg t0, Register:i64 %vreg0</div>
          <div>      t1: i64 = Register %vreg0</div>
          <div>    t6: i64 = undef</div>
          <div>  t35: v8f32 = X86ISD::VBROADCAST t34</div>
          <div>    t34: f32,ch = load<LD4[ConstantPool]> t0, t37,
            undef:i64</div>
          <div>      t37: i64 = X86ISD::WrapperRIP
            TargetConstantPool:i64<float -1.000000e+00> 0</div>
          <div>        t36: i64 = TargetConstantPool<float
            -1.000000e+00> 0</div>
          <div>      t6: i64 = undef</div>
          <div>  t32: v8f32 = X86ISD::VBROADCAST t31</div>
          <div>    t31: f32,ch = load<LD4[ConstantPool]> t0, t39,
            undef:i64</div>
          <div>      t39: i64 = X86ISD::WrapperRIP
            TargetConstantPool:i64<float 1.000000e+00> 0</div>
          <div>        t38: i64 = TargetConstantPool<float
            1.000000e+00> 0</div>
          <div>      t6: i64 = undef</div>
          <div>In function: fn</div>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Sat, Feb 11, 2017 at 11:27 AM, Simon
          Pilgrim via llvm-commits <span dir="ltr"><<a
              moz-do-not-send="true"
              href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">Author:
            rksimon<br>
            Date: Sat Feb 11 11:27:21 2017<br>
            New Revision: 294856<br>
            <br>
            URL: <a moz-do-not-send="true"
              href="http://llvm.org/viewvc/llvm-project?rev=294856&view=rev"
              rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=294856&view=rev</a><br>
            Log:<br>
            [X86][SSE] Convert getTargetShuffleMaskIndices to use
            getTargetConstantBitsFromNode.<br>
            <br>
            Removes duplicate constant extraction code in
            getTargetShuffleMaskIndices.<br>
            <br>
            getTargetConstantBitsFromNode - adds support for
            VZEXT_MOVL(SCALAR_TO_VECTOR) and fail if the caller doesn't
            support undef bits.<br>
            <br>
            Modified:<br>
                llvm/trunk/lib/Target/X86/<wbr>X86ISelLowering.cpp<br>
            <br>
            Modified: llvm/trunk/lib/Target/X86/<wbr>X86ISelLowering.cpp<br>
            URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=294856&r1=294855&r2=294856&view=diff"
              rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>X86/X86ISelLowering.cpp?rev=<wbr>294856&r1=294855&r2=294856&<wbr>view=diff</a><br>
            ==============================<wbr>==============================<wbr>==================<br>
            --- llvm/trunk/lib/Target/X86/<wbr>X86ISelLowering.cpp
            (original)<br>
            +++ llvm/trunk/lib/Target/X86/<wbr>X86ISelLowering.cpp Sat
            Feb 11 11:27:21 2017<br>
            @@ -5151,7 +5151,8 @@ static const Constant
            *getTargetConstant<br>
             // Extract raw constant bits from constant pools.<br>
             static bool getTargetConstantBitsFromNode(<wbr>SDValue Op,
            unsigned EltSizeInBits,<br>
                                                       SmallBitVector
            &UndefElts,<br>
            -                                         
            SmallVectorImpl<APInt> &EltBits) {<br>
            +                                         
            SmallVectorImpl<APInt> &EltBits,<br>
            +                                          bool AllowUndefs
            = true) {<br>
               assert(UndefElts.empty() && "Expected an empty
            UndefElts vector");<br>
               assert(EltBits.empty() && "Expected an empty
            EltBits vector");<br>
            <br>
            @@ -5171,6 +5172,10 @@ static bool
            getTargetConstantBitsFromNod<br>
            <br>
               // Split the undef/constant single bitset data into the
            target elements.<br>
               auto SplitBitData = [&]() {<br>
            +    // Don't split if we don't allow undef bits.<br>
            +    if (UndefBits.getBoolValue() && !AllowUndefs)<br>
            +      return false;<br>
            +<br>
                 UndefElts = SmallBitVector(NumElts, false);<br>
                 EltBits.resize(NumElts, APInt(EltSizeInBits, 0));<br>
            <br>
            @@ -5264,89 +5269,34 @@ static bool
            getTargetConstantBitsFromNod<br>
                 }<br>
               }<br>
            <br>
            +  // Extract a rematerialized scalar constant insertion.<br>
            +  if (Op.getOpcode() == X86ISD::VZEXT_MOVL &&<br>
            +      Op.getOperand(0).getOpcode() == ISD::SCALAR_TO_VECTOR
            &&<br>
            +      isa<ConstantSDNode>(Op.<wbr>getOperand(0).getOperand(0)))
            {<br>
            +    auto *CN = cast<ConstantSDNode>(Op.<wbr>getOperand(0).getOperand(0));<br>
            +    MaskBits = CN->getAPIntValue().<wbr>zextOrTrunc(SrcEltSizeInBits);<br>
            +    MaskBits = MaskBits.zext(SizeInBits);<br>
            +    return SplitBitData();<br>
            +  }<br>
            +<br>
               return false;<br>
             }<br>
            <br>
            -// TODO: Merge more of this with
            getTargetConstantBitsFromNode.<br>
             static bool getTargetShuffleMaskIndices(<wbr>SDValue
            MaskNode,<br>
                                                     unsigned
            MaskEltSizeInBits,<br>
                                                   
             SmallVectorImpl<uint64_t> &RawMask) {<br>
            -  MaskNode = peekThroughBitcasts(MaskNode);<br>
            -<br>
            -  MVT VT = MaskNode.getSimpleValueType();<br>
            -  assert(VT.isVector() && "Can't produce a
            non-vector with a build_vector!");<br>
            -  unsigned NumMaskElts = VT.getSizeInBits() /
            MaskEltSizeInBits;<br>
            -<br>
            -  // Split an APInt element into MaskEltSizeInBits sized
            pieces and<br>
            -  // insert into the shuffle mask.<br>
            -  auto SplitElementToMask = [&](APInt Element) {<br>
            -    // Note that this is x86 and so always little endian:
            the low byte is<br>
            -    // the first byte of the mask.<br>
            -    int Split = VT.getScalarSizeInBits() /
            MaskEltSizeInBits;<br>
            -    for (int i = 0; i < Split; ++i) {<br>
            -      APInt RawElt = Element.getLoBits(<wbr>MaskEltSizeInBits);<br>
            -      Element = Element.lshr(<wbr>MaskEltSizeInBits);<br>
            -      RawMask.push_back(RawElt.<wbr>getZExtValue());<br>
            -    }<br>
            -  };<br>
            -<br>
            -  if (MaskNode.getOpcode() == X86ISD::VBROADCAST) {<br>
            -    // TODO: Handle (MaskEltSizeInBits %
            VT.getScalarSizeInBits()) == 0<br>
            -    // TODO: Handle (VT.getScalarSizeInBits() %
            MaskEltSizeInBits) == 0<br>
            -    if (VT.getScalarSizeInBits() != MaskEltSizeInBits)<br>
            -      return false;<br>
            -    if (auto *CN = dyn_cast<ConstantSDNode>(<wbr>MaskNode.getOperand(0)))
            {<br>
            -      const APInt &MaskElement =
            CN->getAPIntValue();<br>
            -      for (unsigned i = 0, e = VT.getVectorNumElements(); i
            != e; ++i) {<br>
            -        APInt RawElt = MaskElement.getLoBits(<wbr>MaskEltSizeInBits);<br>
            -        RawMask.push_back(RawElt.<wbr>getZExtValue());<br>
            -      }<br>
            -    }<br>
            -    return false;<br>
            -  }<br>
            +  SmallBitVector UndefElts;<br>
            +  SmallVector<APInt, 64> EltBits;<br>
            <br>
            -  if (MaskNode.getOpcode() == X86ISD::VZEXT_MOVL &&<br>
            -      MaskNode.getOperand(0).<wbr>getOpcode() ==
            ISD::SCALAR_TO_VECTOR) {<br>
            -    SDValue MaskOp = MaskNode.getOperand(0).<wbr>getOperand(0);<br>
            -    if (auto *CN = dyn_cast<ConstantSDNode>(<wbr>MaskOp))
            {<br>
            -      if ((MaskEltSizeInBits % VT.getScalarSizeInBits()) ==
            0) {<br>
            -        RawMask.push_back(CN-><wbr>getZExtValue());<br>
            -        RawMask.append(NumMaskElts - 1, 0);<br>
            -        return true;<br>
            -      }<br>
            -<br>
            -      if ((VT.getScalarSizeInBits() % MaskEltSizeInBits) ==
            0) {<br>
            -        unsigned ElementSplit = VT.getScalarSizeInBits() /
            MaskEltSizeInBits;<br>
            -        SplitElementToMask(CN-><wbr>getAPIntValue());<br>
            -        RawMask.append((VT.<wbr>getVectorNumElements() - 1)
            * ElementSplit, 0);<br>
            -        return true;<br>
            -      }<br>
            -    }<br>
            -    return false;<br>
            -  }<br>
            -<br>
            -  if (MaskNode.getOpcode() != ISD::BUILD_VECTOR)<br>
            +  // Extract the raw target constant bits.<br>
            +  // FIXME: We currently don't support UNDEF bits or mask
            entries.<br>
            +  if (!<wbr>getTargetConstantBitsFromNode(<wbr>MaskNode,
            MaskEltSizeInBits, UndefElts,<br>
            +                                     EltBits, /*
            AllowUndefs */ false))<br>
                 return false;<br>
            <br>
            -  // We can always decode if the buildvector is all zero
            constants,<br>
            -  // but can't use isBuildVectorAllZeros as it might
            contain UNDEFs.<br>
            -  if (all_of(MaskNode->ops(), X86::isZeroNode)) {<br>
            -    RawMask.append(NumMaskElts, 0);<br>
            -    return true;<br>
            -  }<br>
            -<br>
            -  // TODO: Handle (MaskEltSizeInBits %
            VT.getScalarSizeInBits()) == 0<br>
            -  if ((VT.getScalarSizeInBits() % MaskEltSizeInBits) != 0)<br>
            -    return false;<br>
            -<br>
            -  for (SDValue Op : MaskNode->ops()) {<br>
            -    if (auto *CN = dyn_cast<ConstantSDNode>(Op.<wbr>getNode()))<br>
            -      SplitElementToMask(CN-><wbr>getAPIntValue());<br>
            -    else if (auto *CFN =
            dyn_cast<ConstantFPSDNode>(Op.<wbr>getNode()))<br>
            -      SplitElementToMask(CFN-><wbr>getValueAPF().bitcastToAPInt()<wbr>);<br>
            -    else<br>
            -      return false;<br>
            -  }<br>
            +  // Insert the extracted elements into the mask.<br>
            +  for (APInt Elt : EltBits)<br>
            +    RawMask.push_back(Elt.<wbr>getZExtValue());<br>
            <br>
               return true;<br>
             }<br>
            <br>
            <br>
            ______________________________<wbr>_________________<br>
            llvm-commits mailing list<br>
            <a moz-do-not-send="true"
              href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
            <a moz-do-not-send="true"
              href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits"
              rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>