From 25f7cfc3cccba6f569f29f79ea533bae960b93c0 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 1 Aug 2009 06:13:52 +0000 Subject: [PATCH] Workaround a couple of Darwin assembler bugs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77781 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 11 +++-- lib/Target/ARM/ARMConstantIslandPass.cpp | 62 +++++++++++++++--------- lib/Target/ARM/ARMInstrThumb2.td | 27 +++++++++-- test/CodeGen/Thumb2/thumb2-orn2.ll | 2 +- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 84fad70c15e..8dca6efbe84 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -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. diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index bf2784a54da..782765a4335 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -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(); + STI = &MF.getTarget().getSubtarget(); + 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; + OptOk = false; - 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; - } + 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; } } diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index afab366639b..8c562b04355 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -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 diff --git a/test/CodeGen/Thumb2/thumb2-orn2.ll b/test/CodeGen/Thumb2/thumb2-orn2.ll index 7758edd1d69..7679e38cc34 100644 --- a/test/CodeGen/Thumb2/thumb2-orn2.ll +++ b/test/CodeGen/Thumb2/thumb2-orn2.ll @@ -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) {