forked from OSchip/llvm-project
[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:
parent
036789a7e8
commit
f73ff612ca
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue