[clang] [clang] Handle single-element vectors in the Swift calling convention (PR #223961)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 16 03:13:10 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Aochang Liu (HelloWorldU)
<details>
<summary>Changes</summary>
Single-element vectors hit an assertion before reaching the target-specific Swift ABI checks, even though some targets support them.
Relax the element-count assertion and scalarize single-element vectors when they are not legal for the target ABI.
Fixes #<!-- -->223871.
Assisted-by: OpenAI GPT-6
---
Full diff: https://github.com/llvm/llvm-project/pull/223961.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/SwiftCallingConv.cpp (+6-3)
- (added) clang/test/CodeGen/swiftcall-single-element-vector.c (+65)
``````````diff
diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp
index 209654303a82b..9b9a44270b8e6 100644
--- a/clang/lib/CodeGen/SwiftCallingConv.cpp
+++ b/clang/lib/CodeGen/SwiftCallingConv.cpp
@@ -693,7 +693,7 @@ bool swiftcall::isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
bool swiftcall::isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
llvm::Type *eltTy, unsigned numElts) {
- assert(numElts > 1 && "illegal vector length");
+ assert(numElts > 0 && "illegal vector length");
return getSwiftABIInfo(CGM).isLegalVectorType(vectorSize, eltTy, numElts);
}
@@ -721,11 +721,14 @@ void swiftcall::legalizeVectorType(CodeGenModule &CGM, CharUnits origVectorSize,
return;
}
- // Try to split the vector into legal subvectors.
auto numElts = cast<llvm::FixedVectorType>(origVectorTy)->getNumElements();
auto eltTy = origVectorTy->getElementType();
- assert(numElts != 1);
+ if (numElts == 1) {
+ components.push_back(eltTy);
+ return;
+ }
+ // Try to split the vector into legal subvectors.
// The largest size that we're still considering making subvectors of.
// Always a power of 2.
unsigned logCandidateNumElts = llvm::Log2_32(numElts);
diff --git a/clang/test/CodeGen/swiftcall-single-element-vector.c b/clang/test/CodeGen/swiftcall-single-element-vector.c
new file mode 100644
index 0000000000000..03423b7f45d2b
--- /dev/null
+++ b/clang/test/CodeGen/swiftcall-single-element-vector.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,X86
+// RUN: %clang_cc1 -no-enable-noundef-analysis -triple arm64-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,ARM,ARM64
+// RUN: %clang_cc1 -no-enable-noundef-analysis -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,ARM
+
+#define SWIFTCALL __attribute__((swiftcall))
+
+typedef long long long1 __attribute__((vector_size(8)));
+typedef double double1 __attribute__((ext_vector_type(1)));
+typedef float float1 __attribute__((ext_vector_type(1)));
+
+// A 64-bit single-element vector is legal on ARM, but must be scalarized on x86.
+// X86-LABEL: define swiftcc i64 @pass_long1(i64
+// X86: ret i64
+// ARM-LABEL: define swiftcc <1 x i64> @pass_long1(<1 x i64>
+// ARM: ret <1 x i64>
+SWIFTCALL long1 pass_long1(long1 value) {
+ return value;
+}
+
+// X86-LABEL: define swiftcc double @pass_double1(double
+// X86: ret double
+// ARM-LABEL: define swiftcc <1 x double> @pass_double1(<1 x double>
+// ARM: ret <1 x double>
+SWIFTCALL double1 pass_double1(double1 value) {
+ return value;
+}
+
+// A 32-bit vector must be scalarized on all three targets.
+// CHECK-LABEL: define swiftcc float @pass_float1(float
+// CHECK: ret float
+SWIFTCALL float1 pass_float1(float1 value) {
+ return value;
+}
+
+struct VectorBox {
+ long1 v;
+};
+
+// X86-LABEL: define swiftcc i64 @pass_box(i64
+// X86: ret i64
+// ARM-LABEL: define swiftcc <1 x i64> @pass_box(<1 x i64>
+// ARM: ret <1 x i64>
+SWIFTCALL struct VectorBox pass_box(struct VectorBox value) {
+ return value;
+}
+
+// CHECK-LABEL: define {{.*}} @call_pass_box(
+// X86: call swiftcc i64 @pass_box(i64
+// ARM: call swiftcc <1 x i64> @pass_box(<1 x i64>
+struct VectorBox call_pass_box(struct VectorBox value) {
+ return pass_box(value);
+}
+
+#ifdef __SIZEOF_INT128__
+typedef __int128 int128_1 __attribute__((vector_size(16)));
+
+// A 128-bit single-element vector is legal on x86, but not on ARM64.
+// X86-LABEL: define swiftcc <1 x i128> @pass_int128_1(<1 x i128>
+// X86: ret <1 x i128>
+// ARM64-LABEL: define swiftcc i128 @pass_int128_1(i128
+// ARM64: ret i128
+SWIFTCALL int128_1 pass_int128_1(int128_1 value) {
+ return value;
+}
+#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/223961
More information about the cfe-commits
mailing list