[llvm] r371095 - [x86] fix horizontal math bug exposed by improved demanded elements analysis (PR43225)

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 6 01:16:16 PDT 2019


Merged to release_90 in r371178.

On Thu, Sep 5, 2019 at 7:26 PM Sanjay Patel via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: spatel
> Date: Thu Sep  5 10:28:17 2019
> New Revision: 371095
>
> URL: http://llvm.org/viewvc/llvm-project?rev=371095&view=rev
> Log:
> [x86] fix horizontal math bug exposed by improved demanded elements analysis (PR43225)
>
> https://bugs.llvm.org/show_bug.cgi?id=43225
>
> Modified:
>     llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>     llvm/trunk/test/CodeGen/X86/haddsub-shuf-undef-operand.ll
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=371095&r1=371094&r2=371095&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Sep  5 10:28:17 2019
> @@ -33934,7 +33934,7 @@ static SDValue combineShuffleOfConcatUnd
>  }
>
>  /// Eliminate a redundant shuffle of a horizontal math op.
> -static SDValue foldShuffleOfHorizOp(SDNode *N) {
> +static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) {
>    unsigned Opcode = N->getOpcode();
>    if (Opcode != X86ISD::MOVDDUP && Opcode != X86ISD::VBROADCAST)
>      if (Opcode != ISD::VECTOR_SHUFFLE || !N->getOperand(1).isUndef())
> @@ -33965,6 +33965,25 @@ static SDValue foldShuffleOfHorizOp(SDNo
>        HOp.getOperand(0) != HOp.getOperand(1))
>      return SDValue();
>
> +  // The shuffle that we are eliminating may have allowed the horizontal op to
> +  // have an undemanded (undefined) operand. Duplicate the other (defined)
> +  // operand to ensure that the results are defined across all lanes without the
> +  // shuffle.
> +  auto updateHOp = [](SDValue HorizOp, SelectionDAG &DAG) {
> +    SDValue X;
> +    if (HorizOp.getOperand(0).isUndef()) {
> +      assert(!HorizOp.getOperand(1).isUndef() && "Not expecting foldable h-op");
> +      X = HorizOp.getOperand(1);
> +    } else if (HorizOp.getOperand(1).isUndef()) {
> +      assert(!HorizOp.getOperand(0).isUndef() && "Not expecting foldable h-op");
> +      X = HorizOp.getOperand(0);
> +    } else {
> +      return HorizOp;
> +    }
> +    return DAG.getNode(HorizOp.getOpcode(), SDLoc(HorizOp),
> +                       HorizOp.getValueType(), X, X);
> +  };
> +
>    // When the operands of a horizontal math op are identical, the low half of
>    // the result is the same as the high half. If a target shuffle is also
>    // replicating low and high halves, we don't need the shuffle.
> @@ -33975,7 +33994,7 @@ static SDValue foldShuffleOfHorizOp(SDNo
>        assert((HOp.getValueType() == MVT::v2f64 ||
>          HOp.getValueType() == MVT::v4f64) && HOp.getValueType() == VT &&
>          "Unexpected type for h-op");
> -      return HOp;
> +      return updateHOp(HOp, DAG);
>      }
>      return SDValue();
>    }
> @@ -33989,14 +34008,14 @@ static SDValue foldShuffleOfHorizOp(SDNo
>        (isTargetShuffleEquivalent(Mask, {0, 0}) ||
>         isTargetShuffleEquivalent(Mask, {0, 1, 0, 1}) ||
>         isTargetShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3})))
> -    return HOp;
> +    return updateHOp(HOp, DAG);
>
>    if (HOp.getValueSizeInBits() == 256 &&
>        (isTargetShuffleEquivalent(Mask, {0, 0, 2, 2}) ||
>         isTargetShuffleEquivalent(Mask, {0, 1, 0, 1, 4, 5, 4, 5}) ||
>         isTargetShuffleEquivalent(
>             Mask, {0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11})))
> -    return HOp;
> +    return updateHOp(HOp, DAG);
>
>    return SDValue();
>  }
> @@ -34050,7 +34069,7 @@ static SDValue combineShuffle(SDNode *N,
>      if (SDValue AddSub = combineShuffleToAddSubOrFMAddSub(N, Subtarget, DAG))
>        return AddSub;
>
> -    if (SDValue HAddSub = foldShuffleOfHorizOp(N))
> +    if (SDValue HAddSub = foldShuffleOfHorizOp(N, DAG))
>        return HAddSub;
>    }
>
>
> Modified: llvm/trunk/test/CodeGen/X86/haddsub-shuf-undef-operand.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/haddsub-shuf-undef-operand.ll?rev=371095&r1=371094&r2=371095&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/haddsub-shuf-undef-operand.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/haddsub-shuf-undef-operand.ll Thu Sep  5 10:28:17 2019
> @@ -1,14 +1,14 @@
>  ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
>  ; RUN: llc < %s -mtriple=x86_64-- -mattr=avx  | FileCheck %s
>
> -; FIXME: Eliminating a shuffle means we have to replace an undef operand of a horizontal op.
> +; Eliminating a shuffle means we have to replace an undef operand of a horizontal op.
>
>  define void @PR43225(<4 x double>* %p0, <4 x double>* %p1, <4 x double> %x, <4 x double> %y, <4 x double> %z) nounwind {
>  ; CHECK-LABEL: PR43225:
>  ; CHECK:       # %bb.0:
>  ; CHECK-NEXT:    vmovaps (%rdi), %ymm0
> -; CHECK-NEXT:    vmovapd (%rsi), %ymm0
> -; CHECK-NEXT:    vhsubpd %ymm0, %ymm2, %ymm0
> +; CHECK-NEXT:    vmovaps (%rsi), %ymm0
> +; CHECK-NEXT:    vhsubpd %ymm2, %ymm2, %ymm0
>  ; CHECK-NEXT:    vmovapd %ymm0, (%rdi)
>  ; CHECK-NEXT:    vzeroupper
>  ; CHECK-NEXT:    retq
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list