From c3bae964d0223121985a52d3c860f879f842f0d3 Mon Sep 17 00:00:00 2001 From: Laytan Date: Thu, 31 Jul 2025 20:26:22 +0200 Subject: [PATCH 1/3] amd64 abi fixes regarding vectors - Fixes the code so SSEUp is grouped/skipped over properly (Fixes #5429) - Fixes f16 vectors using garbage widths, because it would call LLVMGetIntTypeWidth and an f16 is not an int so doesn't have that function --- src/llvm_abi.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index e1cbe7558..c4c5b5a63 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -850,14 +850,18 @@ namespace lbAbiAmd64SysV { } else if (oldv == RegClass_SSEUp) { oldv = RegClass_SSEDv; } else if (is_sse(oldv)) { - i++; - while (i != e && oldv == RegClass_SSEUp) { - i++; + for (i++; i < e; i++) { + RegClass v = (*cls)[cast(isize)i]; + if (v != RegClass_SSEUp) { + break; + } } } else if (oldv == RegClass_X87) { - i++; - while (i != e && oldv == RegClass_X87Up) { - i++; + for (i++; i < e; i++) { + RegClass v = (*cls)[cast(isize)i]; + if (v != RegClass_X87Up) { + break; + } } } else { i++; @@ -1046,10 +1050,9 @@ namespace lbAbiAmd64SysV { i64 elem_sz = lb_sizeof(elem); LLVMTypeKind elem_kind = LLVMGetTypeKind(elem); RegClass reg = RegClass_NoClass; - unsigned elem_width = LLVMGetIntTypeWidth(elem); switch (elem_kind) { - case LLVMIntegerTypeKind: - case LLVMHalfTypeKind: + case LLVMIntegerTypeKind: { + unsigned elem_width = LLVMGetIntTypeWidth(elem); switch (elem_width) { case 8: reg = RegClass_SSEInt8; break; case 16: reg = RegClass_SSEInt16; break; @@ -1065,6 +1068,10 @@ namespace lbAbiAmd64SysV { GB_PANIC("Unhandled integer width for vector type %u", elem_width); } break; + }; + case LLVMHalfTypeKind: + reg = RegClass_SSEInt16; + break; case LLVMFloatTypeKind: reg = RegClass_SSEFv; break; From f32ee28e6d90d15f5c5fb225c19b5292e76302ed Mon Sep 17 00:00:00 2001 From: Laytan Date: Thu, 31 Jul 2025 20:50:46 +0200 Subject: [PATCH 2/3] amd64 support `half` in the abi too --- src/llvm_abi.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index c4c5b5a63..3666c74b5 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -527,6 +527,8 @@ namespace lbAbiAmd64SysV { enum RegClass { RegClass_NoClass, RegClass_Int, + RegClass_SSEHs, + RegClass_SSEHv, RegClass_SSEFs, RegClass_SSEFv, RegClass_SSEDs, @@ -545,6 +547,8 @@ namespace lbAbiAmd64SysV { gb_internal bool is_sse(RegClass reg_class) { switch (reg_class) { + case RegClass_SSEHs: + case RegClass_SSEHv: case RegClass_SSEFs: case RegClass_SSEFv: case RegClass_SSEDs: @@ -693,6 +697,8 @@ namespace lbAbiAmd64SysV { case RegClass_Int: needed_int += 1; break; + case RegClass_SSEHs: + case RegClass_SSEHv: case RegClass_SSEFs: case RegClass_SSEFv: case RegClass_SSEDs: @@ -804,6 +810,8 @@ namespace lbAbiAmd64SysV { to_write = RegClass_Memory; } else if (newv == RegClass_SSEUp) { switch (oldv) { + case RegClass_SSEHv: + case RegClass_SSEHs: case RegClass_SSEFv: case RegClass_SSEFs: case RegClass_SSEDv: @@ -918,6 +926,7 @@ namespace lbAbiAmd64SysV { sz -= rs; break; } + case RegClass_SSEHv: case RegClass_SSEFv: case RegClass_SSEDv: case RegClass_SSEInt8: @@ -928,6 +937,10 @@ namespace lbAbiAmd64SysV { unsigned elems_per_word = 0; LLVMTypeRef elem_type = nullptr; switch (reg_class) { + case RegClass_SSEHv: + elems_per_word = 4; + elem_type = LLVMHalfTypeInContext(c); + break; case RegClass_SSEFv: elems_per_word = 2; elem_type = LLVMFloatTypeInContext(c); @@ -962,6 +975,10 @@ namespace lbAbiAmd64SysV { continue; } break; + case RegClass_SSEHs: + array_add(&types, LLVMHalfTypeInContext(c)); + sz -= 2; + break; case RegClass_SSEFs: array_add(&types, LLVMFloatTypeInContext(c)); sz -= 4; @@ -1008,9 +1025,11 @@ namespace lbAbiAmd64SysV { break; } case LLVMPointerTypeKind: - case LLVMHalfTypeKind: unify(cls, ix + off/8, RegClass_Int); break; + case LLVMHalfTypeKind: + unify(cls, ix + off/8, (off%8 == 2) ? RegClass_SSEHv : RegClass_SSEHs); + break; case LLVMFloatTypeKind: unify(cls, ix + off/8, (off%8 == 4) ? RegClass_SSEFv : RegClass_SSEFs); break; @@ -1070,7 +1089,7 @@ namespace lbAbiAmd64SysV { break; }; case LLVMHalfTypeKind: - reg = RegClass_SSEInt16; + reg = RegClass_SSEHv; break; case LLVMFloatTypeKind: reg = RegClass_SSEFv; From 5527982c20b043ebfc15273a1718343a7f5669b8 Mon Sep 17 00:00:00 2001 From: Laytan Date: Thu, 31 Jul 2025 22:01:17 +0200 Subject: [PATCH 3/3] fix vec offset calculation --- src/llvm_abi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 3666c74b5..b6ed395d9 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1028,7 +1028,7 @@ namespace lbAbiAmd64SysV { unify(cls, ix + off/8, RegClass_Int); break; case LLVMHalfTypeKind: - unify(cls, ix + off/8, (off%8 == 2) ? RegClass_SSEHv : RegClass_SSEHs); + unify(cls, ix + off/8, (off%8 == 6) ? RegClass_SSEHv : RegClass_SSEHs); break; case LLVMFloatTypeKind: unify(cls, ix + off/8, (off%8 == 4) ? RegClass_SSEFv : RegClass_SSEFs);