diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp --- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp +++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp @@ -2083,6 +2083,12 @@ if (GV->isThreadLocal()) return 0; + // If the global has the toc-data attribute then fallback to DAG-ISEL. + if (TM.getTargetTriple().isOSAIX()) + if (const GlobalVariable *Var = dyn_cast_or_null(GV)) + if (Var->hasAttribute("toc-data")) + return false; + PPCFuncInfo->setUsesTOCBasePtr(); // For small code model, generate a simple TOC load. if (CModel == CodeModel::Small) diff --git a/llvm/test/CodeGen/PowerPC/toc-data.ll b/llvm/test/CodeGen/PowerPC/toc-data.ll --- a/llvm/test/CodeGen/PowerPC/toc-data.ll +++ b/llvm/test/CodeGen/PowerPC/toc-data.ll @@ -1,11 +1,17 @@ -; REQUIRES: asserts ; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s \ -; RUN: -stop-before=ppc-ctr-loops-verify | FileCheck %s --check-prefix CHECK32 +; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK32 ; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s \ -; RUN: -stop-before=ppc-ctr-loops-verify | FileCheck %s --check-prefix CHECK64 +; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK64 ; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST32 ; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST64 +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s \ +; RUN: -stop-before=ppc-vsx-copy -O0 | FileCheck %s --check-prefix CHECK32 +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s \ +; RUN: -stop-before=ppc-vsx-copy -O0 | FileCheck %s --check-prefix CHECK64-NOOPT +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST32 +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST64 + @i = dso_local global i32 0, align 4 #0 @d = dso_local local_unnamed_addr global double 3.141590e+00, align 8 @f = dso_local local_unnamed_addr global float 0x4005BE76C0000000, align 4 #0 @@ -29,6 +35,11 @@ ; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 @i, $x2 ; CHECK64-NEXT: STW8 %{{[0-9]+}}, 0, killed %[[SCRATCH]] :: (store (s32) into @i) +; CHECK64-NOOPT: name: write_int +; CHECK64-NOOPT: %[[SUBREG:[0-9]+]]:gprc = COPY %{{[0-9]}}.sub_32 +; CHECK64-NOOPT: %[[ADDR:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 @i, $x2 :: (load (s64) from got) +; CHECK64-NOOPT: STW %[[SUBREG]], 0, killed %[[ADDR]] :: (store (s32) into @i) + ; TEST64: .write_int: ; TEST64: la 4, i[TD](2) ; TEST64-NEXT: stw 3, 0(4) @@ -48,7 +59,12 @@ ; TEST32-NEXT: lwz 4, 4(4) ; CHECK64: name: read_ll -; CHECK64: LDtoc @ll, $x2 :: (load (s64) from got) +; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @ll, $x2 :: (load (s64) from got) +; CHECK64: LD 0, killed %[[SCRATCH]] + +; CHECK64-NOOPT: name: read_ll +; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @ll, $x2 +; CHECK64-NOOPT: LD 0, %[[SCRATCH]] ; TEST64: .read_ll: ; TEST64: ld 3, L..C0(2) @@ -72,6 +88,10 @@ ; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 @f, $x2 ; CHECK64: %{{[0-9]+}}:f4rc = LFS 0, killed %[[SCRATCH]] :: (dereferenceable load (s32) from @f) +; CHECK64-NOOPT: name: read_float +; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 @f, $x2 +; CHECK64-NOOPT: %{{[0-9]+}}:f4rc = LFS 0, killed %[[SCRATCH]] + ; TEST64: .read_float: ; TEST64: la 3, f[TD](2) ; TEST64-NEXT: lfs 1, 0(3) @@ -90,7 +110,12 @@ ; TEST32-NEXT: stfd 1, 0(3) ; CHECK64: name: write_double -; CHECK64: LDtoc @d, $x2 :: (load (s64) from got) +; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @d, $x2 :: (load (s64) from got) +; CHECK64: STFD %{{[0-9]+}}, 0, killed %[[SCRATCH]] + +; CHECK64-NOOPT: name: write_double +; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @d, $x2 +; CHECK64-NOOPT STFD %{{[0-9]+}}, 0 %[[SCRATCH]] ; TEST64: .write_double ; TEST64: ld 3, L..C1(2) @@ -112,6 +137,10 @@ ; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc = ADDItoc8 @i, $x2 ; CHECK64-NEXT: $x3 = COPY %[[SCRATCH]] +; CHECK64-NOOPT: name: addr +; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc = ADDItoc8 @i, $x2 +; CHECK64-NOOPT: $x3 = COPY %[[SCRATCH]] + ; TEST64: .addr ; TEST64: la 3, i[TD](2)