mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-22 11:42:42 +00:00
DAGCombiner: Simplify inverted bit tests
Fold (xor (and x, y), y) -> (and (not x), y) This removes an opportunity for a constant to appear twice. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181395 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
aa76a93cd3
commit
363160a6be
@ -3460,6 +3460,15 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
|
||||
return DAG.getNode(NewOpcode, N->getDebugLoc(), VT, LHS, RHS);
|
||||
}
|
||||
}
|
||||
// fold (xor (and x, y), y) -> (and (not x), y)
|
||||
if (N0.getOpcode() == ISD::AND && N0.getNode()->hasOneUse() &&
|
||||
N0->getOperand(1) == N1) {
|
||||
SDValue X = N0->getOperand(0);
|
||||
SDValue NotX = DAG.getNode(ISD::XOR, X.getDebugLoc(), VT, X,
|
||||
DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT));
|
||||
AddToWorkList(NotX.getNode());
|
||||
return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, NotX, N1);
|
||||
}
|
||||
// fold (xor (xor x, c1), c2) -> (xor x, (xor c1, c2))
|
||||
if (N1C && N0.getOpcode() == ISD::XOR) {
|
||||
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
|
||||
|
@ -32,10 +32,10 @@ define i16 @sccwne(i16 %a, i16 %b) nounwind {
|
||||
}
|
||||
; CHECK:sccwne:
|
||||
; CHECK: cmp.w r14, r15
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: rra.w r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: xor.w #1, r15
|
||||
; CHECK: mov.w r2, r12
|
||||
; CHECK: rra.w r12
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: bic.w r12, r15
|
||||
|
||||
define i16 @sccweq(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp eq i16 %a, %b
|
||||
@ -55,9 +55,8 @@ define i16 @sccwugt(i16 %a, i16 %b) nounwind {
|
||||
}
|
||||
; CHECK:sccwugt:
|
||||
; CHECK: cmp.w r15, r14
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: xor.w #1, r15
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: bic.w r2, r15
|
||||
|
||||
define i16 @sccwuge(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp uge i16 %a, %b
|
||||
@ -76,9 +75,8 @@ define i16 @sccwult(i16 %a, i16 %b) nounwind {
|
||||
}
|
||||
; CHECK:sccwult:
|
||||
; CHECK: cmp.w r14, r15
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: xor.w #1, r15
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: bic.w r2, r15
|
||||
|
||||
define i16 @sccwule(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp ule i16 %a, %b
|
||||
|
@ -142,3 +142,15 @@ entry:
|
||||
; X32: test8:
|
||||
; X32: notl %eax
|
||||
}
|
||||
|
||||
define i32 @test9(i32 %a) nounwind {
|
||||
%1 = and i32 %a, 4096
|
||||
%2 = xor i32 %1, 4096
|
||||
ret i32 %2
|
||||
; X64: test9:
|
||||
; X64: notl [[REG:%[a-z]+]]
|
||||
; X64: andl {{.*}}[[REG:%[a-z]+]]
|
||||
; X32: test9:
|
||||
; X32: notl [[REG:%[a-z]+]]
|
||||
; X32: andl {{.*}}[[REG:%[a-z]+]]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user