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 + : 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>, // 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>, // 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 }