Unexpected behaviour on transparent_union attribute

Hi,

I'm working on a LLVM backend for OpenRISC and
noticed some odd behaviour when compiling busybox for uClibc
using Clang.

After digging in to the issue I found out that functions that
are declared with a transparent union argument got called
with the argument casted to the union instead of using the
calling convention of the first member of the union.

Let me show an example:

typedef union {
  int *a;
  char *b;
} ARG __attribute__ ((__transparent_union__));

void foo(ARG u);

void bar(int *a)
{
  foo(a);
}

Turns into:

%union.ARG = type { i32* }

define void @bar(i32* %a) nounwind {
entry:
  %a.addr = alloca i32*, align 4
  %u = alloca %union.ARG, align 4
  %agg.tmp = alloca %union.ARG, align 4
  %.compoundliteral = alloca %union.ARG, align 4
  store i32* %a, i32** %a.addr, align 4
  %a1 = bitcast %union.ARG* %.compoundliteral to i32**
  %0 = load i32** %a.addr, align 4
  store i32* %0, i32** %a1, align 4
  %1 = bitcast %union.ARG* %agg.tmp to i8*
  %2 = bitcast %union.ARG* %.compoundliteral to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* %2, i32 4, i32 4, i1 false)
  call void @foo(%union.ARG* byval %agg.tmp)
  ret void
}

declare void @foo(%union.ARG* byval)

declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind

When I would have expected something like:

define void @bar(i32* %a) nounwind {
entry:
  %a.addr = alloca i32*, align 4
  %u = alloca i32*, align 4
  store i32* %a, i32** %a.addr, align 4
  %0 = load i32** %a.addr, align 4
  call void @foo(i32* %0)
  ret void
}

declare void @foo(i32*)

I've been able to "solve" the problem by inserting conversions of the
argument type in various places in CodeGen, by it's more of an ugly hack
than a real solution as it is now.
I've got a feeling that the record type (with the transparent union attribute)
should be kept intact as long as possible, so I believe the ideal solution would
be to go through all possible places right before CodeGen, but I'm too much of
a Clang novice to be able to pinpoint where and how (and if my belief is right),
so it's here that I'd like some advice on this issue.

Stefan