From: David Goodwin Date: Thu, 30 Jul 2009 18:56:48 +0000 (+0000) Subject: Cleanup and include code selection for some frame index cases. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d8c95b5ac2ae0619c22434dbdd993196ea82489b;p=oota-llvm.git Cleanup and include code selection for some frame index cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77622 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index f5f5adedf6a..cadd7c690b2 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -598,7 +598,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, // Match simple R + imm12 operands. // Match frame index... - if (N.getOpcode() != ISD::ADD) { + if ((N.getOpcode() != ISD::ADD) && (N.getOpcode() != ISD::SUB)) { if (N.getOpcode() == ISD::FrameIndex) { int FI = cast(N)->getIndex(); Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); @@ -610,8 +610,15 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { int RHSC = (int)RHS->getZExtValue(); - if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits. + if (N.getOpcode() == ISD::SUB) + RHSC = -RHSC; + + if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) Base = N.getOperand(0); + if (Base.getOpcode() == ISD::FrameIndex) { + int FI = cast(Base)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); + } OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); return true; } @@ -622,20 +629,31 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N, SDValue &Base, SDValue &OffImm) { - if ((N.getOpcode() == ISD::ADD) || (N.getOpcode() == ISD::SUB)) { - if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { - int RHSC = (int)RHS->getSExtValue(); - if (N.getOpcode() == ISD::SUB) - RHSC = -RHSC; + // Match simple R - imm8 operands. - if ((RHSC >= -255) && (RHSC <= 0)) { // 8 bits (always negative) - Base = N.getOperand(0); - OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); - return true; + // Match frame index... + if ((N.getOpcode() != ISD::ADD) && (N.getOpcode() != ISD::SUB)) { + if (N.getOpcode() == ISD::FrameIndex) { + int FI = cast(N)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); + OffImm = CurDAG->getTargetConstant(0, MVT::i32); + return true; + } + return false; + } + + if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { + int RHSC = (int)RHS->getSExtValue(); + if (N.getOpcode() == ISD::SUB) + RHSC = -RHSC; + + if ((RHSC >= -255) && (RHSC <= 0)) { // 8 bits (always negative) + Base = N.getOperand(0); + if (Base.getOpcode() == ISD::FrameIndex) { + int FI = cast(Base)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); } - } else if (N.getOpcode() == ISD::SUB) { - Base = N; - OffImm = CurDAG->getTargetConstant(0, MVT::i32); + OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); return true; } } @@ -706,9 +724,24 @@ bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, return true; } + // Leave (R +/- imm) for other address modes... unless they can't + // handle them + if (dyn_cast(N.getOperand(1)) != NULL) { + SDValue OffImm; + if (SelectT2AddrModeImm12(Op, N, Base, OffImm) || + SelectT2AddrModeImm8 (Op, N, Base, OffImm)) + return false; + } + // Thumb2 does not support (R - R) or (R - (R << [1,2,3])). - if (N.getOpcode() != ISD::ADD) - return false; + if (N.getOpcode() == ISD::SUB) { + Base = N; + OffReg = CurDAG->getRegister(0, MVT::i32); + ShImm = CurDAG->getTargetConstant(0, MVT::i32); + return true; + } + + assert(N.getOpcode() == ISD::ADD); // Look for (R + R) or (R + (R << [1,2,3])). unsigned ShAmt = 0; @@ -736,10 +769,6 @@ bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, } else { ShOpcVal = ARM_AM::no_shift; } - } else if (SelectT2AddrModeImm12(Op, N, Base, ShImm) || - SelectT2AddrModeImm8 (Op, N, Base, ShImm)) { - // Don't match if it's possible to match to one of the r +/- imm cases. - return false; } ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32); diff --git a/test/CodeGen/Thumb2/pic-load.ll b/test/CodeGen/Thumb2/pic-load.ll index 71fec5d96d0..553377b48bc 100644 --- a/test/CodeGen/Thumb2/pic-load.ll +++ b/test/CodeGen/Thumb2/pic-load.ll @@ -8,7 +8,7 @@ define hidden arm_apcscc i32 @atexit(void ()* %func) nounwind { entry: ; CHECK: atexit: -; CHECK: add.w r1, r1, pc +; CHECK: add.w r0, r0, pc %r = alloca %struct.one_atexit_routine, align 4 ; <%struct.one_atexit_routine*> [#uses=3] %0 = getelementptr %struct.one_atexit_routine* %r, i32 0, i32 0, i32 0 ; [#uses=1] store void ()* %func, void ()** %0, align 4