[llvm-commits] [ARM] Fix for blocking PR13790. AAPCS byval params issue.

Stepan Dyatkovskiy stpworld at narod.ru
Fri Oct 12 12:05:35 PDT 2012


Hi Manman,


 > Why do we still need to store r1? I thought after the fix, only r2 
and r3 are used :]
 >
 > +; CHECK: stm     r0, {r1, r2, r3}
 > +  %g = alloca i8*
 > +  %g1 = bitcast i8** %g to i8*
 > +  call void @llvm.va_start(i8* %g1)

Initially I had the same thoughts, but test_byval_8_bytes_alignment is 
VA function, so it knows nothing about parameters VA args alignment
define void @test_byval_8_bytes_alignment(i32 %i, ...)

In prolog we should store all possible regs into 8 bytes aligned area 
(stack has 8 bytes alignment). The 4 byte padding is added at the 
beginning. Finally for byval regs we have 16 bytes area in stack:

AREA_START:
[ i32 undef, i32 r1, i32 r2, i32 r3 ]

But when you invoke va_arg for double, you know that this param has 8 
bytes alignment, and you know address where first register is stored:

VA_ARG_DOUBLE = AREA_START + #4.

Then since align == 8, rounding up is performed for VA_ARG_DOUBLE. So 
after all you got:

VA_ARG_DOUBLE = AREA_START + #4 + #4

It is address of r2.

The next lines checks this behaviour:
+; CHECK: add	[[REG:(r[0-9]+)|(lr)]], {{(r[0-9]+)|(lr)}}, #7
+; CHECK: bfc	[[REG]], #0, #3

Imho itsa nice trick :-)

-Stepan.




More information about the llvm-commits mailing list