llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Daniel Cederman (doac)

<details>
<summary>Changes</summary>

Match GCC's SPARC V8 calling convention for vector return values. Return 
floating-point vectors and vectors larger than 64 bits indirectly. Return 
smaller integer vectors in floating-point registers.

https://godbolt.org/z/sKzeoqb17

Assisted-by: Codex

---
Full diff: https://github.com/llvm/llvm-project/pull/222264.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+11) 
- (modified) clang/test/CodeGen/Sparc/sparcv8-abi.c (+75-1) 


``````````diff
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp 
b/clang/lib/CodeGen/Targets/Sparc.cpp
index f5a17aa51184a..09663661bacce 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -71,6 +71,17 @@ ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty) 
const {
   if (const auto *CT = Ty->getAs<ComplexType>())
     return classifyComplexType(CT, /*IsRet=*/true);
 
+  if (const auto *VT = Ty->getAs<VectorType>()) {
+    uint64_t Size = getContext().getTypeSize(Ty);
+    if (VT->getElementType()->isRealFloatingType() || Size > 64)
+      return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
+
+    llvm::Type *FloatTy = llvm::Type::getFloatTy(getVMContext());
+    llvm::Type *CoerceTy =
+        Size <= 32 ? FloatTy : llvm::StructType::get(FloatTy, FloatTy);
+    return ABIArgInfo::getDirect(CoerceTy);
+  }
+
   if (const auto *BT = Ty->getAs<BuiltinType>();
       BT && BT->getKind() == BuiltinType::LongDouble)
     return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
diff --git a/clang/test/CodeGen/Sparc/sparcv8-abi.c 
b/clang/test/CodeGen/Sparc/sparcv8-abi.c
index 7beddd20e5e4d..1aa2687f14f39 100644
--- a/clang/test/CodeGen/Sparc/sparcv8-abi.c
+++ b/clang/test/CodeGen/Sparc/sparcv8-abi.c
@@ -1,4 +1,4 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --filter "^define |^entry:" --version 6
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --filter "^define |^entry:|call .*@return_" --version 6
 // RUN: %clang_cc1 -triple sparc-unknown-unknown -emit-llvm %s -o - | 
FileCheck %s
 
 float __complex__
@@ -50,3 +50,77 @@ t(long double _Complex a)
 {
     return 0;
 }
+
+typedef char v4i8 __attribute__((vector_size(4)));
+typedef char v8i8 __attribute__((vector_size(8)));
+typedef char v16i8 __attribute__((vector_size(16)));
+typedef float v1f32 __attribute__((vector_size(4)));
+typedef double v1f64 __attribute__((vector_size(8)));
+
+// Integer vectors of at most eight bytes are returned in floating-point
+// registers. Larger integer vectors and all floating-point vectors are
+// returned indirectly.
+// CHECK-LABEL: define dso_local float @return_v4i8(
+// CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+//
+v4i8 return_v4i8(int x) { return (v4i8){x, x, x, x}; }
+// CHECK-LABEL: define dso_local { float, float } @return_v8i8(
+// CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+//
+v8i8 return_v8i8(int x) { return (v8i8){x, x, x, x, x, x, x, x}; }
+// CHECK-LABEL: define dso_local void @return_v16i8(
+// CHECK-SAME: ptr dead_on_unwind noalias writable sret(<16 x i8>) align 16 
[[AGG_RESULT:%.*]], i32 noundef [[X:%.*]]) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+//
+v16i8 return_v16i8(int x) {
+  return (v16i8){x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x};
+}
+// CHECK-LABEL: define dso_local void @return_v1f32(
+// CHECK-SAME: ptr dead_on_unwind noalias writable sret(<1 x float>) align 4 
[[AGG_RESULT:%.*]], float noundef [[X:%.*]]) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+//
+v1f32 return_v1f32(float x) { return (v1f32){x}; }
+// CHECK-LABEL: define dso_local void @return_v1f64(
+// CHECK-SAME: ptr dead_on_unwind noalias writable sret(<1 x double>) align 8 
[[AGG_RESULT:%.*]], double noundef [[X:%.*]]) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+//
+v1f64 return_v1f64(double x) { return (v1f64){x}; }
+
+volatile v4i8 v4i8_result;
+volatile v8i8 v8i8_result;
+volatile v16i8 v16i8_result;
+volatile v1f32 v1f32_result;
+volatile v1f64 v1f64_result;
+
+// CHECK-LABEL: define dso_local void @call_integer_vector_returns(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+// CHECK:    [[CALL:%.*]] = call float @return_v4i8(i32 noundef 1)
+// CHECK:    [[CALL1:%.*]] = call { float, float } @return_v8i8(i32 noundef 1)
+// CHECK:    call void @return_v16i8(ptr dead_on_unwind writable sret(<16 x 
i8>) align 16 [[TMP:%.*]], i32 noundef 1)
+//
+void call_integer_vector_returns(void) {
+  v4i8_result = return_v4i8(1);
+  v8i8_result = return_v8i8(1);
+  v16i8_result = return_v16i8(1);
+}
+
+// CHECK-LABEL: define dso_local void @call_f32_vector_return(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+// CHECK:    call void @return_v1f32(ptr dead_on_unwind writable sret(<1 x 
float>) align 4 [[TMP:%.*]], float noundef 1.000000e+00)
+//
+void call_f32_vector_return(void) {
+  v1f32_result = return_v1f32(1.0f);
+}
+
+// CHECK-LABEL: define dso_local void @call_f64_vector_return(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+// CHECK:    call void @return_v1f64(ptr dead_on_unwind writable sret(<1 x 
double>) align 8 [[TMP:%.*]], double noundef 1.000000e+00)
+//
+void call_f64_vector_return(void) {
+  v1f64_result = return_v1f64(1.0);
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/222264
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to