[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
This commit is contained in:
Nirav Dave 2018-05-10 14:28:54 +00:00
parent 85343925d7
commit a5ad417589
2 changed files with 52 additions and 9 deletions

View File

@ -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);

View File

@ -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
}