Skip to content

[clang][SPARC] Treat empty structs as if it's a one-bit type in the CC #90338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 15, 2024

Conversation

koachan
Copy link
Contributor

@koachan koachan commented Apr 27, 2024

Make sure that empty structs are treated as if it has a size of one bit in function parameters and return types so that it occupies a full argument and/or return register slot.

This fixes crashes and miscompilations when passing and/or returning empty structs.

Make sure that empty structs are treated as if it has a size of
one bit in function parameters and return types so that it occupies
a full argument and/or return register slot.

This fixes crashes and miscompilations when passing and/or returning
empty structs.
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:Sparc clang:codegen IR generation bugs: mangling, exceptions, etc. labels Apr 27, 2024
@llvmbot
Copy link
Member

llvmbot commented Apr 27, 2024

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-backend-sparc

@llvm/pr-subscribers-clang-codegen

Author: Koakuma (koachan)

Changes

Make sure that empty structs are treated as if it has a size of one bit in function parameters and return types so that it occupies a full argument and/or return register slot.

This fixes crashes and miscompilations when passing and/or returning empty structs.


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+4-1)
  • (modified) clang/test/CodeGen/sparcv9-abi.c (+6)
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp
index 9025a633f328e2..b82e9a69e19671 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -263,7 +263,10 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const {
 
   CoerceBuilder CB(getVMContext(), getDataLayout());
   CB.addStruct(0, StrTy);
-  CB.pad(llvm::alignTo(CB.DL.getTypeSizeInBits(StrTy), 64));
+  // All structs, even empty ones, should take up a register argument slot,
+  // so pin the minimum struct size to one bit.
+  CB.pad(llvm::alignTo(
+      std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(), 1UL), 64));
 
   // Try to use the original type for coercion.
   llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
diff --git a/clang/test/CodeGen/sparcv9-abi.c b/clang/test/CodeGen/sparcv9-abi.c
index 5e74a9a883cefa..360bd9d9019e56 100644
--- a/clang/test/CodeGen/sparcv9-abi.c
+++ b/clang/test/CodeGen/sparcv9-abi.c
@@ -21,6 +21,12 @@ char f_int_4(char x) { return x; }
 // CHECK-LABEL: define{{.*}} fp128 @f_ld(fp128 noundef %x)
 long double f_ld(long double x) { return x; }
 
+// Empty struct is lowered as a placeholder word parameter.
+struct empty {};
+
+// CHECK-LABEL: define{{.*}} i64 @f_empty(i64 %x.coerce)
+struct empty f_empty(struct empty x) { return x; }
+
 // Small structs are passed in registers.
 struct small {
   int *a, *b;

@koachan koachan merged commit c2fba6d into llvm:main May 15, 2024
3 of 4 checks passed
@fhahn
Copy link
Contributor

fhahn commented May 15, 2024

This breaks building on some platforms. Should be fixed with da116bd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:Sparc clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants