diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -318,6 +318,17 @@ SubtargetFeature<"privileged", "HasPrivileged", "true", "Add privileged instructions">; +// Specifies that local-exec TLS accesses in any function with this target +// attribute should use the optimized TOC-free sequence (where the offset is an +// immediate off of R13 for which the linker might add fix-up code if the +// immediate is too large). +// Clearly, this isn't really a feature of the subtarget, but is used as a +// convenient way to affect code generation for individual functions. +def FeatureAIXLocalExecTLS : + SubtargetFeature<"aix-small-local-exec-tls", "HasAIXSmallLocalExecTLS", "true", + "Produce a TOC-free local-exec TLS sequence for this function " + "for 64-bit AIX">; + def FeaturePredictableSelectIsExpensive : SubtargetFeature<"predictable-select-expensive", "PredictableSelectIsExpensive", diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp --- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -123,6 +123,11 @@ // Determine endianness. IsLittleEndian = TM.isLittleEndian(); + + if (HasAIXSmallLocalExecTLS && (!TargetTriple.isOSAIX() || !IsPPC64)) + report_fatal_error( + "The aix-small-local-exec-tls attribute is only supported on AIX in " + "64-bit mode.\n", false); } bool PPCSubtarget::enableMachineScheduler() const { return true; } diff --git a/llvm/test/CodeGen/PowerPC/check-aix-small-local-exec-tls-opt-IRattribute.ll b/llvm/test/CodeGen/PowerPC/check-aix-small-local-exec-tls-opt-IRattribute.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/check-aix-small-local-exec-tls-opt-IRattribute.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -ppc-asm-full-reg-names \ +; RUN: < %s | FileCheck %s +; RUN: not llc -mtriple powerpc-ibm-aix-xcoff -ppc-asm-full-reg-names \ +; RUN: < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED +; RUN: not llc -mtriple powerpc64le-unknown-linux-gnu -ppc-asm-full-reg-names \ +; RUN: < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED + +define dso_local signext i32 @testWithIRAttr() #0 { +entry: + ret i32 0 +} +; Check that the aix-small-local-exec-tls attribute is not supported on Linux and AIX (32-bit). +; CHECK-NOT-SUPPORTED: The aix-small-local-exec-tls attribute is only supported on AIX in 64-bit mode. + +; Make sure that the test was actually compiled successfully after using the +; aix-small-local-exec-tls attribute. +; CHECK-LABEL: testWithIRAttr: +; CHECK: li r3, 0 +; CHECK-NEXT: blr + + +attributes #0 = { "target-features"="+aix-small-local-exec-tls" } + diff --git a/llvm/test/CodeGen/PowerPC/check-aix-small-local-exec-tls-opt.ll b/llvm/test/CodeGen/PowerPC/check-aix-small-local-exec-tls-opt.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/check-aix-small-local-exec-tls-opt.ll @@ -0,0 +1,22 @@ +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -mattr=+aix-small-local-exec-tls \ +; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s +; RUN: not llc -mtriple powerpc-ibm-aix-xcoff -mattr=+aix-small-local-exec-tls \ +; RUN: -ppc-asm-full-reg-names < %s 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED +; RUN: not llc -mtriple powerpc64le-unknown-linux-gnu -mattr=+aix-small-local-exec-tls \ +; RUN: -ppc-asm-full-reg-names < %s 2>&1 | \ +; RUN: FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED + +define dso_local signext i32 @testNoIRAttr() { +entry: + ret i32 0 +} + +; Check that the aix-small-local-exec-tls attribute is not supported on Linux and AIX (32-bit). +; CHECK-NOT-SUPPORTED: The aix-small-local-exec-tls attribute is only supported on AIX in 64-bit mode. + +; Make sure that the test was actually compiled successfully after using the +; aix-small-local-exec-tls attribute. +; CHECK-LABEL: testNoIRAttr: +; CHECK: li r3, 0 +; CHECK-NEXT: blr