[llvm] 2b50ce1 - [PowerPC][AIX] Enable the default AltiVec ABI on AIX

Zarko Todorovski via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 5 09:46:51 PST 2021


Author: Zarko Todorovski
Date: 2021-03-05T12:46:27-05:00
New Revision: 2b50ce152417286e0091a1683482457473d4d7a8

URL: https://github.com/llvm/llvm-project/commit/2b50ce152417286e0091a1683482457473d4d7a8
DIFF: https://github.com/llvm/llvm-project/commit/2b50ce152417286e0091a1683482457473d4d7a8.diff

LOG: [PowerPC][AIX] Enable the default AltiVec ABI on AIX

This patch adds support for the default AltiVec ABI for AIX.

Vector registers 20 through 31 are marked as reserved and cannot
be used in the default ABI. This patch adds handling for this case
and also remove the default AltiVec ABI errors.

Reviewed By: sfertile

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

Added: 
    llvm/test/CodeGen/PowerPC/aix-csr-vector.ll
    llvm/test/CodeGen/PowerPC/aix-inlineasm-reserved-reg-dflt-warn.ll

Modified: 
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp

Removed: 
    llvm/test/CodeGen/PowerPC/aix-vec-abi.ll


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 460ddd24490e..9ecf61d2175e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -6307,11 +6307,6 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
   const Align PtrAlign = IsPPC64 ? Align(8) : Align(4);
   const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
 
-  if (ValVT.isVector() && !State.getMachineFunction()
-                               .getTarget()
-                               .Options.EnableAIXExtendedAltivecABI)
-    report_fatal_error("the default Altivec AIX ABI is not yet supported");
-
   if (ValVT == MVT::f128)
     report_fatal_error("f128 is unimplemented on AIX.");
 
@@ -15327,6 +15322,15 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
     R.first = PPC::CR0;
     R.second = &PPC::CRRCRegClass;
   }
+  // FIXME: This warning should ideally be emitted in the front end.
+  const auto &TM = getTargetMachine();
+  if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
+    if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
+         (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
+        (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
+      errs() << "warning: vector registers 20 to 32 are reserved in the "
+                "default AIX AltiVec ABI and cannot be used\n";
+  }
 
   return R;
 }

diff  --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 76b1cfe40ad2..171bb77a55a8 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -156,10 +156,6 @@ PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
 const MCPhysReg*
 PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
   const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
-  if (Subtarget.isAIXABI() &&
-      (Subtarget.hasAltivec() && !TM.getAIXExtendedAltivecABI()))
-    report_fatal_error("the default AIX Altivec ABI is not yet "
-                       "supported.");
   if (MF->getFunction().getCallingConv() == CallingConv::AnyReg) {
     if (!TM.isPPC64() && Subtarget.isAIXABI())
       report_fatal_error("AnyReg unimplemented on 32-bit AIX.");
@@ -200,15 +196,18 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
   }
   // Standard calling convention CSRs.
   if (TM.isPPC64()) {
-    if (Subtarget.hasAltivec())
+    if (Subtarget.hasAltivec() &&
+        (!Subtarget.isAIXABI() || TM.getAIXExtendedAltivecABI())) {
       return SaveR2 ? CSR_PPC64_R2_Altivec_SaveList
                     : CSR_PPC64_Altivec_SaveList;
+    }
     return SaveR2 ? CSR_PPC64_R2_SaveList : CSR_PPC64_SaveList;
   }
   // 32-bit targets.
   if (Subtarget.isAIXABI()) {
     if (Subtarget.hasAltivec())
-      return CSR_AIX32_Altivec_SaveList;
+      return TM.getAIXExtendedAltivecABI() ? CSR_AIX32_Altivec_SaveList
+                                           : CSR_AIX32_SaveList;
     return CSR_AIX32_SaveList;
   }
   if (Subtarget.hasAltivec())
@@ -231,10 +230,13 @@ PPCRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
   }
 
   if (Subtarget.isAIXABI()) {
-    return TM.isPPC64() ? (Subtarget.hasAltivec() ? CSR_PPC64_Altivec_RegMask
-                                                  : CSR_PPC64_RegMask)
-                        : (Subtarget.hasAltivec() ? CSR_AIX32_Altivec_RegMask
-                                                  : CSR_AIX32_RegMask);
+    return TM.isPPC64()
+               ? ((Subtarget.hasAltivec() && TM.getAIXExtendedAltivecABI())
+                      ? CSR_PPC64_Altivec_RegMask
+                      : CSR_PPC64_RegMask)
+               : ((Subtarget.hasAltivec() && TM.getAIXExtendedAltivecABI())
+                      ? CSR_AIX32_Altivec_RegMask
+                      : CSR_AIX32_RegMask);
   }
 
   if (CC == CallingConv::Cold) {
@@ -335,6 +337,17 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
          IE = PPC::VRRCRegClass.end(); I != IE; ++I)
       markSuperRegs(Reserved, *I);
 
+  if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
+      !TM.getAIXExtendedAltivecABI()) {
+    //  In the AIX default Altivec ABI, vector registers VR20-VR31 are reserved
+    //  and cannot be used.
+    for (auto Reg : CSR_Altivec_SaveList) {
+      if (Reg == 0)
+        break;
+      markSuperRegs(Reserved, Reg);
+    }
+  }
+
   assert(checkAllSuperRegsMarked(Reserved));
   return Reserved;
 }
@@ -426,15 +439,28 @@ unsigned PPCRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
     unsigned FP = TFI->hasFP(MF) ? 1 : 0;
     return 32 - FP - DefaultSafety;
   }
-  case PPC::F8RCRegClassID:
   case PPC::F4RCRegClassID:
-  case PPC::VRRCRegClassID:
-  case PPC::VFRCRegClassID:
+  case PPC::F8RCRegClassID:
   case PPC::VSLRCRegClassID:
     return 32 - DefaultSafety;
-  case PPC::VSRCRegClassID:
+  case PPC::VFRCRegClassID:
+  case PPC::VRRCRegClassID: {
+    const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
+    // Vector registers VR20-VR31 are reserved and cannot be used in the default
+    // Altivec ABI on AIX.
+    if (!TM.getAIXExtendedAltivecABI() && Subtarget.isAIXABI())
+      return 20 - DefaultSafety;
+  }
+    return 32 - DefaultSafety;
   case PPC::VSFRCRegClassID:
   case PPC::VSSRCRegClassID:
+  case PPC::VSRCRegClassID: {
+    const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
+    if (!TM.getAIXExtendedAltivecABI() && Subtarget.isAIXABI())
+      // Vector registers VR20-VR31 are reserved and cannot be used in the
+      // default Altivec ABI on AIX.
+      return 52 - DefaultSafety;
+  }
     return 64 - DefaultSafety;
   case PPC::CRRCRegClassID:
     return 8 - DefaultSafety;

diff  --git a/llvm/test/CodeGen/PowerPC/aix-csr-vector.ll b/llvm/test/CodeGen/PowerPC/aix-csr-vector.ll
new file mode 100644
index 000000000000..05b8d31bb6a5
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-csr-vector.ll
@@ -0,0 +1,201 @@
+; RUN: llc -mtriple=powerpc-unknown-aix-xcoff -verify-machineinstrs -mcpu=pwr7 \
+; RUN:     -mattr=+altivec -stop-after=prologepilog < %s | \
+; RUN:   FileCheck --check-prefix=MIR32 %s
+
+; RUN: llc -mtriple=powerpc-unknown-aix-xcoff -verify-machineinstrs \
+; RUN:     -mcpu=pwr7 -mattr=+altivec < %s | \
+; RUN:   FileCheck --check-prefix=ASM32 %s
+
+; RUN: llc -mtriple=powerpc64-unknown-aix-xcoff -verify-machineinstrs \
+; RUN:     -mcpu=pwr7 -mattr=+altivec -stop-after=prologepilog < %s | \
+; RUN:   FileCheck --check-prefix=MIR64 %s
+
+; RUN: llc -mtriple=powerpc64-unknown-aix-xcoff -verify-machineinstrs \
+; RUN:     -mcpu=pwr7 -mattr=+altivec < %s | \
+; RUN:   FileCheck --check-prefix=ASM64 %s
+
+define dso_local void @vec_regs() {
+  entry:
+    call void asm sideeffect "", "~{v13},~{v20},~{v26},~{v31}"()
+      ret void
+}
+
+; MIR32-LABEL:   name:            vec_regs
+
+; MIR32:         fixedStack:      []
+; MIR32-NOT:     STXVD2X killed $v20
+; MIR32-NOT:     STXVD2X killed $v26
+; MIR32-NOT:     STXVD2X killed $v31
+; MIR32-LABEL:   INLINEASM
+; MIR32-NOT:     $v20 = LXVD2X
+; MIR32-NOT:     $v26 = LXVD2X
+; MIR32-NOT:     $v31 = LXVD2X
+; MIR32:         BLR implicit $lr, implicit $rm
+
+; MIR64-LABEL:   name:            vec_regs
+
+; MIR64:         fixedStack:      []
+; MIR64-NOT:     STXVD2X killed $v20
+; MIR64-NOT:     STXVD2X killed $v26
+; MIR64-NOT:     STXVD2X killed $v31
+; MIR64-LABEL:   INLINEASM
+; MIR64-NOT:     $v20 = LXVD2X
+; MIR64-NOT:     $v26 = LXVD2X
+; MIR64-NOT:     $v31 = LXVD2X
+; MIR64:         BLR8 implicit $lr8, implicit $rm
+
+; ASM32-LABEL:   .vec_regs:
+
+; ASM32-NOT:     20
+; ASM32-NOT:     26
+; ASM32-NOT:     31
+; ASM32-DAG:     #APP
+; ASM32-DAG:     #NO_APP
+; ASM32:         blr
+
+; ASM64-LABEL:   .vec_regs:
+
+; ASM64-NOT:     20
+; ASM64-NOT:     26
+; ASM64-NOT:     31
+; ASM64-DAG:     #APP
+; ASM64-DAG:     #NO_APP
+; ASM64:         blr
+
+define dso_local void @fprs_gprs_vecregs() {
+    call void asm sideeffect "", "~{r14},~{r25},~{r31},~{f14},~{f21},~{f31},~{v20},~{v26},~{v31}"()
+      ret void
+}
+
+; MIR32-LABEL:   name:            fprs_gprs_vecregs
+
+; MIR32:         fixedStack:
+
+; MIR32:         liveins: $r14, $r25, $r31, $f14, $f21, $f31
+
+; MIR32-NOT:     STXVD2X killed $v20
+; MIR32-NOT:     STXVD2X killed $v26
+; MIR32-NOT:     STXVD2X killed $v31
+; MIR32-DAG:     STW killed $r14, -216, $r1 :: (store 4 into %fixed-stack.5, align 8)
+; MIR32-DAG:     STW killed $r25, -172, $r1 :: (store 4 into %fixed-stack.4)
+; MIR32-DAG:     STW killed $r31, -148, $r1 :: (store 4 into %fixed-stack.3)
+; MIR32-DAG:     STFD killed $f14, -144, $r1 :: (store 8 into %fixed-stack.2, align 16)
+; MIR32-DAG:     STFD killed $f21, -88, $r1 :: (store 8 into %fixed-stack.1)
+; MIR32-DAG:     STFD killed $f31, -8, $r1 :: (store 8 into %fixed-stack.0)
+
+; MIR32-LABEL:   INLINEASM
+
+; MIR32-NOT:     $v20 = LXVD2X
+; MIR32-NOT:     $v26 = LXVD2X
+; MIR32-NOT:     $v31 = LXVD2X
+; MIR32-DAG:     $r14 = LWZ -216, $r1 :: (load 4 from %fixed-stack.5, align 8)
+; MIR32-DAG:     $r25 = LWZ -172, $r1 :: (load 4 from %fixed-stack.4)
+; MIR32-DAG:     $r31 = LWZ -148, $r1 :: (load 4 from %fixed-stack.3)
+; MIR32-DAG:     $f14 = LFD -144, $r1 :: (load 8 from %fixed-stack.2, align 16)
+; MIR32-DAG:     $f21 = LFD -88, $r1 :: (load 8 from %fixed-stack.1)
+; MIR32-DAG:     $f31 = LFD -8, $r1 :: (load 8 from %fixed-stack.0)
+; MIR32-DAG:     BLR implicit $lr, implicit $rm
+
+; MIR64-LABEL:   name:            fprs_gprs_vecregs
+
+; MIR64:         fixedStack:
+
+; MIR64:         liveins: $x14, $x25, $x31, $f14, $f21, $f31
+
+; MIR64-NOT:     STXVD2X killed $v20
+; MIR64-NOT:     STXVD2X killed $v26
+; MIR64-NOT:     STXVD2X killed $v31
+; MIR64-DAG:     STD killed $x14, -288, $x1 :: (store 8 into %fixed-stack.5, align 16)
+; MIR64-DAG:     STD killed $x25, -200, $x1 :: (store 8 into %fixed-stack.4)
+; MIR64-DAG:     STD killed $x31, -152, $x1 :: (store 8 into %fixed-stack.3)
+; MIR64-DAG:     STFD killed $f14, -144, $x1 :: (store 8 into %fixed-stack.2, align 16)
+; MIR64-DAG:     STFD killed $f21, -88, $x1 :: (store 8 into %fixed-stack.1)
+; MIR64-DAG:     STFD killed $f31, -8, $x1 :: (store 8 into %fixed-stack.0)
+
+; MIR64-LABEL:   INLINEASM
+
+; MIR64-NOT:     $v20 = LXVD2X
+; MIR64-NOT:     $v26 = LXVD2X
+; MIR64-NOT:     $v31 = LXVD2X
+; MIR64-DAG:     $x14 = LD -288, $x1 :: (load 8 from %fixed-stack.5, align 16)
+; MIR64-DAG:     $x25 = LD -200, $x1 :: (load 8 from %fixed-stack.4)
+; MIR64-DAG:     $x31 = LD -152, $x1 :: (load 8 from %fixed-stack.3)
+; MIR64-DAG:     $f14 = LFD -144, $x1 :: (load 8 from %fixed-stack.2, align 16)
+; MIR64-DAG:     $f21 = LFD -88, $x1 :: (load 8 from %fixed-stack.1)
+; MIR64-DAG:     $f31 = LFD -8, $x1 :: (load 8 from %fixed-stack.0)
+; MIR64:         BLR8 implicit $lr8, implicit $rm
+
+;; We don't have -ppc-full-reg-names on AIX so can't reliably check-not for
+;; only vector registers numbers in this case.
+
+; ASM32-LABEL:   .fprs_gprs_vecregs:
+
+; ASM32-DAG:     stw 14, -216(1)                         # 4-byte Folded Spill
+; ASM32-DAG:     stw 25, -172(1)                         # 4-byte Folded Spill
+; ASM32-DAG:     stw 31, -148(1)                         # 4-byte Folded Spill
+; ASM32-DAG:     stfd 14, -144(1)                        # 8-byte Folded Spill
+; ASM32-DAG:     stfd 21, -88(1)                         # 8-byte Folded Spill
+; ASM32-DAG:     stfd 31, -8(1)                          # 8-byte Folded Spill
+; ASM32-DAG:     #APP
+; ASM32-DAG:     #NO_APP
+; ASM32-DAG:     lfd 31, -8(1)                           # 8-byte Folded Reload
+; ASM32-DAG:     lfd 21, -88(1)                          # 8-byte Folded Reload
+; ASM32-DAG:     lfd 14, -144(1)                         # 8-byte Folded Reload
+; ASM32-DAG:     lwz 31, -148(1)                         # 4-byte Folded Reload
+; ASM32-DAG:     lwz 25, -172(1)                         # 4-byte Folded Reload
+; ASM32-DAG:     lwz 14, -216(1)                         # 4-byte Folded Reload
+; ASM32:         blr
+
+; ASM64-LABEL    .fprs_gprs_vecregs:
+
+; ASM64-DAG:     std 14, -288(1)                         # 8-byte Folded Spill
+; ASM64-DAG:     std 25, -200(1)                         # 8-byte Folded Spill
+; ASM64-DAG:     std 31, -152(1)                         # 8-byte Folded Spill
+; ASM64-DAG:     stfd 14, -144(1)                        # 8-byte Folded Spill
+; ASM64-DAG:     stfd 21, -88(1)                         # 8-byte Folded Spill
+; ASM64-DAG:     stfd 31, -8(1)                          # 8-byte Folded Spill
+; ASM64-DAG:     #APP
+; ASM64-DAG:     #NO_APP
+; ASM64-DAG:     lfd 31, -8(1)                           # 8-byte Folded Reload
+; ASM64-DAG:     lfd 21, -88(1)                          # 8-byte Folded Reload
+; ASM64-DAG:     lfd 14, -144(1)                         # 8-byte Folded Reload
+; ASM64-DAG:     ld 31, -152(1)                          # 8-byte Folded Reload
+; ASM64-DAG:     ld 25, -200(1)                          # 8-byte Folded Reload
+; ASM64-DAG:     ld 14, -288(1)                          # 8-byte Folded Reload
+; ASM64:         blr
+
+define dso_local void @all_fprs_and_vecregs() {
+    call void asm sideeffect "", "~{f0},~{f1},~{f2},~{f3},~{f4},~{f5},~{f6},~{f7},~{f8},~{f9},~{f10},~{f12},~{f13},~{f14},~{f15},~{f16},~{f17},~{f18},~{f19},~{f20},~{f21},~{f22},~{f23},~{f24},~{f25},~{f26},~{f27},~{f28},~{f29},~{f30},~{f31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6}~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19}"()
+      ret void
+}
+
+;; Check that reserved vectors are not used.
+; MIR32-LABEL:   all_fprs_and_vecregs
+
+; MIR32-NOT:     $v20
+; MIR32-NOT:     $v21
+; MIR32-NOT:     $v22
+; MIR32-NOT:     $v23
+; MIR32-NOT:     $v24
+; MIR32-NOT:     $v25
+; MIR32-NOT:     $v26
+; MIR32-NOT:     $v27
+; MIR32-NOT:     $v28
+; MIR32-NOT:     $v29
+; MIR32-NOT:     $v30
+; MIR32-NOT:     $v31
+
+; MIR64-LABEL:   all_fprs_and_vecregs
+
+; MIR64-NOT:     $v20
+; MIR64-NOT:     $v21
+; MIR64-NOT:     $v22
+; MIR64-NOT:     $v23
+; MIR64-NOT:     $v24
+; MIR64-NOT:     $v25
+; MIR64-NOT:     $v26
+; MIR64-NOT:     $v27
+; MIR64-NOT:     $v28
+; MIR64-NOT:     $v29
+; MIR64-NOT:     $v30
+; MIR64-NOT:     $v31

diff  --git a/llvm/test/CodeGen/PowerPC/aix-inlineasm-reserved-reg-dflt-warn.ll b/llvm/test/CodeGen/PowerPC/aix-inlineasm-reserved-reg-dflt-warn.ll
new file mode 100644
index 000000000000..645de08c437c
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-inlineasm-reserved-reg-dflt-warn.ll
@@ -0,0 +1,14 @@
+; RUN: llc < %s -mtriple=powerpc-unknown-aix-xcoff -verify-machineinstrs \
+; RUN:     -mcpu=pwr7 -mattr=+altivec 2>&1 | \
+; RUN:   FileCheck --check-prefix=DFLTWRN %s
+
+; RUN: llc < %s -mtriple=powerpc64-unknown-aix-xcoff -verify-machineinstrs \
+; RUN:     -mcpu=pwr7 -mattr=+altivec 2>&1 | \
+; RUN:   FileCheck --check-prefix=DFLTWRN %s
+define dso_local void @vec_warn() {
+entry:
+  call void asm sideeffect "", "~{v23}"()
+  ret void
+}
+
+; DFLTWRN: warning: vector registers 20 to 32 are reserved in the default AIX AltiVec ABI and cannot be used

diff  --git a/llvm/test/CodeGen/PowerPC/aix-vec-abi.ll b/llvm/test/CodeGen/PowerPC/aix-vec-abi.ll
deleted file mode 100644
index 9dac55c37b93..000000000000
--- a/llvm/test/CodeGen/PowerPC/aix-vec-abi.ll
+++ /dev/null
@@ -1,8 +0,0 @@
-; RUN: not --crash llc < %s -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr8 2>&1 | FileCheck %s --check-prefix=DFLTERROR
-; RUN: not --crash llc < %s -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr8 2>&1 | FileCheck %s --check-prefix=DFLTERROR
-
-define void @vec_callee(<4 x i32> %vec1) {
-    ret void 
-}
-
-; DFLTERROR:  LLVM ERROR: the default Altivec AIX ABI is not yet supported


        


More information about the llvm-commits mailing list