[clang] [clang][X86] Return Win64 __int128 indirectly (PR #210358)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 17 08:23:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: oltolm (oltolm)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/210358.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/Targets/X86.cpp (+2-4)
- (modified) clang/test/CodeGen/win64-i128.c (+12-4)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/210358
More information about the cfe-commits
mailing list