[clang] [clang][X86] Return Win64 __int128 indirectly (PR #210358)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 17 08:21:48 PDT 2026
https://github.com/oltolm created https://github.com/llvm/llvm-project/pull/210358
Make Win64 __int128/__uint128 returns use indirect return lowering instead of coercing them to a v2i64 XMM return.
This matches the updated GCC behavior and removes the old special-case compatibility path for MinGW i128 returns.
In https://github.com/gcc-mirror/gcc/commit/e63a873f1df7493b8b657acafb451bf40166044e I fixed GCC to return `__int128` indirectly on Windows. This patch does the same for Clang.
>From fad973afe6500fb0727c58c93ff314b7b923da53 Mon Sep 17 00:00:00 2001
From: Oleg Tolmatcev <oleg.tolmatcev at gmail.com>
Date: Fri, 17 Jul 2026 17:17:02 +0200
Subject: [PATCH] [clang][X86] Return Win64 __int128 indirectly
Make Win64 __int128/__uint128 returns use indirect return lowering
instead of coercing them to a v2i64 XMM return.
This matches the updated GCC behavior and removes the old special-case
compatibility path for MinGW i128 returns.
---
clang/lib/CodeGen/Targets/X86.cpp | 6 ++----
clang/test/CodeGen/win64-i128.c | 16 ++++++++++++----
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 4e99ebab6ba34..275e13730eab3 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -3447,12 +3447,10 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs,
Align, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
/*ByVal=*/false);
- // Mingw64 GCC returns i128 in XMM0. Coerce to v2i64 to handle that.
- // Clang matches them for compatibility.
if (BT->getKind() == BuiltinType::Int128 ||
BT->getKind() == BuiltinType::UInt128)
- return ABIArgInfo::getDirect(llvm::FixedVectorType::get(
- llvm::Type::getInt64Ty(getVMContext()), 2));
+ return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
+ /*ByVal=*/false);
// Mingw64 GCC returns f128 via sret, and Clang matches that for
// compatibility. This mirrors the X86 backend's CanLowerReturn logic.
diff --git a/clang/test/CodeGen/win64-i128.c b/clang/test/CodeGen/win64-i128.c
index 5095d11a4c81f..2eb3dba783a21 100644
--- a/clang/test/CodeGen/win64-i128.c
+++ b/clang/test/CodeGen/win64-i128.c
@@ -7,13 +7,21 @@ typedef int int128_t __attribute__((mode(TI)));
int128_t foo(void) { return 0; }
-// GNU64: define dso_local <2 x i64> @foo()
-// MSC64: define dso_local <2 x i64> @foo()
+// GNU64-LABEL: define dso_local void @foo(
+// GNU64-SAME: sret(i128) align 16
+// MSC64-LABEL: define dso_local void @foo(
+// MSC64-SAME: sret(i128) align 16
int128_t bar(int128_t a, int128_t b) { return a * b; }
-// GNU64: define dso_local <2 x i64> @bar(ptr noundef align 16 dead_on_return %0, ptr noundef align 16 dead_on_return %1)
-// MSC64: define dso_local <2 x i64> @bar(ptr noundef align 16 dead_on_return %0, ptr noundef align 16 dead_on_return %1)
+// GNU64-LABEL: define dso_local void @bar(
+// GNU64-SAME: sret(i128) align 16
+// GNU64-SAME: ptr noundef align 16 dead_on_return
+// GNU64-SAME: ptr noundef align 16 dead_on_return
+// MSC64-LABEL: define dso_local void @bar(
+// MSC64-SAME: sret(i128) align 16
+// MSC64-SAME: ptr noundef align 16 dead_on_return
+// MSC64-SAME: ptr noundef align 16 dead_on_return
void vararg(int a, ...) {
// GNU64-LABEL: define{{.*}} void @vararg
More information about the cfe-commits
mailing list