[DAGCombiner] Rebuild (setcc x, y, ==) from (xor (xor x, y), 1)
authorRoger Ferrer Ibanez <roger.ferrer@bsc.es>
Wed, 7 Aug 2019 15:31:29 +0000 (15:31 +0000)
committerRoger Ferrer Ibanez <roger.ferrer@bsc.es>
Wed, 15 Jul 2020 07:34:22 +0000 (07:34 +0000)
The existing code already considered this case. Unfortunately a typo in
the condition prevents it from triggering. Also the existing code, had
it run, forgot to do the folding.

This fixes PR42876.

Differential Revision: https://reviews.llvm.org/D65802

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/AArch64/cmp-bool.ll
llvm/test/CodeGen/ARM/cmp-bool.ll
llvm/test/CodeGen/RISCV/cmp-bool.ll
llvm/test/CodeGen/WebAssembly/reg-stackify.ll
llvm/test/CodeGen/X86/cmp-bool.ll

index dc9c86264e60249f81d85315318a746d75565247..f14b3dba4f3180beb134e6e195dd92caf81c216d 100644 (file)
@@ -14099,8 +14099,8 @@ SDValue DAGCombiner::rebuildSetCC(SDValue N) {
     }
   }
 
-  // Transform br(xor(x, y)) -> br(x != y)
-  // Transform br(xor(xor(x,y), 1)) -> br (x == y)
+  // Transform (brcond (xor x, y)) -> (brcond (setcc, x, y, ne))
+  // Transform (brcond (xor (xor x, y), -1)) -> (brcond (setcc, x, y, eq))
   if (N.getOpcode() == ISD::XOR) {
     // Because we may call this on a speculatively constructed
     // SimplifiedSetCC Node, we need to simplify this node first.
@@ -14124,16 +14124,17 @@ SDValue DAGCombiner::rebuildSetCC(SDValue N) {
     if (N.getOpcode() != ISD::XOR)
       return N;
 
-    SDNode *TheXor = N.getNode();
-
-    SDValue Op0 = TheXor->getOperand(0);
-    SDValue Op1 = TheXor->getOperand(1);
+    SDValue Op0 = N->getOperand(0);
+    SDValue Op1 = N->getOperand(1);
 
     if (Op0.getOpcode() != ISD::SETCC && Op1.getOpcode() != ISD::SETCC) {
       bool Equal = false;
-      if (isOneConstant(Op0) && Op0.hasOneUse() &&
-          Op0.getOpcode() == ISD::XOR) {
-        TheXor = Op0.getNode();
+      // (brcond (xor (xor x, y), -1)) -> (brcond (setcc x, y, eq))
+      if (isBitwiseNot(N) && Op0.hasOneUse() && Op0.getOpcode() == ISD::XOR &&
+          Op0.getValueType() == MVT::i1) {
+        N = Op0;
+        Op0 = N->getOperand(0);
+        Op1 = N->getOperand(1);
         Equal = true;
       }
 
@@ -14141,7 +14142,7 @@ SDValue DAGCombiner::rebuildSetCC(SDValue N) {
       if (LegalTypes)
         SetCCVT = getSetCCResultType(SetCCVT);
       // Replace the uses of XOR with SETCC
-      return DAG.getSetCC(SDLoc(TheXor), SetCCVT, Op0, Op1,
+      return DAG.getSetCC(SDLoc(N), SetCCVT, Op0, Op1,
                           Equal ? ISD::SETEQ : ISD::SETNE);
     }
   }
index 41c3ddc4528a07a09af9bb0193dac0aaabe500c6..907d982a7efd1e080564d4e17b7658655b82138f 100644 (file)
@@ -25,9 +25,8 @@ if.end:
 define void @bool_ne(i1 zeroext %a, i1 zeroext %b, void ()* nocapture %c) nounwind {
 ; CHECK-LABEL: bool_ne:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    eor w8, w0, w1
-; CHECK-NEXT:    cmp w8, #1 // =1
-; CHECK-NEXT:    b.ne .LBB1_2
+; CHECK-NEXT:    cmp w0, w1
+; CHECK-NEXT:    b.eq .LBB1_2
 ; CHECK-NEXT:  // %bb.1: // %if.then
 ; CHECK-NEXT:    br x2
 ; CHECK-NEXT:  .LBB1_2: // %if.end
index a3ad9f7b8cabc38eda253133fa358dade16678e3..18ef348b9edac86f9a1b75ce43d9028ede41d477 100644 (file)
@@ -41,17 +41,15 @@ if.end:
 define void @bool_ne(i1 zeroext %a, i1 zeroext %b, void ()* nocapture %c) nounwind {
 ; ARM-LABEL: bool_ne:
 ; ARM:       @ %bb.0: @ %entry
-; ARM-NEXT:    eor r0, r0, r1
-; ARM-NEXT:    cmp r0, #1
-; ARM-NEXT:    bxne lr
+; ARM-NEXT:    cmp r0, r1
+; ARM-NEXT:    bxeq lr
 ; ARM-NEXT:    bx r2
 ;
 ; THUMB-LABEL: bool_ne:
 ; THUMB:       @ %bb.0: @ %entry
 ; THUMB-NEXT:    push {r7, lr}
-; THUMB-NEXT:    eors r0, r1
-; THUMB-NEXT:    cmp r0, #1
-; THUMB-NEXT:    bne .LBB1_2
+; THUMB-NEXT:    cmp r0, r1
+; THUMB-NEXT:    beq .LBB1_2
 ; THUMB-NEXT:  @ %bb.1: @ %if.then
 ; THUMB-NEXT:    blx r2
 ; THUMB-NEXT:  .LBB1_2: @ %if.end
@@ -59,10 +57,9 @@ define void @bool_ne(i1 zeroext %a, i1 zeroext %b, void ()* nocapture %c) nounwi
 ;
 ; THUMB2-LABEL: bool_ne:
 ; THUMB2:       @ %bb.0: @ %entry
-; THUMB2-NEXT:    eors r0, r1
-; THUMB2-NEXT:    cmp r0, #1
-; THUMB2-NEXT:    it ne
-; THUMB2-NEXT:    bxne lr
+; THUMB2-NEXT:    cmp r0, r1
+; THUMB2-NEXT:    it eq
+; THUMB2-NEXT:    bxeq lr
 ; THUMB2-NEXT:    bx r2
 entry:
   %cmp = xor i1 %a, %b
index 785fcb1eaa89fa21ce66d78c9b698ff100955e71..01c9c9cae32cf5602ecef2ef26343217aa7292aa 100644 (file)
@@ -33,9 +33,7 @@ if.end:
 define void @bool_ne(i1 zeroext %a, i1 zeroext %b, void ()* nocapture %c) nounwind {
 ; RV32-LABEL: bool_ne:
 ; RV32:       # %bb.0: # %entry
-; RV32-NEXT:    xor a0, a0, a1
-; RV32-NEXT:    addi a1, zero, 1
-; RV32-NEXT:    bne a0, a1, .LBB1_2
+; RV32-NEXT:    beq a0, a1, .LBB1_2
 ; RV32-NEXT:  # %bb.1: # %if.then
 ; RV32-NEXT:    jr a2
 ; RV32-NEXT:  .LBB1_2: # %if.end
@@ -43,9 +41,7 @@ define void @bool_ne(i1 zeroext %a, i1 zeroext %b, void ()* nocapture %c) nounwi
 ;
 ; RV64-LABEL: bool_ne:
 ; RV64:       # %bb.0: # %entry
-; RV64-NEXT:    xor a0, a0, a1
-; RV64-NEXT:    addi a1, zero, 1
-; RV64-NEXT:    bne a0, a1, .LBB1_2
+; RV64-NEXT:    beq a0, a1, .LBB1_2
 ; RV64-NEXT:  # %bb.1: # %if.then
 ; RV64-NEXT:    jr a2
 ; RV64-NEXT:  .LBB1_2: # %if.end
index 24a8caffea93b28387921d7a0aed6304a3e3dfbb..80507b52a0bf639a9d1f778d2d73a4a1f764e422 100644 (file)
@@ -112,16 +112,14 @@ define i32 @no_sink_readonly_call(i32 %x, i32 %y, i32* %p) {
 ; CHECK-NEXT: i32.const   $push[[L11:[0-9]+]]=, 2{{$}}
 ; CHECK-NEXT: i32.lt_s    $push[[L4:[0-9]+]]=, $3, $pop[[L11]]{{$}}
 ; CHECK-NEXT: i32.xor     $push[[L6:[0-9]+]]=, $pop[[L3]], $pop[[L4]]{{$}}
-; CHECK-NEXT: i32.xor     $push[[L7:[0-9]+]]=, $pop[[L5]], $pop[[L6]]{{$}}
-; CHECK-NEXT: i32.const   $push10=, 1{{$}}
-; CHECK-NEXT: i32.ne      $push8=, $pop7, $pop10{{$}}
-; CHECK-NEXT: br_if       0, $pop8{{$}}
-; CHECK-NEXT: i32.const   $push9=, 0{{$}}
-; CHECK-NEXT: return      $pop9{{$}}
+; CHECK-NEXT: i32.eq      $push7=, $pop[[L5]], $pop[[L6]]{{$}}
+; CHECK-NEXT: br_if       0, $pop7{{$}}
+; CHECK-NEXT: i32.const   $push8=, 0{{$}}
+; CHECK-NEXT: return      $pop8{{$}}
 ; CHECK-NEXT: .LBB{{[0-9]+}}_2:
 ; CHECK-NEXT: end_block{{$}}
-; CHECK-NEXT: i32.const   $push14=, 1{{$}}
-; CHECK-NEXT: return      $pop14{{$}}
+; CHECK-NEXT: i32.const   $push12=, 1{{$}}
+; CHECK-NEXT: return      $pop12{{$}}
 ; NOREGS-LABEL: stack_uses:
 ; NOREGS: .functype stack_uses (i32, i32, i32, i32) -> (i32){{$}}
 ; NOREGS-NEXT: block {{$}}
@@ -139,9 +137,7 @@ define i32 @no_sink_readonly_call(i32 %x, i32 %y, i32* %p) {
 ; NOREGS-NEXT: i32.const   2{{$}}
 ; NOREGS-NEXT: i32.lt_s
 ; NOREGS-NEXT: i32.xor {{$}}
-; NOREGS-NEXT: i32.xor {{$}}
-; NOREGS-NEXT: i32.const   1{{$}}
-; NOREGS-NEXT: i32.ne {{$}}
+; NOREGS-NEXT: i32.eq {{$}}
 ; NOREGS-NEXT: br_if       0{{$}}
 ; NOREGS-NEXT: i32.const   0{{$}}
 ; NOREGS-NEXT: return{{$}}
index 400844bbb79f5a1aee72508b7b365d23181dc155..7af03cd7faf4b473db7a5f520efbfc4a0f8cd92e 100644 (file)
@@ -25,9 +25,8 @@ if.end:
 define void @bool_ne(i1 zeroext %a, i1 zeroext %b, void ()* nocapture %c) nounwind {
 ; CHECK-LABEL: bool_ne:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    xorl %esi, %edi
-; CHECK-NEXT:    cmpb $1, %dil
-; CHECK-NEXT:    jne .LBB1_1
+; CHECK-NEXT:    cmpb %sil, %dil
+; CHECK-NEXT:    je .LBB1_1
 ; CHECK-NEXT:  # %bb.2: # %if.then
 ; CHECK-NEXT:    jmpq *%rdx # TAILCALL
 ; CHECK-NEXT:  .LBB1_1: # %if.end