diff options
| author | Nirav Dave <niravd@google.com> | 2018-05-10 14:28:54 +0000 |
|---|---|---|
| committer | Nirav Dave <niravd@google.com> | 2018-05-10 14:28:54 +0000 |
| commit | a5ad417589272f9b042d73a80bdfb0259db43f19 (patch) | |
| tree | 262fb37a91706c4bc2bd892b9681ef135feb8b66 | |
| parent | 85343925d73a80b6a938399c64504a034afde554 (diff) | |
| download | bcm5719-llvm-a5ad417589272f9b042d73a80bdfb0259db43f19.tar.gz bcm5719-llvm-a5ad417589272f9b042d73a80bdfb0259db43f19.zip | |
[DAG] Avoid using deleted node in rebuildSetCC
Summary:
The combine in rebuildSetCC may be combined to another
node leaving our references stale. Keep a handle on
it to avoid stale references.
Fixes PR36602.
Reviewers: dbabokin, RKSimon, eli.friedman, davide
Subscribers: hiraditya, uabelho, JesperAntonsson, qcolombet, llvm-commits
Differential Revision: https://reviews.llvm.org/D46404
llvm-svn: 331985
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 29 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/pr36602.ll | 30 |
2 files changed, 51 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c36be8f0b73..22c31a0e78c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11524,16 +11524,29 @@ SDValue DAGCombiner::rebuildSetCC(SDValue N) { // Transform br(xor(x, y)) -> br(x != y) // Transform br(xor(xor(x,y), 1)) -> br (x == y) if (N.getOpcode() == ISD::XOR) { - SDNode *TheXor = N.getNode(); + // Because we may call this on a speculatively constructed + // SimplifiedSetCC Node, we need to simplify this node first. + // Ideally this should be folded into SimplifySetCC and not + // here. For now, grab a handle to N so we don't lose it from + // replacements interal to the visit. + HandleSDNode XORHandle(N); + while (N.getOpcode() == ISD::XOR) { + SDValue Tmp = visitXOR(N.getNode()); + // No simplification done. + if (!Tmp.getNode()) + break; + // Returning N is form in-visit replacement that may invalidated + // N. Grab value from Handle. + if (Tmp.getNode() == N.getNode()) + N = XORHandle.getValue(); + else // Node simplified. Try simplifying again. + N = Tmp; + } - // Avoid missing important xor optimizations. - while (SDValue Tmp = visitXOR(TheXor)) { - // We don't have a XOR anymore, bail. - if (Tmp.getOpcode() != ISD::XOR) - return Tmp; + if (N.getOpcode() != ISD::XOR) + return N; - TheXor = Tmp.getNode(); - } + SDNode *TheXor = N.getNode(); SDValue Op0 = TheXor->getOperand(0); SDValue Op1 = TheXor->getOperand(1); diff --git a/llvm/test/CodeGen/X86/pr36602.ll b/llvm/test/CodeGen/X86/pr36602.ll new file mode 100644 index 00000000000..fa2e05e8633 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr36602.ll @@ -0,0 +1,30 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s + + +define i32 @fn2() { +; CHECK-LABEL: fn2: +; CHECK: # %bb.0: +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: testb %al, %al +; CHECK-NEXT: jne .LBB0_2 +; CHECK-NEXT: # %bb.1: # %bb1 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB0_2: # %bb2 +; CHECK-NEXT: movl $1, %eax +; CHECK-NEXT: retq + %_tmp10 = icmp eq i8 0, 0 + %_tmp13 = icmp slt i8 undef, 1 + %_tmp151 = or i1 %_tmp10, %_tmp13 + %_tmp15 = zext i1 %_tmp151 to i8 + br i1 %_tmp151, label %bb1, label %bb2 + +bb1: ; preds = %0, %0 + ret i32 0 + +bb2: ; preds = %0, %0 + ret i32 1 + + +} |

