[PATCH] D79770: [RISCV] Fix passing two floating-point values in complex separately by two GPRs on RV64
This revision was automatically updated to reflect the committed changes. Closed by commit rG7ee479a760e0: [RISCV] Fix passing two floating-point values in complex separately by two GPRs… (authored by Jim). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D79770/new/ 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(); } 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,
[PATCH] D79770: [RISCV] Fix passing two floating-point values in complex separately by two GPRs on RV64
asb accepted this revision. asb added a comment. This revision is now accepted and ready to land. Good catch, thanks for the fix! The logic was incorrectly written assuming `isFloatingType` would return false for complex values which is of course incorrect. Comment at: clang/lib/CodeGen/TargetInfo.cpp:10241-10242 // 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--; luismarques wrote: > Do you have tests that show the impact of the added `FLen >= Size && > ArgFPRsLeft` conditions for other values besides complex floats? That's actually not an added clause - it's just been clang-formatted onto a new line. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D79770/new/ https://reviews.llvm.org/D79770 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D79770: [RISCV] Fix passing two floating-point values in complex separately by two GPRs on RV64
luismarques added inline comments. Comment at: clang/lib/CodeGen/TargetInfo.cpp:10241-10242 // 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--; Do you have tests that show the impact of the added `FLen >= Size && ArgFPRsLeft` conditions for other values besides complex floats? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D79770/new/ https://reviews.llvm.org/D79770 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D79770: [RISCV] Fix passing two floating-point values in complex separately by two GPRs on RV64
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(); } Index: clang/test/CodeGen/riscv64-