[llvm] 78d91df - [RISCV] Support register allocation for GHC when f/d is not specified in the architecture

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 23 22:40:16 PDT 2023


Author: eopXD
Date: 2023-07-23T22:40:10-07:00
New Revision: 78d91df452d669570e120cb5c3d5febf7f17475d

URL: https://github.com/llvm/llvm-project/commit/78d91df452d669570e120cb5c3d5febf7f17475d
DIFF: https://github.com/llvm/llvm-project/commit/78d91df452d669570e120cb5c3d5febf7f17475d.diff

LOG: [RISCV] Support register allocation for GHC when f/d is not specified in the architecture

This patch supports register allocation for floating-point types when
`zfinx` and `zdinx` is specified in the architecture for the GHC
calling convention.

Reviewed By: craig.topper

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

Added: 
    llvm/test/CodeGen/RISCV/ghccc-without-f-reg.ll

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index f642124e072ccf..92aa3b7bf82fe1 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -15444,25 +15444,28 @@ bool RISCV::CC_RISCV_FastCC(const DataLayout &DL, RISCVABI::ABI ABI,
 bool RISCV::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
                          CCValAssign::LocInfo LocInfo,
                          ISD::ArgFlagsTy ArgFlags, CCState &State) {
-
   if (ArgFlags.isNest()) {
     report_fatal_error(
         "Attribute 'nest' is not supported in GHC calling convention");
   }
 
+  static const MCPhysReg GPRList[] = {
+      RISCV::X9,  RISCV::X18, RISCV::X19, RISCV::X20, RISCV::X21, RISCV::X22,
+      RISCV::X23, RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27};
+
   if (LocVT == MVT::i32 || LocVT == MVT::i64) {
     // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, R7, SpLim
     //                        s1    s2  s3  s4  s5  s6  s7  s8  s9  s10 s11
-    static const MCPhysReg GPRList[] = {
-        RISCV::X9, RISCV::X18, RISCV::X19, RISCV::X20, RISCV::X21, RISCV::X22,
-        RISCV::X23, RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27};
     if (unsigned Reg = State.AllocateReg(GPRList)) {
       State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
       return false;
     }
   }
 
-  if (LocVT == MVT::f32) {
+  const RISCVSubtarget &Subtarget =
+      State.getMachineFunction().getSubtarget<RISCVSubtarget>();
+
+  if (LocVT == MVT::f32 && Subtarget.hasStdExtF()) {
     // Pass in STG registers: F1, ..., F6
     //                        fs0 ... fs5
     static const MCPhysReg FPR32List[] = {RISCV::F8_F, RISCV::F9_F,
@@ -15474,7 +15477,7 @@ bool RISCV::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
     }
   }
 
-  if (LocVT == MVT::f64) {
+  if (LocVT == MVT::f64 && Subtarget.hasStdExtD()) {
     // Pass in STG registers: D1, ..., D6
     //                        fs6 ... fs11
     static const MCPhysReg FPR64List[] = {RISCV::F22_D, RISCV::F23_D,
@@ -15486,6 +15489,15 @@ bool RISCV::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
     }
   }
 
+  if ((LocVT == MVT::f32 && Subtarget.hasStdExtZfinx()) ||
+      (LocVT == MVT::f64 && Subtarget.hasStdExtZdinx() &&
+       Subtarget.is64Bit())) {
+    if (unsigned Reg = State.AllocateReg(GPRList)) {
+      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+      return false;
+    }
+  }
+
   report_fatal_error("No registers left in GHC calling convention");
   return true;
 }
@@ -15505,9 +15517,9 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
   case CallingConv::Fast:
     break;
   case CallingConv::GHC:
-    if (!Subtarget.hasStdExtF() || !Subtarget.hasStdExtD())
-      report_fatal_error(
-        "GHC calling convention requires the F and D instruction set extensions");
+    if (!Subtarget.hasStdExtFOrZfinx() || !Subtarget.hasStdExtDOrZdinx())
+      report_fatal_error("GHC calling convention requires the (Zfinx/F) and "
+                         "(Zdinx/D) instruction set extensions");
   }
 
   const Function &Func = MF.getFunction();

diff  --git a/llvm/test/CodeGen/RISCV/ghccc-without-f-reg.ll b/llvm/test/CodeGen/RISCV/ghccc-without-f-reg.ll
new file mode 100644
index 00000000000000..32df34fe2c0f24
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/ghccc-without-f-reg.ll
@@ -0,0 +1,76 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=riscv64 -mattr=+zfinx,+zdinx < %s | FileCheck %s
+
+; Check the GHC call convention works for zfinx, zdinx (rv64)
+
+ at f1 = external global float
+ at f2 = external global float
+ at f3 = external global float
+ at f4 = external global float
+ at f5 = external global float
+ at f6 = external global float
+
+define ghccc void @caller_float() nounwind {
+; CHECK-LABEL: caller_float:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lui a0, %hi(f6)
+; CHECK-NEXT:    lw s6, %lo(f6)(a0)
+; CHECK-NEXT:    lui a0, %hi(f5)
+; CHECK-NEXT:    lw s5, %lo(f5)(a0)
+; CHECK-NEXT:    lui a0, %hi(f4)
+; CHECK-NEXT:    lw s4, %lo(f4)(a0)
+; CHECK-NEXT:    lui a0, %hi(f3)
+; CHECK-NEXT:    lw s3, %lo(f3)(a0)
+; CHECK-NEXT:    lui a0, %hi(f2)
+; CHECK-NEXT:    lw s2, %lo(f2)(a0)
+; CHECK-NEXT:    lui a0, %hi(f1)
+; CHECK-NEXT:    lw s1, %lo(f1)(a0)
+; CHECK-NEXT:    tail callee_float at plt
+entry:
+  %0  = load float, ptr @f6
+  %1  = load float, ptr @f5
+  %2  = load float, ptr @f4
+  %3  = load float, ptr @f3
+  %4 = load float, ptr @f2
+  %5 = load float, ptr @f1
+  tail call ghccc void @callee_float(float %5, float %4, float %3, float %2, float %1, float %0) nounwind
+  ret void
+}
+
+declare ghccc void @callee_float(float, float, float, float, float, float)
+
+ at d1 = external global double
+ at d2 = external global double
+ at d3 = external global double
+ at d4 = external global double
+ at d5 = external global double
+ at d6 = external global double
+
+define ghccc void @caller_double() nounwind {
+; CHECK-LABEL: caller_double:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lui a0, %hi(d6)
+; CHECK-NEXT:    ld s6, %lo(d6)(a0)
+; CHECK-NEXT:    lui a0, %hi(d5)
+; CHECK-NEXT:    ld s5, %lo(d5)(a0)
+; CHECK-NEXT:    lui a0, %hi(d4)
+; CHECK-NEXT:    ld s4, %lo(d4)(a0)
+; CHECK-NEXT:    lui a0, %hi(d3)
+; CHECK-NEXT:    ld s3, %lo(d3)(a0)
+; CHECK-NEXT:    lui a0, %hi(d2)
+; CHECK-NEXT:    ld s2, %lo(d2)(a0)
+; CHECK-NEXT:    lui a0, %hi(d1)
+; CHECK-NEXT:    ld s1, %lo(d1)(a0)
+; CHECK-NEXT:    tail callee_double at plt
+entry:
+  %0  = load double, ptr @d6
+  %1  = load double, ptr @d5
+  %2  = load double, ptr @d4
+  %3  = load double, ptr @d3
+  %4 = load double, ptr @d2
+  %5 = load double, ptr @d1
+  tail call ghccc void @callee_double(double %5, double %4, double %3, double %2, double %1, double %0) nounwind
+  ret void
+}
+
+declare ghccc void @callee_double(double, double, double, double, double, double)


        


More information about the llvm-commits mailing list