From f73ff612cabc043d481b6fdd3b5e7cd92d5f0706 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 13 Feb 2018 16:25:27 +0000 Subject: [PATCH] [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 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 4 ++-- llvm/test/CodeGen/X86/tbm_patterns.ll | 9 ++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1c32a92ddad5..ac981d0457e9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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 - if (isOneConstant(N1) && VT == MVT::i1 && + if (isOneConstant(N1) && VT == MVT::i1 && N0.hasOneUse() && (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1); 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 - if (isAllOnesConstant(N1) && + if (isAllOnesConstant(N1) && N0.hasOneUse() && (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1); if (isa(RHS) || isa(LHS)) { diff --git a/llvm/test/CodeGen/X86/tbm_patterns.ll b/llvm/test/CodeGen/X86/tbm_patterns.ll index 14f8a8fe2dfc..0b63a0e68c5f 100644 --- a/llvm/test/CodeGen/X86/tbm_patterns.ll +++ b/llvm/test/CodeGen/X86/tbm_patterns.ll @@ -907,17 +907,12 @@ entry: ret i64 %and } -; This should select 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. +; Make sure the mask doesn't break our matching of blcic define i64 @masked_blcic(i64) { ; CHECK-LABEL: masked_blcic: ; CHECK: # %bb.0: ; CHECK-NEXT: movzwl %di, %eax -; CHECK-NEXT: # kill: def $edi killed $edi killed $rdi def $rdi -; CHECK-NEXT: notl %edi -; CHECK-NEXT: orq $-65536, %rdi # imm = 0xFFFF0000 -; CHECK-NEXT: incq %rax -; CHECK-NEXT: andq %rdi, %rax +; CHECK-NEXT: blcicl %eax, %eax ; CHECK-NEXT: retq %2 = and i64 %0, 65535 %3 = xor i64 %2, -1