questions about byval argument passing

Suppose this structure is passed by value to a function foo(struct S1),

struct S1 {
  int i0;
  float f0;
  double d0;
  long long l0;

and the ABI dictates the elements of the structure are copied to both
integer and floating pointer argument registers in the following way:

(i0, f0) => 1st 64-bit integer argument register
d0 => 2nd double float argument register (doubles are passed in FP registers)
l0 => 3rd 64-bit integer argument register

What is the best way to find out whether integer registers or floating
pointer registers should be used for argument passing inside
TargetLowering::LowerCall? I can get basic information of the
structure being passed (for example, by calling
ArgFlagsTy::getByValSize() or ArgFlagsTy::getByValAlign() to get size
and alignment), but there doesn't seem to be an easy way to find more
detailed information. Do I have to get the instance of StructType for
structure S1 and analyze it?

The way we do stuff like this for x86-64 is adding handling to clang;
for example, to handle your case, make clang lower "void f(struct S1
x)" to the following:

define void @x(i64 %x.1, double %x.2, i64 %x.3)

Basically, an LLVM struct type doesn't really encode enough
information to accurately compute the C calling convention, so we
handle the tricky cases in the frontend. The relevant code is in
clang/lib/CodeGen/TargetInfo.cpp .


Thanks, I will try that.