diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2021-04-11 18:41:51 +0100 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2021-04-11 18:42:01 +0100 |
commit | 38c799bce8016f7487067a031b62cf98069aaa4d (patch) | |
tree | 5bd3873e9a7582dc945d7adebe2f7520c3ce0800 /llvm/lib/Target | |
parent | [RISCV] Drop earlyclobber constraint from vwadd(u).wx, vwsub(u).wx, vfwadd.wf... (diff) | |
download | llvm-project-38c799bce8016f7487067a031b62cf98069aaa4d.tar.gz llvm-project-38c799bce8016f7487067a031b62cf98069aaa4d.tar.bz2 llvm-project-38c799bce8016f7487067a031b62cf98069aaa4d.zip |
[X86] Fold cmpeq/ne(and(X,Y),Y) --> cmpeq/ne(and(~X,Y),0)
Followup to D100177, handle an similar (demorgan inverse style) case from PR47797 as well
The AVX512 test cases could be further improved if we folded not(iX bitcast(vXi1)) -> (iX bitcast(not(vXi1)))
Alive2: https://alive2.llvm.org/ce/z/AnA_-W
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 321d4791029a..3e260027bb83 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -48163,9 +48163,9 @@ static SDValue combineSetCC(SDNode *N, SelectionDAG &DAG, DAG.getNode(X86ISD::SETCC, DL, MVT::i8, X86CC, V)); } - // cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0) - // cmpne(or(X,Y),X) --> cmpne(and(~X,Y),0) if (OpVT.isScalarInteger()) { + // cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0) + // cmpne(or(X,Y),X) --> cmpne(and(~X,Y),0) auto MatchOrCmpEq = [&](SDValue N0, SDValue N1) { if (N0.getOpcode() == ISD::OR && N0->hasOneUse()) { if (N0.getOperand(0) == N1) @@ -48181,6 +48181,24 @@ static SDValue combineSetCC(SDNode *N, SelectionDAG &DAG, return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC); if (SDValue AndN = MatchOrCmpEq(RHS, LHS)) return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC); + + // cmpeq(and(X,Y),Y) --> cmpeq(and(~X,Y),0) + // cmpne(and(X,Y),Y) --> cmpne(and(~X,Y),0) + auto MatchAndCmpEq = [&](SDValue N0, SDValue N1) { + if (N0.getOpcode() == ISD::AND && N0->hasOneUse()) { + if (N0.getOperand(0) == N1) + return DAG.getNode(ISD::AND, DL, OpVT, N1, + DAG.getNOT(DL, N0.getOperand(1), OpVT)); + if (N0.getOperand(1) == N1) + return DAG.getNode(ISD::AND, DL, OpVT, N1, + DAG.getNOT(DL, N0.getOperand(0), OpVT)); + } + return SDValue(); + }; + if (SDValue AndN = MatchAndCmpEq(LHS, RHS)) + return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC); + if (SDValue AndN = MatchAndCmpEq(RHS, LHS)) + return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC); } } |