From: Evan Cheng Date: Tue, 13 Mar 2007 21:05:54 +0000 (+0000) Subject: AM2 can match 2^n +/- 1. e.g. ldr r3, [r2, r2, lsl #2] X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a13fd108f2c77adc60045859f1df4923b59a9d10;p=oota-llvm.git AM2 can match 2^n +/- 1. e.g. ldr r3, [r2, r2, lsl #2] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35088 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index c9642caef73..b0c040b39d7 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -102,6 +102,29 @@ void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op, SDOperand N, SDOperand &Base, SDOperand &Offset, SDOperand &Opc) { + if (N.getOpcode() == ISD::MUL) { + if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { + // X * [3,5,9] -> X + X * [2,4,8] etc. + int RHSC = (int)RHS->getValue(); + if (RHSC & 1) { + RHSC = RHSC & ~1; + ARM_AM::AddrOpc AddSub = ARM_AM::add; + if (RHSC < 0) { + AddSub = ARM_AM::sub; + RHSC = - RHSC; + } + if (isPowerOf2_32(RHSC)) { + unsigned ShAmt = Log2_32(RHSC); + Base = Offset = N.getOperand(0); + Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, + ARM_AM::lsl), + MVT::i32); + return true; + } + } + } + } + if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { Base = N; if (N.getOpcode() == ISD::FrameIndex) {