diff options
| author | Sean Fertile <sfertile@ca.ibm.com> | 2019-09-24 18:04:51 +0000 | 
|---|---|---|
| committer | Sean Fertile <sfertile@ca.ibm.com> | 2019-09-24 18:04:51 +0000 | 
| commit | b3a9320c08ef45de8039075cc532bdb89b5d88f9 (patch) | |
| tree | 28af73242d4dcfde7888be3fde2b014b46489dd4 | |
| parent | d9629b88ff72927cac6494293e5a5501e504b222 (diff) | |
| download | bcm5719-llvm-b3a9320c08ef45de8039075cc532bdb89b5d88f9.tar.gz bcm5719-llvm-b3a9320c08ef45de8039075cc532bdb89b5d88f9.zip  | |
Extends the expansion of the LWZtoc pseduo op for AIX.
Differential Revision: https://reviews.llvm.org/D67853
llvm-svn: 372772
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 53 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll | 21 | 
2 files changed, 59 insertions, 15 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index c835df3cabc..5ab2701be0e 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -649,16 +649,19 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {      }    }    case PPC::LWZtoc: { -    // Transform %r3 = LWZtoc @min1, %r2 +    assert(!isDarwin && "TOC is an ELF/XCOFF construct."); + +    // Transform %rN = LWZtoc @op1, %r2      LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); -    // Change the opcode to LWZ, and the global address operand to be a -    // reference to the GOT entry we will synthesize later. +    // Change the opcode to LWZ.      TmpInst.setOpcode(PPC::LWZ); +      const MachineOperand &MO = MI->getOperand(1); +    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() && +           "Unexpected operand type for LWZtoc pseudo."); -    // Map symbol -> label of TOC entry -    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()); +    // Map the operand to its corresponding MCSymbol.      MCSymbol *MOSymbol = nullptr;      if (MO.isGlobal())        MOSymbol = getSymbol(MO.getGlobal()); @@ -669,23 +672,43 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {      else if (MO.isBlockAddress())        MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); -    if (PL == PICLevel::SmallPIC) { +    const bool IsAIX = TM.getTargetTriple().isOSAIX(); + +    // Create a reference to the GOT entry for the symbol. The GOT entry will be +    // synthesized later. +    if (PL == PICLevel::SmallPIC && !IsAIX) {        const MCExpr *Exp =          MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,                                  OutContext);        TmpInst.getOperand(1) = MCOperand::createExpr(Exp); -    } else { -      MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); +      EmitToStreamer(*OutStreamer, TmpInst); +      return; +    } -      const MCExpr *Exp = -        MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, -                                OutContext); -      const MCExpr *PB = -        MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")), -                                                             OutContext); -      Exp = MCBinaryExpr::createSub(Exp, PB, OutContext); +    // Otherwise use the TOC. 'TOCEntry' is a local symbol used to reference +    // the storage allocated in the TOC which contains the address of +    // 'MOSymbol'. Said TOC entry will be synthesized later. +    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); +    const MCExpr *Exp = +        MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext); + +    // AIX uses the local symbol directly for the operand; that the symbol is +    // accessed toc-relative is implicit. +    if (IsAIX) { +      assert( +          TM.getCodeModel() == CodeModel::Small && +          "This pseudo should only be selected for 32-bit small code model.");        TmpInst.getOperand(1) = MCOperand::createExpr(Exp); +      EmitToStreamer(*OutStreamer, TmpInst); +      return;      } + +    // Create an explicit subtract expression between the local symbol and +    // '.LTOC' to manifest the toc-relative offset. +    const MCExpr *PB = MCSymbolRefExpr::create( +        OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext); +    Exp = MCBinaryExpr::createSub(Exp, PB, OutContext); +    TmpInst.getOperand(1) = MCOperand::createExpr(Exp);      EmitToStreamer(*OutStreamer, TmpInst);      return;    } diff --git a/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll b/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll new file mode 100644 index 00000000000..b368cb43dbb --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll @@ -0,0 +1,21 @@ +; RUN: llc -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -code-model=small < %s | FileCheck %s + +@b = common global i32 0 +@a = common global i32 0 + +define void @test() { +  %1 = load i32, i32* @b +  store i32 %1, i32* @a +  ret void +} + +; CHECK-LABEL:   test +; CHECK-DAG:       lwz [[REG1:[0-9]+]], LC0(2) +; CHECK-DAG:       lwz [[REG2:[0-9]+]], LC1(2) +; CHECK-DAG:       lwz [[REG3:[0-9]+]], 0([[REG1]]) +; CHECK:           stw [[REG3]], 0([[REG2]]) +; CHECK:           blr + +; TODO Update test when TOC-entry emission lands. +; CHECK-NOT: .tc  | 

