From 1ec72738ac685543a02068559877ec713b36a463 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 14 Sep 2006 21:11:37 +0000 Subject: [PATCH] Fold (X & C1) | (Y & C2) -> (X|Y) & C3 when possible. This implements CodeGen/X86/and-or-fold.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30379 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 59b87043aa7..e098bd98439 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1155,6 +1155,26 @@ SDOperand DAGCombiner::visitOR(SDNode *N) { if (Tmp.Val) return Tmp; } + // (X & C1) | (Y & C2) -> (X|Y) & C3 if possible. + if (N0.getOpcode() == ISD::AND && + N1.getOpcode() == ISD::AND && + N0.getOperand(1).getOpcode() == ISD::Constant && + N1.getOperand(1).getOpcode() == ISD::Constant && + // Don't increase # computations. + (N0.Val->hasOneUse() || N1.Val->hasOneUse())) { + // We can only do this xform if we know that bits from X that are set in C2 + // but not in C1 are already zero. Likewise for Y. + uint64_t LHSMask = cast(N0.getOperand(1))->getValue(); + uint64_t RHSMask = cast(N1.getOperand(1))->getValue(); + + if (TLI.MaskedValueIsZero(N0.getOperand(0), RHSMask&~LHSMask) && + TLI.MaskedValueIsZero(N1.getOperand(0), LHSMask&~RHSMask)) { + SDOperand X =DAG.getNode(ISD::OR, VT, N0.getOperand(0), N1.getOperand(0)); + return DAG.getNode(ISD::AND, VT, X, DAG.getConstant(LHSMask|RHSMask, VT)); + } + } + + // See if this is some rotate idiom. if (SDNode *Rot = MatchRotate(N0, N1)) return SDOperand(Rot, 0); -- 2.34.1