[llvm] r372772 - Extends the expansion of the LWZtoc pseduo op for AIX.

Sean Fertile via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 24 11:04:52 PDT 2019


Author: sfertile
Date: Tue Sep 24 11:04:51 2019
New Revision: 372772

URL: http://llvm.org/viewvc/llvm-project?rev=372772&view=rev
Log:
Extends the expansion of the LWZtoc pseduo op for AIX.

Differential Revision: https://reviews.llvm.org/D67853

Added:
    llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=372772&r1=372771&r2=372772&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Sep 24 11:04:51 2019
@@ -649,16 +649,19 @@ void PPCAsmPrinter::EmitInstruction(cons
     }
   }
   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(cons
     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;
   }

Added: llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll?rev=372772&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll Tue Sep 24 11:04:51 2019
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff \
+; RUN: -code-model=small < %s | FileCheck %s
+
+ at b = common global i32 0
+ at 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




More information about the llvm-commits mailing list