mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[DAGCombiner] Rebuild (setcc x, y, ==) from (xor (xor x, y), 1)
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
This commit is contained in:
parent
7ef6c6e4c3
commit
97e701dc7a
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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{{$}}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user