OSDN Git Service

Shrinkify Thumb2 r = add sp, imm.
authorEvan Cheng <evan.cheng@apple.com>
Tue, 11 Aug 2009 23:00:31 +0000 (23:00 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 11 Aug 2009 23:00:31 +0000 (23:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78745 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelDAGToDAG.cpp
lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/Thumb2SizeReduction.cpp
test/CodeGen/Thumb2/2009-07-21-ISelBug.ll

index b2173c6..af1e57b 100644 (file)
@@ -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?
index f877247..44dcdac 100644 (file)
@@ -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,
index da3701d..8f6fb3a 100644 (file)
@@ -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);
   }
 
 
index 98979b5..0766a57 100644 (file)
@@ -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           ; <i8*> [#uses=3]
        %2 = getelementptr i8* %1, i32 4                ; <i8*> [#uses=1]
        %3 = getelementptr i8* %1, i32 8                ; <i8*> [#uses=1]