[cfe-dev] Union Types

Pranav Bhandarkar pranavb at codeaurora.org
Mon Apr 23 17:51:46 PDT 2012


Consider the following simple testcase that uses a union.

typedef union {
  int w[2];
  long long int d;
}x; //64 bits.

extern void bar (long long int a);
void  foo (int *a) {
  x u;
  u.w[0] = *a;
  u.w[1] = *(a+1);
  bar (u.d);
On Hexagon, the most optimal code would be (pseudo-code)

r0=load (*a);
r1=load *(a+1);
bar(); // u.d is passed in the register pair r1:r0
This can be done by the Scalar Replacement of Aggregates pass. However, when
I looked at the scalar replacement of aggregates pass, it process the
following alloca

%u = alloca %union.x, align 8
%union.x = type { i64 }

So, scalar replacement converts this into a scalar of type i64 and for the
two loads generates two zero-extensions from 32 bits to 64 bits thus mucking
up any optimization opportunity. The following is what Scalar replacement
generates for u.w[0] = *a;
%u = alloca i64

%0 = load i32* %a, align 4, !tbaa !0

%.in3 = load i64* %u

%1 = zext i32 %0 to i64

%mask4 = and i64 %.in3, -4294967296

%ins5 = or i64 %mask4, %1

store i64 %ins5, i64* %u   

IMHO if the type %union.x was "type { [2 x i32] }" these unnecessary "zext"s
would not have been needed. So my question is what is the best way to fix
this problem ? Is the union type layout in clang a problem ? IMHO, this
layout is eliding information that there are two components at offsets 0 and
4 inside the union.


Qualcomm Innovation Center, (QuIC) is a member of the Code Aurora Forum.

More information about the cfe-dev mailing list