From e72f853489cd772af1e021737ebee313567ea689 Mon Sep 17 00:00:00 2001 From: Nirav Dave Date: Thu, 10 May 2018 14:28:54 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331985 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 31 +++++++++++++++++------- test/CodeGen/X86/pr36602.ll | 30 +++++++++++++++++++++++ 2 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 test/CodeGen/X86/pr36602.ll diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c36be8f0b73..22c31a0e78c 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11524,17 +11524,30 @@ 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(); - - // 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; - - TheXor = Tmp.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; } + if (N.getOpcode() != ISD::XOR) + return N; + + SDNode *TheXor = N.getNode(); + SDValue Op0 = TheXor->getOperand(0); SDValue Op1 = TheXor->getOperand(1); diff --git a/test/CodeGen/X86/pr36602.ll b/test/CodeGen/X86/pr36602.ll new file mode 100644 index 00000000000..fa2e05e8633 --- /dev/null +++ b/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 + + +}