On Tue, 31 Mar 2015, 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?

Yep, it seems that loading from p with the following has a value of
type 'int', not 'myint'.

typedef int myint __attribute__((aligned(8)));
myint i;
myint *p = &i;

Well, the gimplifier does that:

/* Create a temporary with a name derived from VAL.  Subroutine of
   lookup_tmp_var; nobody else should call this function.  */

static inline tree
create_tmp_from_val (tree val)
{
  /* Drop all qualifiers and address-space information from the value 
type.  */
  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
  tree var = create_tmp_var (type, get_name (val));

it even drops address-space info which looks suspicious to me for

int *p [addr-space:X];
int * [addr-space:X] *q = &p;

and

 **q;

it would generate

 int *tem = *q;
 int tem = *tem;

and thus drop the addr-space from the 2nd load.  Similar for atomics
if they are also on the variant chain (ah, but those are lowered
early, so it doesn't matter for them).

So you indeed need a testcase where the compiler creates a temporary
of such type (or you need a type the gimplifier doesn't consider
a register type).

Richard.

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)

Reply via email to