[PATCH] D79770: [RISCV] Fix passing two floating-point values in complex separately by two GPRs on RV64

Jim Lin via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue May 12 01:02:36 PDT 2020


Jim created this revision.
Jim added reviewers: asb, luismarques, lenary.
Herald added subscribers: cfe-commits, evandro, apazos, sameer.abuasal, pzheng, s.egerton, benna, psnobl, jocewei, PkmX, rkruppe, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar.
Herald added a project: clang.

This patch fixed the error of counting the remaining FPRs. Complex floating-point values should be passed by two FPRs for the hard-float ABI. If no two FPRs are available, it should be passed via a 64-bit GPR (fp+fp).  `ArgFPRsLeft` is only decreased one while the type is complex floating-point. It causes two floating-point values in the complex are passed separately by two GPRs.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79770

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/riscv64-lp64-abi.c
  clang/test/CodeGen/riscv64-lp64f-lp64d-abi.c


Index: clang/test/CodeGen/riscv64-lp64f-lp64d-abi.c
===================================================================
--- clang/test/CodeGen/riscv64-lp64f-lp64d-abi.c
+++ clang/test/CodeGen/riscv64-lp64f-lp64d-abi.c
@@ -165,6 +165,35 @@
   return (struct floatcomplex_s){1.0};
 }
 
+// Complex floating-point values or structs containing a single complex
+// floating-point value should be passed in GPRs if no two FPRs is available.
+
+// CHECK: define void @f_floatcomplex_insufficient_fprs1(float %a.coerce0, float %a.coerce1, float %b.coerce0, float %b.coerce1, float %c.coerce0, float %c.coerce1, float %d.coerce0, float %d.coerce1, i64 %e.coerce)
+void f_floatcomplex_insufficient_fprs1(float __complex__ a, float __complex__ b,
+                                       float __complex__ c, float __complex__ d,
+                                       float __complex__ e) {}
+
+
+// CHECK: define void @f_floatcomplex_s_arg_insufficient_fprs1(float %0, float %1, float %2, float %3, float %4, float %5, float %6, float %7, i64 %e.coerce)
+void f_floatcomplex_s_arg_insufficient_fprs1(struct floatcomplex_s a,
+                                             struct floatcomplex_s b,
+                                             struct floatcomplex_s c,
+                                             struct floatcomplex_s d,
+                                             struct floatcomplex_s e) {}
+
+// CHECK: define void @f_floatcomplex_insufficient_fprs2(float %a, float %b.coerce0, float %b.coerce1, float %c.coerce0, float %c.coerce1, float %d.coerce0, float %d.coerce1, i64 %e.coerce)
+void f_floatcomplex_insufficient_fprs2(float a,
+                                       float __complex__ b, float __complex__ c,
+                                       float __complex__ d, float __complex__ e) {}
+
+
+// CHECK: define void @f_floatcomplex_s_arg_insufficient_fprs2(float %a, float %0, float %1, float %2, float %3, float %4, float %5, i64 %e.coerce)
+void f_floatcomplex_s_arg_insufficient_fprs2(float a,
+                                             struct floatcomplex_s b,
+                                             struct floatcomplex_s c,
+                                             struct floatcomplex_s d,
+                                             struct floatcomplex_s e) {}
+
 // Test single or two-element structs that need flattening. e.g. those
 // containing nested structs, floats in small arrays, zero-length structs etc.
 
Index: clang/test/CodeGen/riscv64-lp64-abi.c
===================================================================
--- clang/test/CodeGen/riscv64-lp64-abi.c
+++ clang/test/CodeGen/riscv64-lp64-abi.c
@@ -30,3 +30,24 @@
                               uint8_t e, int8_t f, uint8_t g) {
   return (struct large){a, e, f, g};
 }
+
+// Complex floating-point values or structs containing a single complex
+// floating-point value should be passed in a GPR.
+
+// CHECK: define void @f_floatcomplex(i64 %a.coerce)
+void f_floatcomplex(float __complex__ a) {}
+
+// CHECK: define i64 @f_ret_floatcomplex()
+float __complex__ f_ret_floatcomplex() {
+  return 1.0;
+}
+
+struct floatcomplex_s { float __complex__ c; };
+
+// CHECK: define void @f_floatcomplex_s_arg(i64 %a.coerce)
+void f_floatcomplex_s_arg(struct floatcomplex_s a) {}
+
+// CHECK: define i64 @f_ret_floatcomplex_s()
+struct floatcomplex_s f_ret_floatcomplex_s() {
+  return (struct floatcomplex_s){1.0};
+}
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -10238,7 +10238,8 @@
   uint64_t Size = getContext().getTypeSize(Ty);
 
   // Pass floating point values via FPRs if possible.
-  if (IsFixed && Ty->isFloatingType() && FLen >= Size && ArgFPRsLeft) {
+  if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
+      FLen >= Size && ArgFPRsLeft) {
     ArgFPRsLeft--;
     return ABIArgInfo::getDirect();
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79770.263370.patch
Type: text/x-patch
Size: 3978 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200512/0a5dd86b/attachment.bin>


More information about the cfe-commits mailing list