From a02a3dda5652995afaaf11148c11d98c9b9d908f Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 26 Mar 2009 06:14:09 +0000 Subject: [PATCH] Pull transform from target-dependent code into target-independent code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67742 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 49 ++++++++++++++++++++++++ lib/Target/X86/X86ISelLowering.cpp | 39 ------------------- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index db4b3927233..041c5007c53 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4355,6 +4355,55 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) { N1.getOperand(0), N1.getOperand(1), N2); } + if (N1.hasOneUse() && N1.getOpcode() == ISD::SRL) { + // Match this pattern so that we can generate simpler code: + // + // %a = ... + // %b = and i32 %a, 2 + // %c = srl i32 %b, 1 + // brcond i32 %c ... + // + // into + // + // %a = ... + // %b = and %a, 2 + // %c = setcc eq %b, 0 + // brcond %c ... + // + // This applies only when the AND constant value has one bit set and the + // SRL constant is equal to the log2 of the AND constant. The back-end is + // smart enough to convert the result into a TEST/JMP sequence. + SDValue Op0 = N1.getOperand(0); + SDValue Op1 = N1.getOperand(1); + + if (Op0.getOpcode() == ISD::AND && + Op0.hasOneUse() && + Op1.getOpcode() == ISD::Constant) { + SDValue AndOp0 = Op0.getOperand(0); + SDValue AndOp1 = Op0.getOperand(1); + + if (AndOp1.getOpcode() == ISD::Constant) { + const APInt &AndConst = cast(AndOp1)->getAPIntValue(); + + if (AndConst.isPowerOf2() && + cast(Op1)->getAPIntValue()==AndConst.logBase2()) { + SDValue SetCC = + DAG.getSetCC(N->getDebugLoc(), + TLI.getSetCCResultType(Op0.getValueType()), + Op0, DAG.getConstant(0, Op0.getValueType()), + ISD::SETNE); + + // Replace the uses of SRL with SETCC + DAG.ReplaceAllUsesOfValueWith(N1, SetCC); + removeFromWorkList(N1.getNode()); + DAG.DeleteNode(N1.getNode()); + return DAG.getNode(ISD::BRCOND, N->getDebugLoc(), + MVT::Other, Chain, SetCC, N2); + } + } + } + } + return SDValue(); } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 154e8d3fd9c..89228261659 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5870,45 +5870,6 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { CC = DAG.getConstant(CCode, MVT::i8); Cond = Cond.getOperand(0).getOperand(1); addTest = false; - } else if (Cond.hasOneUse() && Cond.getOpcode() == ISD::SRL) { - // Match this pattern so that we can generate simpler code: - // - // %a = ... - // %b = and i32 %a, 2 - // %c = srl i32 %b, 1 - // %d = br i32 %c, - // - // into - // - // %a = ... - // %b = and %a, 2 - // %c = X86ISD::CMP %b, 0 - // %d = X86ISD::BRCOND %c ... - // - // This applies only when the AND constant value has one bit set and the - // SRL constant is equal to the log2 of the AND constant. The back-end is - // smart enough to convert the result into a TEST/JMP sequence. - SDValue Op0 = Cond.getOperand(0); - SDValue Op1 = Cond.getOperand(1); - - if (Op0.getOpcode() == ISD::AND && - Op0.hasOneUse() && - Op1.getOpcode() == ISD::Constant) { - SDValue AndOp0 = Op0.getOperand(0); - SDValue AndOp1 = Op0.getOperand(1); - - if (AndOp1.getOpcode() == ISD::Constant) { - const APInt &AndConst = cast(AndOp1)->getAPIntValue(); - - if (AndConst.isPowerOf2() && - cast(Op1)->getAPIntValue()==AndConst.logBase2()) { - CC = DAG.getConstant(X86::COND_NE, MVT::i8); - Cond = EmitTest(Op0, X86::COND_NE, DAG); - return DAG.getNode(X86ISD::BRCOND, dl, Op.getValueType(), - Chain, Dest, CC, Cond); - } - } - } } } -- 2.34.1