https://github.com/HelloWorldU created 
https://github.com/llvm/llvm-project/pull/223961

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

>From bb0fcfb4f1d2f50cafc70076c5a9e6bc5a70ba6a Mon Sep 17 00:00:00 2001
From: HelloWorldU <[email protected]>
Date: Wed, 16 Sep 2026 17:59:18 +0800
Subject: [PATCH] [clang] Handle single-element vectors in the Swift calling
 convention

Allow single-element vectors to reach target-specific ABI legality checks. 
Preserve supported vectors and lower unsupported ones to their scalar element 
before entering the subvector splitting algorithm.

Add regression coverage for scalar and aggregate arguments and returns on 
x86-64, AArch64, and ARM.

Fixes #223871.
---
 clang/lib/CodeGen/SwiftCallingConv.cpp        |  9 ++-
 .../CodeGen/swiftcall-single-element-vector.c | 65 +++++++++++++++++++
 2 files changed, 71 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGen/swiftcall-single-element-vector.c

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

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

Reply via email to