Workaround a couple of Darwin assembler bugs.
authorEvan Cheng <evan.cheng@apple.com>
Sat, 1 Aug 2009 06:13:52 +0000 (06:13 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Sat, 1 Aug 2009 06:13:52 +0000 (06:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77781 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMConstantIslandPass.cpp
lib/Target/ARM/ARMInstrThumb2.td
test/CodeGen/Thumb2/thumb2-orn2.ll

index 84fad70c15e8f9da7ce8e42222eabf0cf3eac3c1..8dca6efbe84dba7ad7887f52fcc1f0e723c3e1a9 100644 (file)
@@ -466,9 +466,14 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
       // FIXME: If we know the size of the function is less than (1 << 16) *2
       // bytes, we can use 16-bit entries instead. Then there won't be an
       // alignment issue.
-      unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT)
-        ? 2 : 4;
-      return getNumJTEntries(JT, JTI) * EntrySize + InstSize;
+      unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4;
+      unsigned NumEntries = getNumJTEntries(JT, JTI);
+      if (Opc == ARM::t2TBB && (NumEntries & 1))
+        // Make sure the instruction that follows TBB is 2-byte aligned.
+        // FIXME: Constant island pass should insert an "ALIGN" instruction
+        // instead.
+        ++NumEntries;
+      return NumEntries * EntrySize + InstSize;
     }
     default:
       // Otherwise, pseudo-instruction sizes are zero.
index bf2784a54da025efea8ceee651f1150d5ba89672..782765a4335185cbda55a845eedd6386caff51e2 100644 (file)
@@ -132,6 +132,7 @@ namespace {
     bool HasFarJump;
 
     const TargetInstrInfo *TII;
+    const ARMSubtarget *STI;
     ARMFunctionInfo *AFI;
     bool isThumb;
     bool isThumb1;
@@ -227,6 +228,8 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
 
   TII = MF.getTarget().getInstrInfo();
   AFI = MF.getInfo<ARMFunctionInfo>();
+  STI = &MF.getTarget().getSubtarget<ARMSubtarget>();
+
   isThumb = AFI->isThumbFunction();
   isThumb1 = AFI->isThumb1OnlyFunction();
   isThumb2 = AFI->isThumb2Function();
@@ -281,6 +284,9 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
     MadeChange = true;
   }
 
+  // Let's see if we can use tbb / tbh to do jump tables.
+  MadeChange |= OptimizeThumb2JumpTables(MF);
+
   // After a while, this might be made debug-only, but it is not expensive.
   verify(MF);
 
@@ -289,9 +295,6 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
   if (isThumb && !HasFarJump && AFI->isLRSpilledForFarJump())
     MadeChange |= UndoLRSpillRestore();
 
-  // Let's see if we can use tbb / tbh to do jump tables.
-  MadeChange |= OptimizeThumb2JumpTables(MF);
-
   BBSizes.clear();
   BBOffsets.clear();
   WaterList.clear();
@@ -464,6 +467,8 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,
           bool NegOk = false;
           bool IsSoImm = false;
 
+          // FIXME: Temporary workaround until I can figure out what's going on.
+          unsigned Slack = T2JumpTables.empty() ? 0 : 4;
           switch (Opc) {
           default:
             llvm_unreachable("Unknown addressing mode for CP reference!");
@@ -513,7 +518,7 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,
           // Remember that this is a user of a CP entry.
           unsigned CPI = I->getOperand(op).getIndex();
           MachineInstr *CPEMI = CPEMIs[CPI];
-          unsigned MaxOffs = ((1 << Bits)-1) * Scale;
+          unsigned MaxOffs = ((1 << Bits)-1) * Scale - Slack;
           CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk, IsSoImm));
 
           // Increment corresponding CPEntry reference count.
@@ -675,7 +680,7 @@ MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {
 
   // We removed instructions from UserMBB, subtract that off from its size.
   // Add 2 or 4 to the block to count the unconditional branch we added to it.
-  unsigned delta = isThumb1 ? 2 : 4;
+  int delta = isThumb1 ? 2 : 4;
   BBSizes[OrigBBI] -= NewBBSize - delta;
 
   // ...and adjust BBOffsets for NewBB accordingly.
@@ -1362,7 +1367,10 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
       // sure all the branches are forward.
       if (ByteOk && (DstOffset - JTOffset) > ((1<<8)-1)*2)
         ByteOk = false;
-      if (HalfWordOk && (DstOffset - JTOffset) > ((1<<16)-1)*2)
+      unsigned TBHLimit = ((1<<16)-1)*2;
+      if (STI->isTargetDarwin())
+        TBHLimit >>= 1;  // FIXME: Work around an assembler bug.
+      if (HalfWordOk && (DstOffset - JTOffset) > TBHLimit)
         HalfWordOk = false;
       if (!ByteOk && !HalfWordOk)
         break;
@@ -1406,23 +1414,33 @@ bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
       MachineInstr *LeaMI = --PrevI;
       if (LeaMI->getOpcode() != ARM::t2LEApcrelJT ||
           LeaMI->getOperand(0).getReg() != BaseReg)
-        LeaMI = 0;
-
-      if (OptOk) {
-        unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH;
-        AddDefaultPred(BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc))
-                       .addReg(IdxReg, getKillRegState(IdxRegKill))
-                       .addJumpTableIndex(JTI, JTOP.getTargetFlags())
-                       .addImm(MI->getOperand(JTOpIdx+1).getImm()));
-        // FIXME: Insert an "ALIGN" instruction to ensure the next instruction
-        // is 2-byte aligned. For now, asm printer will fix it up.
-        AddrMI->eraseFromParent();
-        if (LeaMI)
-          LeaMI->eraseFromParent();
-        MI->eraseFromParent();
-        ++NumTBs;
-        MadeChange = true;
-      }
+        OptOk = false;
+
+      if (!OptOk)
+        continue;
+
+      unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH;
+      MachineInstr *NewJTMI = BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc))
+        .addReg(IdxReg, getKillRegState(IdxRegKill))
+        .addJumpTableIndex(JTI, JTOP.getTargetFlags())
+        .addImm(MI->getOperand(JTOpIdx+1).getImm());
+      // FIXME: Insert an "ALIGN" instruction to ensure the next instruction
+      // is 2-byte aligned. For now, asm printer will fix it up.
+      unsigned NewSize = TII->GetInstSizeInBytes(NewJTMI);
+      unsigned OrigSize = TII->GetInstSizeInBytes(AddrMI);
+      OrigSize += TII->GetInstSizeInBytes(LeaMI);
+      OrigSize += TII->GetInstSizeInBytes(MI);
+
+      AddrMI->eraseFromParent();
+      LeaMI->eraseFromParent();
+      MI->eraseFromParent();
+
+      int delta = OrigSize - NewSize;
+      BBSizes[MBB->getNumber()] -= delta;
+      AdjustBBOffsetsAfter(MBB, -delta);
+
+      ++NumTBs;
+      MadeChange = true;
     }
   }
 
index afab366639b538a8ea07533ca5a861718757e4e3..8c562b04355079fec0b0766ad49dfc5fb149b085 100644 (file)
@@ -749,7 +749,21 @@ def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
 
 // FIXME: A8.6.18  BFI - Bitfield insert (Encoding T1)
 
+/*
 defm t2ORN  : T2I_bin_irs<"orn", BinOpFrag<(or  node:$LHS, (not node:$RHS))>>;
+*/
+// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
+def t2ORNri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
+                   "orn", " $dst, $lhs, $rhs",
+                   [(set GPR:$dst, (or GPR:$lhs, (not t2_so_imm:$rhs)))]>,
+                   Requires<[IsThumb2, IsNotDarwin]>;
+
+def t2ORNrr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
+                   "orn", " $dst, $lhs, $rhs",
+                   [(set GPR:$dst, (or GPR:$lhs, (not GPR:$rhs)))]>;
+def t2ORNrs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
+                   "orn", " $dst, $lhs, $rhs",
+                   [(set GPR:$dst, (or GPR:$lhs, (not t2_so_reg:$rhs)))]>;
 
 // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
 let AddedComplexity = 1 in
@@ -759,8 +773,10 @@ defm t2MVN  : T2I_un_irs  <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
 def : T2Pat<(and     GPR:$src, t2_so_imm_not:$imm),
             (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
 
+// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
 def : T2Pat<(or      GPR:$src, t2_so_imm_not:$imm),
-            (t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
+            (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
+            Requires<[IsThumb2, IsNotDarwin]>;
 
 def : T2Pat<(t2_so_imm_not:$src),
             (t2MVNi t2_so_imm_not:$src)>;
@@ -1037,15 +1053,16 @@ def t2BR_JT :
           "mov pc, $target\n$jt",
           [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
 
+// FIXME: Add a non-pc based case that can be predicated.
 def t2TBB :
-    T2I<(outs),
+    T2JTI<(outs),
         (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
-        "tbb", " $index\n$jt", []>;
+        "tbb $index\n$jt", []>;
 
 def t2TBH :
-    T2I<(outs),
+    T2JTI<(outs),
         (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
-        "tbh", " $index\n$jt", []>;
+        "tbh $index\n$jt", []>;
 } // isNotDuplicable, isIndirectBranch
 
 } // isBranch, isTerminator, isBarrier
index 7758edd1d69383e87d13c27f9eaa649543b907b2..7679e38cc34678194a0eed94e4345b471fb4d43e 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep {orn\\W*r\[0-9\]*,\\W*r\[0-9\]*,\\W*#\[0-9\]*} | grep {#187\\|#11141290\\|#3422604288\\|#1114112} | count 4
+; RUN: llvm-as < %s | llc -mtriple=thumb-linux -mattr=+thumb2 | grep {orn\\W*r\[0-9\]*,\\W*r\[0-9\]*,\\W*#\[0-9\]*} | grep {#187\\|#11141290\\|#3422604288\\|#1114112} | count 4
 
 ; 0x000000bb = 187
 define i32 @f1(i32 %a) {