forked from OSchip/llvm-project
[SDAG] Handle A and B&~A in haveNoCommonBitsSet()
This is the DAG variant of D124763. The code already handles the general pattern, but not this degenerate case. This allows folding A + (B&~A) to A | (B&~A) which further holds to A | B. Handling on the SDAG level is needed because in the motivating case the add is actually a getelementptr, which only gets converted into an add on the SDAG level. However, this patch is not quite sufficient to handle the getelementptr case yet, because of an interfering demanded bits simplification. Differential Revision: https://reviews.llvm.org/D124772
This commit is contained in:
parent
ed2d4da732
commit
2171a896ed
|
@ -4686,18 +4686,21 @@ bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
|
|||
|
||||
static bool haveNoCommonBitsSetCommutative(SDValue A, SDValue B) {
|
||||
// Match masked merge pattern (X & ~M) op (Y & M)
|
||||
if (A->getOpcode() == ISD::AND && B->getOpcode() == ISD::AND) {
|
||||
auto MatchNoCommonBitsPattern = [&](SDValue NotM, SDValue And) {
|
||||
if (isBitwiseNot(NotM, true)) {
|
||||
SDValue NotOperand = NotM->getOperand(0);
|
||||
return NotOperand == And->getOperand(0) ||
|
||||
NotOperand == And->getOperand(1);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// Including degenerate case (X & ~M) op M
|
||||
auto MatchNoCommonBitsPattern = [&](SDValue NotM, SDValue Other) {
|
||||
if (isBitwiseNot(NotM, true)) {
|
||||
SDValue NotOperand = NotM->getOperand(0);
|
||||
if (Other == NotOperand)
|
||||
return true;
|
||||
if (Other->getOpcode() == ISD::AND)
|
||||
return NotOperand == Other->getOperand(0) ||
|
||||
NotOperand == Other->getOperand(1);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (A->getOpcode() == ISD::AND)
|
||||
return MatchNoCommonBitsPattern(A->getOperand(0), B) ||
|
||||
MatchNoCommonBitsPattern(A->getOperand(1), B);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@ define i8 @add_and_xor(i8 %x, i8 %y) {
|
|||
; CHECK-LABEL: add_and_xor:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: notb %al
|
||||
; CHECK-NEXT: andb %sil, %al
|
||||
; CHECK-NEXT: addb %dil, %al
|
||||
; CHECK-NEXT: orl %esi, %eax
|
||||
; CHECK-NEXT: # kill: def $al killed $al killed $eax
|
||||
; CHECK-NEXT: retq
|
||||
%xor = xor i8 %x, -1
|
||||
%and = and i8 %xor, %y
|
||||
|
@ -51,9 +50,8 @@ define i8 @add_and_xor_commuted1(i8 %x, i8 %y) {
|
|||
; CHECK-LABEL: add_and_xor_commuted1:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: notb %al
|
||||
; CHECK-NEXT: andb %sil, %al
|
||||
; CHECK-NEXT: addb %dil, %al
|
||||
; CHECK-NEXT: orl %esi, %eax
|
||||
; CHECK-NEXT: # kill: def $al killed $al killed $eax
|
||||
; CHECK-NEXT: retq
|
||||
%xor = xor i8 %x, -1
|
||||
%and = and i8 %y, %xor
|
||||
|
@ -65,9 +63,8 @@ define i8 @add_and_xor_commuted2(i8 %x, i8 %y) {
|
|||
; CHECK-LABEL: add_and_xor_commuted2:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: notb %al
|
||||
; CHECK-NEXT: andb %sil, %al
|
||||
; CHECK-NEXT: addb %dil, %al
|
||||
; CHECK-NEXT: orl %esi, %eax
|
||||
; CHECK-NEXT: # kill: def $al killed $al killed $eax
|
||||
; CHECK-NEXT: retq
|
||||
%xor = xor i8 %x, -1
|
||||
%and = and i8 %xor, %y
|
||||
|
@ -79,9 +76,8 @@ define i8 @add_and_xor_commuted3(i8 %x, i8 %y) {
|
|||
; CHECK-LABEL: add_and_xor_commuted3:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: notb %al
|
||||
; CHECK-NEXT: andb %sil, %al
|
||||
; CHECK-NEXT: addb %dil, %al
|
||||
; CHECK-NEXT: orl %esi, %eax
|
||||
; CHECK-NEXT: # kill: def $al killed $al killed $eax
|
||||
; CHECK-NEXT: retq
|
||||
%xor = xor i8 %x, -1
|
||||
%and = and i8 %y, %xor
|
||||
|
@ -95,18 +91,17 @@ define i8 @add_and_xor_extra_use(i8 %x, i8 %y) nounwind {
|
|||
; CHECK-NEXT: pushq %rbp
|
||||
; CHECK-NEXT: pushq %r14
|
||||
; CHECK-NEXT: pushq %rbx
|
||||
; CHECK-NEXT: movl %esi, %r14d
|
||||
; CHECK-NEXT: movl %edi, %ebp
|
||||
; CHECK-NEXT: movl %ebp, %eax
|
||||
; CHECK-NEXT: movl %esi, %ebx
|
||||
; CHECK-NEXT: movl %edi, %r14d
|
||||
; CHECK-NEXT: movl %r14d, %eax
|
||||
; CHECK-NEXT: notb %al
|
||||
; CHECK-NEXT: movzbl %al, %ebx
|
||||
; CHECK-NEXT: movl %ebx, %edi
|
||||
; CHECK-NEXT: movzbl %al, %ebp
|
||||
; CHECK-NEXT: movl %ebp, %edi
|
||||
; CHECK-NEXT: callq use@PLT
|
||||
; CHECK-NEXT: andb %r14b, %bl
|
||||
; CHECK-NEXT: movzbl %bl, %ebx
|
||||
; CHECK-NEXT: movl %ebx, %edi
|
||||
; CHECK-NEXT: andb %bl, %bpl
|
||||
; CHECK-NEXT: movzbl %bpl, %edi
|
||||
; CHECK-NEXT: callq use@PLT
|
||||
; CHECK-NEXT: addb %bpl, %bl
|
||||
; CHECK-NEXT: orb %r14b, %bl
|
||||
; CHECK-NEXT: movl %ebx, %eax
|
||||
; CHECK-NEXT: popq %rbx
|
||||
; CHECK-NEXT: popq %r14
|
||||
|
|
Loading…
Reference in New Issue