[llvm] r311623 - [DAG] Fix Node Replacement in PromoteIntBinOp

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 24 09:17:26 PDT 2017


Merged to 5.0 in r311670.

On Wed, Aug 23, 2017 at 6:08 PM, Hans Wennborg via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: hans
> Date: Wed Aug 23 18:08:27 2017
> New Revision: 311623
>
> URL: http://llvm.org/viewvc/llvm-project?rev=311623&view=rev
> Log:
> [DAG] Fix Node Replacement in PromoteIntBinOp
>
> When one operand is a user of another in a promoted binary operation
> we may replace and delete the returned value before returning
> triggering an assertion. Reorder node replacements to prevent this.
>
> Fixes PR34137.
>
> Landing on behalf of Nirav.
>
> Differential Revision: https://reviews.llvm.org/D36581
>
> Added:
>     llvm/trunk/test/CodeGen/X86/pr34137.ll
> Modified:
>     llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=311623&r1=311622&r2=311623&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Aug 23 18:08:27 2017
> @@ -1168,22 +1168,30 @@ SDValue DAGCombiner::PromoteIntBinOp(SDV
>      SDValue RV =
>          DAG.getNode(ISD::TRUNCATE, DL, VT, DAG.getNode(Opc, DL, PVT, NN0, NN1));
>
> -    // New replace instances of N0 and N1
> -    if (Replace0 && N0 && N0.getOpcode() != ISD::DELETED_NODE && NN0 &&
> -        NN0.getOpcode() != ISD::DELETED_NODE) {
> +    // We are always replacing N0/N1's use in N and only need
> +    // additional replacements if there are additional uses.
> +    Replace0 &= !N0->hasOneUse();
> +    Replace1 &= (N0 != N1) && !N1->hasOneUse();
> +
> +    // Combine Op here so it is presreved past replacements.
> +    CombineTo(Op.getNode(), RV);
> +
> +    // If operands have a use ordering, make sur we deal with
> +    // predecessor first.
> +    if (Replace0 && Replace1 && N0.getNode()->isPredecessorOf(N1.getNode())) {
> +      std::swap(N0, N1);
> +      std::swap(NN0, NN1);
> +    }
> +
> +    if (Replace0) {
>        AddToWorklist(NN0.getNode());
>        ReplaceLoadWithPromotedLoad(N0.getNode(), NN0.getNode());
>      }
> -
> -    if (Replace1 && N1 && N1.getOpcode() != ISD::DELETED_NODE && NN1 &&
> -        NN1.getOpcode() != ISD::DELETED_NODE) {
> +    if (Replace1) {
>        AddToWorklist(NN1.getNode());
>        ReplaceLoadWithPromotedLoad(N1.getNode(), NN1.getNode());
>      }
> -
> -    // Deal with Op being deleted.
> -    if (Op && Op.getOpcode() != ISD::DELETED_NODE)
> -      return RV;
> +    return Op;
>    }
>    return SDValue();
>  }
>
> Added: llvm/trunk/test/CodeGen/X86/pr34137.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr34137.ll?rev=311623&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/pr34137.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/pr34137.ll Wed Aug 23 18:08:27 2017
> @@ -0,0 +1,53 @@
> +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
> +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
> +
> + at var_3 = external global i16, align 2
> + at var_13 = external global i16, align 2
> + at var_212 = external global i64, align 8
> +
> +define void @pr34127() {
> +; CHECK-LABEL: pr34127:
> +; CHECK:       # BB#0: # %entry
> +; CHECK-NEXT:    movzwl {{.*}}(%rip), %eax
> +; CHECK-NEXT:    movw {{.*}}(%rip), %cx
> +; CHECK-NEXT:    andw %ax, %cx
> +; CHECK-NEXT:    andl %eax, %ecx
> +; CHECK-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
> +; CHECK-NEXT:    xorl %edx, %edx
> +; CHECK-NEXT:    testw %cx, %cx
> +; CHECK-NEXT:    sete %dl
> +; CHECK-NEXT:    andl %eax, %edx
> +; CHECK-NEXT:    movq %rdx, {{.*}}(%rip)
> +; CHECK-NEXT:    movw $0, (%rax)
> +; CHECK-NEXT:    retq
> +entry:
> +  %a = alloca i32, align 4
> +  %0 = load i16, i16* @var_3, align 2
> +  %conv = zext i16 %0 to i32
> +  %1 = load i16, i16* @var_3, align 2
> +  %conv1 = zext i16 %1 to i32
> +  %2 = load i16, i16* @var_13, align 2
> +  %conv2 = zext i16 %2 to i32
> +  %and = and i32 %conv1, %conv2
> +  %and3 = and i32 %conv, %and
> +  store i32 %and3, i32* %a, align 4
> +  %3 = load i16, i16* @var_3, align 2
> +  %conv4 = zext i16 %3 to i32
> +  %4 = load i16, i16* @var_3, align 2
> +  %conv5 = zext i16 %4 to i32
> +  %5 = load i16, i16* @var_13, align 2
> +  %conv6 = zext i16 %5 to i32
> +  %and7 = and i32 %conv5, %conv6
> +  %and8 = and i32 %conv4, %and7
> +  %tobool = icmp ne i32 %and8, 0
> +  %lnot = xor i1 %tobool, true
> +  %conv9 = zext i1 %lnot to i32
> +  %6 = load i16, i16* @var_3, align 2
> +  %conv10 = zext i16 %6 to i32
> +  %and11 = and i32 %conv9, %conv10
> +  %conv12 = sext i32 %and11 to i64
> +  store i64 %conv12, i64* @var_212, align 8
> +  %conv14 = zext i1 undef to i16
> +  store i16 %conv14, i16* undef, align 2
> +  ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list