[llvm] r375113 - [AIX] TOC pseudo expansion for 64bit large + 64bit small + 32bit large models
Xiangling Liao via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 17 06:20:26 PDT 2019
Author: xiangling_liao
Date: Thu Oct 17 06:20:25 2019
New Revision: 375113
URL: http://llvm.org/viewvc/llvm-project?rev=375113&view=rev
Log:
[AIX] TOC pseudo expansion for 64bit large + 64bit small + 32bit large models
This patch provides support for peudo ops including ADDIStocHA8, ADDIStocHA, LWZtocL,
LDtoc, LDtocL for AIX, lowering them from MIR to assembly.
Differential Revision: https://reviews.llvm.org/D68341
Added:
llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll
Modified:
llvm/trunk/include/llvm/MC/MCExpr.h
llvm/trunk/lib/MC/MCExpr.cpp
llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll
Modified: llvm/trunk/include/llvm/MC/MCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCExpr.h?rev=375113&r1=375112&r2=375113&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCExpr.h (original)
+++ llvm/trunk/include/llvm/MC/MCExpr.h Thu Oct 17 06:20:25 2019
@@ -235,6 +235,8 @@ public:
VK_PPC_TOC_LO, // symbol at toc@l
VK_PPC_TOC_HI, // symbol at toc@h
VK_PPC_TOC_HA, // symbol at toc@ha
+ VK_PPC_U, // symbol at u
+ VK_PPC_L, // symbol at l
VK_PPC_DTPMOD, // symbol at dtpmod
VK_PPC_TPREL_LO, // symbol at tprel@l
VK_PPC_TPREL_HI, // symbol at tprel@h
Modified: llvm/trunk/lib/MC/MCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=375113&r1=375112&r2=375113&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCExpr.cpp (original)
+++ llvm/trunk/lib/MC/MCExpr.cpp Thu Oct 17 06:20:25 2019
@@ -259,6 +259,8 @@ StringRef MCSymbolRefExpr::getVariantKin
case VK_PPC_TOC_LO: return "toc at l";
case VK_PPC_TOC_HI: return "toc at h";
case VK_PPC_TOC_HA: return "toc at ha";
+ case VK_PPC_U: return "u";
+ case VK_PPC_L: return "l";
case VK_PPC_DTPMOD: return "dtpmod";
case VK_PPC_TPREL_LO: return "tprel at l";
case VK_PPC_TPREL_HI: return "tprel at h";
@@ -373,6 +375,8 @@ MCSymbolRefExpr::getVariantKindForName(S
.Case("toc at l", VK_PPC_TOC_LO)
.Case("toc at h", VK_PPC_TOC_HI)
.Case("toc at ha", VK_PPC_TOC_HA)
+ .Case("u", VK_PPC_U)
+ .Case("l", VK_PPC_L)
.Case("tls", VK_PPC_TLS)
.Case("dtpmod", VK_PPC_DTPMOD)
.Case("tprel at l", VK_PPC_TPREL_LO)
Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp?rev=375113&r1=375112&r2=375113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp Thu Oct 17 06:20:25 2019
@@ -66,6 +66,31 @@ void PPCInstPrinter::printRegName(raw_os
void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
StringRef Annot, const MCSubtargetInfo &STI) {
+ // Customize printing of the addis instruction on AIX. When an operand is a
+ // symbol reference, the instruction syntax is changed to look like a load
+ // operation, i.e:
+ // Transform: addis $rD, $rA, $src --> addis $rD, $src($rA).
+ if (TT.isOSAIX() &&
+ (MI->getOpcode() == PPC::ADDIS8 || MI->getOpcode() == PPC::ADDIS) &&
+ MI->getOperand(2).isExpr()) {
+ assert((MI->getOperand(0).isReg() && MI->getOperand(1).isReg()) &&
+ "The first and the second operand of an addis instruction"
+ " should be registers.");
+
+ assert(isa<MCSymbolRefExpr>(MI->getOperand(2).getExpr()) &&
+ "The third operand of an addis instruction should be a symbol "
+ "reference expression if it is an expression at all.");
+
+ O << "\taddis ";
+ printOperand(MI, 0, O);
+ O << ", ";
+ printOperand(MI, 2, O);
+ O << "(";
+ printOperand(MI, 1, O);
+ O << ")";
+ return;
+ }
+
// Check for slwi/srwi mnemonics.
if (MI->getOpcode() == PPC::RLWINM) {
unsigned char SH = MI->getOperand(2).getImm();
Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=375113&r1=375112&r2=375113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Oct 17 06:20:25 2019
@@ -536,6 +536,8 @@ static MCSymbol *getMCSymbolForTOCPseudo
void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst TmpInst;
const bool IsDarwin = TM.getTargetTriple().isOSDarwin();
+ const bool IsPPC64 = Subtarget->isPPC64();
+ const bool IsAIX = Subtarget->isAIXABI();
const Module *M = MF->getFunction().getParent();
PICLevel::Level PL = M->getPICLevel();
@@ -683,11 +685,10 @@ void PPCAsmPrinter::EmitInstruction(cons
const MachineOperand &MO = MI->getOperand(1);
assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
- "Unexpected operand type for LWZtoc pseudo.");
+ "Invalid operand for LWZtoc.");
// Map the operand to its corresponding MCSymbol.
const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
- const bool IsAIX = TM.getTargetTriple().isOSAIX();
// Create a reference to the GOT entry for the symbol. The GOT entry will be
// synthesized later.
@@ -700,7 +701,7 @@ void PPCAsmPrinter::EmitInstruction(cons
return;
}
- // Otherwise use the TOC. 'TOCEntry' is a label used to reference the
+ // Otherwise, use the TOC. 'TOCEntry' is a label 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);
@@ -732,6 +733,8 @@ void PPCAsmPrinter::EmitInstruction(cons
case PPC::LDtocCPT:
case PPC::LDtocBA:
case PPC::LDtoc: {
+ assert(!IsDarwin && "TOC is an ELF/XCOFF construct");
+
// Transform %x3 = LDtoc @min1, %x2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
@@ -748,15 +751,77 @@ void PPCAsmPrinter::EmitInstruction(cons
MCSymbol *TOCEntry =
lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO, *this));
+ const MCSymbolRefExpr::VariantKind VK =
+ IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC;
const MCExpr *Exp =
- MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
- OutContext);
+ MCSymbolRefExpr::create(TOCEntry, VK, OutContext);
TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
EmitToStreamer(*OutStreamer, TmpInst);
return;
}
+ case PPC::ADDIStocHA: {
+ assert((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) &&
+ "This pseudo should only be selected for 32-bit large code model on"
+ " AIX.");
+
+ // Transform %rd = ADDIStocHA %rA, @sym(%r2)
+ LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
+
+ // Change the opcode to ADDIS.
+ TmpInst.setOpcode(PPC::ADDIS);
+
+ const MachineOperand &MO = MI->getOperand(2);
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
+ "Invalid operand for ADDIStocHA.");
+
+ // Map the machine operand to its corresponding MCSymbol.
+ MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
+
+ // Always use TOC on AIX. Map the global address operand to be a reference
+ // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
+ // reference the storage allocated in the TOC which contains the address of
+ // 'MOSymbol'.
+ MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
+ const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
+ MCSymbolRefExpr::VK_PPC_U,
+ OutContext);
+ TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
+ EmitToStreamer(*OutStreamer, TmpInst);
+ return;
+ }
+ case PPC::LWZtocL: {
+ assert(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large &&
+ "This pseudo should only be selected for 32-bit large code model on"
+ " AIX.");
+
+ // Transform %rd = LWZtocL @sym, %rs.
+ LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
+ // Change the opcode to lwz.
+ TmpInst.setOpcode(PPC::LWZ);
+
+ const MachineOperand &MO = MI->getOperand(1);
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
+ "Invalid operand for LWZtocL.");
+
+ // Map the machine operand to its corresponding MCSymbol.
+ MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
+
+ // Always use TOC on AIX. Map the global address operand to be a reference
+ // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
+ // reference the storage allocated in the TOC which contains the address of
+ // 'MOSymbol'.
+ MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
+ const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
+ MCSymbolRefExpr::VK_PPC_L,
+ OutContext);
+ TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
+ EmitToStreamer(*OutStreamer, TmpInst);
+ return;
+ }
case PPC::ADDIStocHA8: {
+ assert(!IsDarwin && "TOC is an ELF/XCOFF construct");
+
// Transform %xd = ADDIStocHA8 %x2, @sym
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
@@ -778,9 +843,11 @@ void PPCAsmPrinter::EmitInstruction(cons
(MO.isCPI() && TM.getCodeModel() == CodeModel::Large))
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
+ const MCSymbolRefExpr::VariantKind VK =
+ IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA;
+
const MCExpr *Exp =
- MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
- OutContext);
+ MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
if (!MO.isJTI() && MO.getOffset())
Exp = MCBinaryExpr::createAdd(Exp,
@@ -793,6 +860,8 @@ void PPCAsmPrinter::EmitInstruction(cons
return;
}
case PPC::LDtocL: {
+ assert(!IsDarwin && "TOC is an ELF/XCOFF construct");
+
// Transform %xd = LDtocL @sym, %xs
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
@@ -817,9 +886,10 @@ void PPCAsmPrinter::EmitInstruction(cons
if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large)
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
+ const MCSymbolRefExpr::VariantKind VK =
+ IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO;
const MCExpr *Exp =
- MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
- OutContext);
+ MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
EmitToStreamer(*OutStreamer, TmpInst);
return;
@@ -855,8 +925,8 @@ void PPCAsmPrinter::EmitInstruction(cons
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymGotTprel =
- MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
- OutContext);
+ MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
+ OutContext);
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(1).getReg())
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=375113&r1=375112&r2=375113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Oct 17 06:20:25 2019
@@ -328,6 +328,7 @@ bool PPCInstrInfo::isReallyTriviallyReMa
case PPC::LIS:
case PPC::LIS8:
case PPC::QVGPCI:
+ case PPC::ADDIStocHA:
case PPC::ADDIStocHA8:
case PPC::ADDItocL:
case PPC::LOAD_STACK_GUARD:
Modified: 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=375113&r1=375112&r2=375113&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll Thu Oct 17 06:20:25 2019
@@ -1,21 +1,45 @@
-; RUN: llc -mtriple powerpc-ibm-aix-xcoff \
-; RUN: -code-model=small < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff \
+; RUN: -code-model=small < %s | FileCheck %s --check-prefixes=CHECK,SMALL
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff \
+; RUN: -code-model=large < %s | FileCheck %s --check-prefixes=CHECK,LARGE
- at b = common global i32 0
@a = common global i32 0
-define void @test() {
- %1 = load i32, i32* @b
- store i32 %1, i32* @a
+define i32 @test_load() {
+entry:
+ %0 = load i32, i32* @a
+ ret i32 %0
+}
+
+; SMALL-LABEL: .test_load:{{$}}
+; SMALL: lwz [[REG1:[0-9]+]], LC0(2)
+; SMALL: lwz [[REG2:[0-9]+]], 0([[REG1]])
+; SMALL: blr
+
+; LARGE-LABEL: .test_load:{{$}}
+; LARGE: addis [[REG1:[0-9]+]], LC0 at u(2)
+; LARGE: lwz [[REG2:[0-9]+]], LC0 at l([[REG1]])
+; LARGE: lwz [[REG3:[0-9]+]], 0([[REG2]])
+; LARGE: blr
+
+ at b = common global i32 0
+
+define void @test_store(i32 %0) {
+ store i32 %0, i32* @b
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
+; SMALL-LABEL: .test_store:{{$}}
+; SMALL: lwz [[REG1:[0-9]+]], LC1(2)
+; SMALL: stw [[REG2:[0-9]+]], 0([[REG1]])
+; SMALL: blr
+
+; LARGE-LABEL: .test_store:{{$}}
+; LARGE: addis [[REG1:[0-9]+]], LC1 at u(2)
+; LARGE: lwz [[REG2:[0-9]+]], LC1 at l([[REG1]])
+; LARGE: stw [[REG3:[0-9]+]], 0([[REG2]])
+; LARGE: blr
; TODO Update test when TOC-entry emission lands.
; CHECK-NOT: .tc
Added: llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll?rev=375113&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll Thu Oct 17 06:20:25 2019
@@ -0,0 +1,45 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff \
+; RUN: -code-model=small < %s | FileCheck %s --check-prefixes=CHECK,SMALL
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff \
+; RUN: -code-model=large < %s | FileCheck %s --check-prefixes=CHECK,LARGE
+
+ at a = common global i32 0
+
+define zeroext i32 @test_load() {
+entry:
+ %0 = load i32, i32* @a
+ ret i32 %0
+}
+
+; SMALL-LABEL: .test_load:{{$}}
+; SMALL: ld [[REG1:[0-9]+]], LC0(2)
+; SMALL: lwz [[REG2:[0-9]+]], 0([[REG1]])
+; SMALL: blr
+
+; LARGE-LABEL: .test_load:{{$}}
+; LARGE: addis [[REG1:[0-9]+]], LC0 at u(2)
+; LARGE: ld [[REG2:[0-9]+]], LC0 at l([[REG1]])
+; LARGE: lwz [[REG3:[0-9]+]], 0([[REG2]])
+; LARGE: blr
+
+ at b = common global i32 0
+
+define void @test_store(i32 zeroext %0) {
+ store i32 %0, i32* @b
+ ret void
+}
+
+; SMALL-LABEL: .test_store:{{$}}
+; SMALL: ld [[REG1:[0-9]+]], LC1(2)
+; SMALL: stw [[REG2:[0-9]+]], 0([[REG1]])
+; SMALL: blr
+
+; LARGE-LABEL: .test_store:{{$}}
+; LARGE: addis [[REG1:[0-9]+]], LC1 at u(2)
+; LARGE: ld [[REG2:[0-9]+]], LC1 at l([[REG1]])
+; LARGE: stw [[REG3:[0-9]+]], 0([[REG2]])
+; LARGE: blr
+
+; TODO Update test when TOC-entry emission lands.
+; CHECK-NOT: .tc
More information about the llvm-commits
mailing list