diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index 2caf4c99a1f..71bad1a5550 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -223,6 +223,9 @@ static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, static Reloc::Model getEffectiveRelocModel(const Triple &TT, Optional RM) { + assert((!TT.isOSAIX() || !RM.hasValue() || *RM == Reloc::PIC_) && + "Invalid relocation model for AIX."); + if (RM.hasValue()) return *RM; @@ -230,8 +233,8 @@ static Reloc::Model getEffectiveRelocModel(const Triple &TT, if (TT.isOSDarwin()) return Reloc::DynamicNoPIC; - // Big Endian PPC is PIC by default. - if (TT.getArch() == Triple::ppc64) + // Big Endian PPC and AIX default to PIC. + if (TT.getArch() == Triple::ppc64 || TT.isOSAIX()) return Reloc::PIC_; // Rest are static by default. diff --git a/test/tools/llc/aix-pic-setting.ll b/test/tools/llc/aix-pic-setting.ll new file mode 100644 index 00000000000..d5987f2adf2 --- /dev/null +++ b/test/tools/llc/aix-pic-setting.ll @@ -0,0 +1,8 @@ +; RUN: llc -mtriple=powerpc-ibm-aix < %s 2>&1 1>/dev/null | FileCheck --allow-empty %s +; RUN: llc -mtriple=powerpc-ibm-aix --relocation-model=pic < %s 2>&1 1>/dev/null | FileCheck --allow-empty %s +; RUN: llc -mtriple=powerpc64-ibm-aix --relocation-model=pic < %s 2>&1 1>/dev/null | FileCheck --allow-empty %s +; RUN: not llc -mtriple=powerpc-ibm-aix --relocation-model=static < %s 2>&1 | FileCheck --check-prefix=CHECK-NON-PIC %s +; RUN: not llc -mtriple=powerpc64-ibm-aix --relocation-model=ropi-rwpi < %s 2>&1 | FileCheck --check-prefix=CHECK-NON-PIC %s + +; CHECK-NOT: {{.}} +; CHECK-NON-PIC: invalid relocation model, AIX only supports PIC. diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index b35f8e853c3..0cf65139d5a 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -461,8 +461,17 @@ static int compileModule(char **argv, LLVMContext &Context) { Options.MCOptions.IASSearchPaths = IncludeDirs; Options.MCOptions.SplitDwarfFile = SplitDwarfFile; + // On AIX, setting the relocation model to anything other than PIC is considered + // a user error. + Optional RM = getRelocModel(); + if (TheTriple.isOSAIX() && RM.hasValue() && *RM != Reloc::PIC_) { + WithColor::error(errs(), argv[0]) + << "invalid relocation model, AIX only supports PIC.\n"; + return 1; + } + std::unique_ptr Target(TheTarget->createTargetMachine( - TheTriple.getTriple(), CPUStr, FeaturesStr, Options, getRelocModel(), + TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, getCodeModel(), OLvl)); assert(Target && "Could not allocate target machine!"); diff --git a/unittests/Target/PowerPC/AIXRelocModelTest.cpp b/unittests/Target/PowerPC/AIXRelocModelTest.cpp new file mode 100644 index 00000000000..fa5560910af --- /dev/null +++ b/unittests/Target/PowerPC/AIXRelocModelTest.cpp @@ -0,0 +1,39 @@ +#include "llvm/ADT/Triple.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +class AIXRelocModelTest : public ::testing::Test { +protected: + static void SetUpTestCase() { + LLVMInitializePowerPCTargetInfo(); + LLVMInitializePowerPCTarget(); + LLVMInitializePowerPCTargetMC(); + } +}; + +TEST_F(AIXRelocModelTest, DefalutToPIC) { + Triple TheTriple(/*ArchStr*/ "powerpc", /*VendorStr*/ "", /*OSStr*/ "aix"); + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, Error); + ASSERT_TRUE(TheTarget) << Error; + + TargetOptions Options; + // Create a TargetMachine for powerpc--aix target, and deliberately leave its + // relocation model unset. + std::unique_ptr Target(TheTarget->createTargetMachine( + /*TT*/ TheTriple.getTriple(), /*CPU*/ "", /*Features*/ "", + /*Options*/ Options, /*RM*/ None, /*CM*/ None, + /*OL*/ CodeGenOpt::Default)); + ASSERT_TRUE(Target) << "Could not allocate target machine!"; + + // The relocation model on AIX should be forced to PIC regardless. + EXPECT_TRUE(Target->getRelocationModel() == Reloc::PIC_); +} + +} // end of anonymous namespace diff --git a/unittests/Target/PowerPC/CMakeLists.txt b/unittests/Target/PowerPC/CMakeLists.txt new file mode 100644 index 00000000000..6927fc4c7c1 --- /dev/null +++ b/unittests/Target/PowerPC/CMakeLists.txt @@ -0,0 +1,21 @@ +include_directories( + ${CMAKE_SOURCE_DIR}/lib/Target/PowerPC + ${CMAKE_BINARY_DIR}/lib/Target/PowerPC + ) + +set(LLVM_LINK_COMPONENTS + Analysis + CodeGen + Core + MC + MIRParser + Support + Target + PowerPCCodeGen + PowerPCDesc + PowerPCInfo + ) + +add_llvm_unittest(PowerPCTests + AIXRelocModelTest.cpp + )