[llvm] e56b479 - [Hexagon] Bugfix in VarArg lowering: Special case for musl (#157564)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 17 11:03:32 PDT 2025
Author: Benedikt Lukas Huber
Date: 2025-09-17T11:03:27-07:00
New Revision: e56b479d9f096171287e23169ce23295046535c0
URL: https://github.com/llvm/llvm-project/commit/e56b479d9f096171287e23169ce23295046535c0
DIFF: https://github.com/llvm/llvm-project/commit/e56b479d9f096171287e23169ce23295046535c0.diff
LOG: [Hexagon] Bugfix in VarArg lowering: Special case for musl (#157564)
While debugging #145206 I found that a possible cause for the problem is
the call to printf, which is variadic.
In a musl environment VarArgs are treated like *non* VarArgs.
The handling of this special case was bypassed by the commit
a4f85515c20566a3c059aacd1ee3554b598f33f0.
The reason is that the arguement `TreatAsVarArg` is only set to `true`
in
an *non* musl env. `TreatAsVarArg` determines the result of
`isVarArg()`.
The `CCIfArgVarArg` class only checks each individual
variable, but not whether `isVarArg()` is true.
Without the special case, the unnamed arguments are always passed
on the stack, as is standard calling convention. But with musl
also unnamed arguments can be passed in registers.
Possibly, this fixes #145206.
Added:
llvm/test/CodeGen/Hexagon/vararg-musl.ll
Modified:
llvm/lib/Target/Hexagon/HexagonCallingConv.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonCallingConv.td b/llvm/lib/Target/Hexagon/HexagonCallingConv.td
index fd6d873dd4188..dceb70c8abbf2 100644
--- a/llvm/lib/Target/Hexagon/HexagonCallingConv.td
+++ b/llvm/lib/Target/Hexagon/HexagonCallingConv.td
@@ -6,6 +6,15 @@
//
//===----------------------------------------------------------------------===//
+// We cannot use the standard CCIfArgVarArg class here since in Hexagon there
+// exists a special case for a musl environment. In a musl environment VarArgs
+// are treated like non VarArgs. I.e., in a musl enviroment unnamed arguments
+// can also be passed in registers. The CCIfArgVarArg class only checks each
+// individual argument, but not whether State.isVarArg() is true. We also have
+// to check State.isVarArg() which is determined by the TreatAsVarArg argument.
+class CCIfStateVarArgAndArgVarArg<CCAction A>
+ : CCIf<"State.isVarArg() && ArgFlags.isVarArg()", A>;
+
def CC_HexagonStack: CallingConv<[
CCIfType<[i32,v2i16,v4i8],
CCAssignToStack<4,4>>,
@@ -23,7 +32,7 @@ def CC_Hexagon_Legacy: CallingConv<[
CCIfByVal<
CCPassByVal<8,8>>,
- CCIfArgVarArg<
+ CCIfStateVarArgAndArgVarArg<
CCDelegateTo<CC_HexagonStack>>,
// Pass split values in pairs, allocate odd register if necessary.
@@ -53,7 +62,7 @@ def CC_Hexagon: CallingConv<[
CCIfByVal<
CCPassByVal<8,1>>,
- CCIfArgVarArg<
+ CCIfStateVarArgAndArgVarArg<
CCDelegateTo<CC_HexagonStack>>,
// Pass split values in pairs, allocate odd register if necessary.
diff --git a/llvm/test/CodeGen/Hexagon/vararg-musl.ll b/llvm/test/CodeGen/Hexagon/vararg-musl.ll
new file mode 100644
index 0000000000000..b902dded32153
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/vararg-musl.ll
@@ -0,0 +1,15 @@
+; RUN: llc -mtriple=hexagon-unknown-linux-musl < %s | FileCheck %s -check-prefix=MUSL
+; RUN: llc -mtriple=hexagon-unknown-none-elf < %s | FileCheck %s -check-prefix=NONMUSL
+
+; MUSL-NOT: memw
+; NONMUSL: memw
+
+declare i32 @f0(i32 %a0, ...)
+
+define i32 @f1(i32 %a0, i32 %a1) #0 {
+b1:
+ %v7 = call i32 (i32, ...) @f0(i32 %a0, i32 %a1)
+ ret i32 %v7
+}
+
+attributes #0 = { nounwind }
More information about the llvm-commits
mailing list