On Tue, Mar 31, 2015 at 11:47:37AM +0100, Alan Lawrence wrote: > Richard Biener wrote: > > > >But I find it odd that on ARM passing *((aligned_int *)p) as > >vararg (only as varargs?) changes calling conventions independent > >of the functions type signature. > > Does it? Do you have a testcase, and compilation flags, that'll make this > show up in an RTL dump? I've tried numerous cases, including AFAICT yours, > and I always get the value being passed in the expected ("unaligned") > register?
If the integral type alignment right now matters, I'd try something like: typedef int V __attribute__((aligned (8))); V x; int foo (int x, ...) { int z; __builtin_va_list va; __builtin_va_start (va, x); switch (x) { case 1: case 3: case 6: z = __builtin_va_arg (va, int); break; default: z = __builtin_va_arg (va, V); break; } __builtin_va_end (va); return z; } int bar (void) { V v = 3; int w = 3; foo (1, (int) v); foo (2, (V) w); v = 3; w = (int) v; foo (3, w); foo (4, (V) w); v = (V) w; foo (5, v); foo (6, (int) v); foo (7, x); return 0; } (of course, most likely with passing a different value each time and verification of the result). As the compiler treats all those casts there as useless, I'd expect that the types of the passed argument would be pretty much random. And, note that even on x86_64, the __builtin_va_arg with V expands into # addr.1_3 = PHI <addr.1_27(9), _31(10)> z_35 = MEM[(V * {ref-all})addr.1_3]; using exactly the same address for int as well as V va_arg - if you increase the overalignment arbitrarily, it will surely be a wrong IL because nobody really guarantees anything about the overalignment. So, I think the tree-sra.c patch is a good idea - try to keep using the main type variants as the types in the IL where possible except for the MEM_REF first argument (i.e. even the lhs of the load should IMHO not be overaligned). As Eric Botcazou said, GCC right now isn't really prepared for under or overaligned scalars, only when they are in structs (or for middle-end in *MEM_REFs). Jakub