[DAGCombiner] Add one use check to fold (not (and x, y)) -> (or (not x), (not y))

Summary:
If the and has an additional use we shouldn't invert it. That creates an additional instruction.

While there add a one use check to the transform above that looked similar.

Reviewers: spatel, RKSimon

Reviewed By: RKSimon

Subscribers: llvm-commits

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

llvm-svn: 325019
This commit is contained in:
Craig Topper 2018-02-13 16:25:27 +00:00
parent 036789a7e8
commit f73ff612ca
2 changed files with 4 additions and 9 deletions

View File

@ -5398,7 +5398,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
} }
// fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are setcc // fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are setcc
if (isOneConstant(N1) && VT == MVT::i1 && if (isOneConstant(N1) && VT == MVT::i1 && N0.hasOneUse() &&
(N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) {
SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1); SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1);
if (isOneUseSetCC(RHS) || isOneUseSetCC(LHS)) { if (isOneUseSetCC(RHS) || isOneUseSetCC(LHS)) {
@ -5410,7 +5410,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
} }
} }
// fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are constants // fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are constants
if (isAllOnesConstant(N1) && if (isAllOnesConstant(N1) && N0.hasOneUse() &&
(N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) {
SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1); SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1);
if (isa<ConstantSDNode>(RHS) || isa<ConstantSDNode>(LHS)) { if (isa<ConstantSDNode>(RHS) || isa<ConstantSDNode>(LHS)) {

View File

@ -907,17 +907,12 @@ entry:
ret i64 %and ret i64 %and
} }
; This should select blcic ; Make sure the mask doesn't break our matching of blcic
; TODO: the xor is being combined with the mask and creating an or that's breaking this. Looks like a missing one use check.
define i64 @masked_blcic(i64) { define i64 @masked_blcic(i64) {
; CHECK-LABEL: masked_blcic: ; CHECK-LABEL: masked_blcic:
; CHECK: # %bb.0: ; CHECK: # %bb.0:
; CHECK-NEXT: movzwl %di, %eax ; CHECK-NEXT: movzwl %di, %eax
; CHECK-NEXT: # kill: def $edi killed $edi killed $rdi def $rdi ; CHECK-NEXT: blcicl %eax, %eax
; CHECK-NEXT: notl %edi
; CHECK-NEXT: orq $-65536, %rdi # imm = 0xFFFF0000
; CHECK-NEXT: incq %rax
; CHECK-NEXT: andq %rdi, %rax
; CHECK-NEXT: retq ; CHECK-NEXT: retq
%2 = and i64 %0, 65535 %2 = and i64 %0, 65535
%3 = xor i64 %2, -1 %3 = xor i64 %2, -1