Skip to content

Calling convention for arguments on the stack on Xtensa is incorrect for arguments narrower than 32 bits (LLVM-245) #66

Closed
@kyrias

Description

@kyrias

According to the ISA document function arguments passed on the stack are all essentially stored in 32-bit slots, which matches how GCC for Xtensa behaves. Meanwhile LLVM for Xtensa passes smaller arguments packed together. This means that passing more than 6 arguments to a function between code compiled by GCC and LLVM is currently broken.

E.g.:

GCC:
| 8-bit  | padding                | 16-bit         | padding        | 32-bit                         |

LLVM:
| 8-bit  | 16-bit         | 32-bit                         |

I see in CC_Xtensa_Custom that i8 and i16 are promoted to i32 for non-byval arguments:

// Promote i8 and i16
if (LocVT == MVT::i8 || LocVT == MVT::i16) {
LocVT = MVT::i32;
if (ArgFlags.isSExt())
LocInfo = CCValAssign::SExt;
else if (ArgFlags.isZExt())
LocInfo = CCValAssign::ZExt;
else
LocInfo = CCValAssign::AExt;
}

But the same promotion s not being done for byval ones:

if (ArgFlags.isByVal()) {
Align ByValAlign = ArgFlags.getNonZeroByValAlign();
unsigned Offset = State.AllocateStack(ArgFlags.getByValSize(), ByValAlign);
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
// Allocate rest of registers, because rest part is not used to pass
// arguments
while (State.AllocateReg(IntRegs)) {
}
return false;
}


I was considering trying to submit a patch for this, but I'm not sure if you're currently accepting patches for the Xtensa part, or if so how you're accepting them.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions