diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index b2173c6ca5da..af1e57b3e6f5 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -898,7 +898,7 @@ SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDValue Op) { Chain); if (Subtarget->isThumb1Only()) { - // Use tADDrSPr since Thumb1 does not have a sub r, sp, r. ARMISelLowering + // Use tADDspr since Thumb1 does not have a sub r, sp, r. ARMISelLowering // should have negated the size operand already. FIXME: We can't insert // new target independent node at this stage so we are forced to negate // it earlier. Is there a better solution? diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index f8772476f876..44dcdac53775 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -149,9 +149,9 @@ def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU, def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU, "sub $dst, $rhs * 4", []>; -// ADD rm, sp, rm -def tADDrSPr : TI<(outs GPR:$dst), (ins GPR:$sp, GPR:$rhs), IIC_iALU, - "add $dst, $sp, $rhs", []>; +// ADD rm, sp +def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU, + "add $dst, $rhs", []>; // ADD sp, rm def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU, diff --git a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp index da3701d390a0..8f6fb3ac8438 100644 --- a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp +++ b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp @@ -57,6 +57,8 @@ namespace { // FIXME: t2ADDS variants. { ARM::t2ADDri, ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 0,0, 0 }, { ARM::t2ADDrr, ARM::tADDrr, ARM::tADDhirr, 0, 0, 1, 0, 0,1, 0 }, + // Note: immediate scale is 4. + { ARM::t2ADDrSPi,ARM::tADDrSPi,0, 8, 0, 1, 0, 1,0, 0 }, { ARM::t2ANDrr, 0, ARM::tAND, 0, 0, 0, 1, 0,0, 0 }, { ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 0 }, { ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 0 }, @@ -199,7 +201,7 @@ static bool VerifyLowRegs(MachineInstr *MI) { unsigned Opc = MI->getOpcode(); bool isPCOk = (Opc == ARM::t2LDM_RET) || (Opc == ARM::t2LDM); bool isLROk = (Opc == ARM::t2STM); - bool isSPOk = isPCOk || isLROk; + bool isSPOk = isPCOk || isLROk || (Opc == ARM::t2ADDrSPi); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); if (!MO.isReg() || MO.isImplicit()) @@ -423,8 +425,9 @@ Thumb2SizeReduce::ReduceToNarrow(MachineBasicBlock &MBB, MachineInstr *MI, return false; unsigned Limit = ~0U; + unsigned Scale = (Entry.WideOpc == ARM::t2ADDrSPi) ? 4 : 1; if (Entry.Imm1Limit) - Limit = (1 << Entry.Imm1Limit) - 1; + Limit = ((1 << Entry.Imm1Limit) - 1) * Scale; const TargetInstrDesc &TID = MI->getDesc(); for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { @@ -435,10 +438,13 @@ Thumb2SizeReduce::ReduceToNarrow(MachineBasicBlock &MBB, MachineInstr *MI, unsigned Reg = MO.getReg(); if (!Reg || Reg == ARM::CPSR) continue; + if (Entry.WideOpc == ARM::t2ADDrSPi && Reg == ARM::SP) + continue; if (Entry.LowRegs1 && !isARMLowRegister(Reg)) return false; - } else if (MO.isImm()) { - if (MO.getImm() > Limit) + } else if (MO.isImm() && + !TID.OpInfo[i].isPredicate()) { + if (MO.getImm() > Limit || (MO.getImm() & (Scale-1)) != 0) return false; } } @@ -479,9 +485,14 @@ Thumb2SizeReduce::ReduceToNarrow(MachineBasicBlock &MBB, MachineInstr *MI, for (unsigned i = 1, e = MI->getNumOperands(); i != e; ++i) { if (i < NumOps && TID.OpInfo[i].isOptionalDef()) continue; - if (SkipPred && TID.OpInfo[i].isPredicate()) - continue; - MIB.addOperand(MI->getOperand(i)); + bool isPred = (i < NumOps && TID.OpInfo[i].isPredicate()); + if (SkipPred && isPred) + continue; + const MachineOperand &MO = MI->getOperand(i); + if (Scale > 1 && !isPred && MO.isImm()) + MIB.addImm(MO.getImm() / Scale); + else + MIB.addOperand(MO); } diff --git a/llvm/test/CodeGen/Thumb2/2009-07-21-ISelBug.ll b/llvm/test/CodeGen/Thumb2/2009-07-21-ISelBug.ll index 98979b5449b7..0766a574693d 100644 --- a/llvm/test/CodeGen/Thumb2/2009-07-21-ISelBug.ll +++ b/llvm/test/CodeGen/Thumb2/2009-07-21-ISelBug.ll @@ -1,10 +1,12 @@ -; RUN: llvm-as < %s | llc -mtriple=thumbv7-apple-darwin9 -mattr=+vfp2,+thumb2 +; RUN: llvm-as < %s | llc -mtriple=thumbv7-apple-darwin9 -mattr=+vfp2,+thumb2 | FileCheck %s ; rdar://7076238 @"\01LC" = external constant [36 x i8], align 1 ; <[36 x i8]*> [#uses=1] -define arm_apcscc i32 @getUnknown(i32, ...) nounwind { +define arm_apcscc i32 @t(i32, ...) nounwind { entry: +; CHECK: t: +; CHECK: add r7, sp, #3 * 4 %1 = load i8** undef, align 4 ; [#uses=3] %2 = getelementptr i8* %1, i32 4 ; [#uses=1] %3 = getelementptr i8* %1, i32 8 ; [#uses=1]