Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11498,16 +11498,22 @@ // 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(); + while (N.getOpcode() == ISD::XOR) { + HandleSDNode XORHandle(N); + SDValue Tmp = visitXOR(N.getNode()); + if (!Tmp.getNode()) + break; + // In place update be a move. + if (Tmp.getNode() == N.getNode()) + N = XORHandle.getValue(); + else + 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); Index: llvm/test/CodeGen/X86/pr36602.ll =================================================================== --- /dev/null +++ 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 + + +}