[LLVMdev] RFC: llvm-convert.cpp Patch

Bill Wendling isanbard at gmail.com
Tue Nov 6 17:45:27 PST 2007


Hi all,

This patch is to fix a problem on PPC64 where an unaligned memcpy is
generated. The testcase is this:

$ cat testcase.c
void Qux() {
  char Bar[11] = {0};
}

What happens is that we produce LLVM code like this:

	call void @llvm.memcpy.i64( i8* %event_list2, i8* getelementptr ([11
x i8]* @C.103.30698, i32 0, i32 0), i64 11, i32 8 )

Notice that it has an 8-byte alignment. However, the Bar variable has
1-byte alignment, because it's being placed into the "redzone". The
generic code for the function is:

$ more testcase.c.t03.generic
Qux ()
{
  static char C.0[11] = {0};
  char Bar[11];

  Bar = C.0;
}

Anyway, it turns out that the gimplifier was generating the correct
alignment, but it was being overridden in assemble_variable():

  /* On some machines, it is good to increase alignment sometimes.  */
  if (! DECL_USER_ALIGN (decl))
    {
#ifdef DATA_ALIGNMENT
      align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
#endif
#ifdef CONSTANT_ALIGNMENT
=>    if (DECL_INITIAL (decl) != 0 && DECL_INITIAL (decl) != error_mark_node)
        align = CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align);
#endif
    }

By setting the DECL_USER_ALIGN field, we can get the correct alignment.

Comments?

-bw

Index: gimplify.c
===================================================================
--- gimplify.c  (revision 43658)
+++ gimplify.c  (working copy)
@@ -2756,7 +2756,8 @@
                TREE_STATIC (new) = 1;
                TREE_READONLY (new) = 1;
                DECL_INITIAL (new) = ctor;
-               if (align > DECL_ALIGN (new))
+               /* LLVM LOCAL - Set DECL_USER_ALIGN when equal */
+               if (align >= DECL_ALIGN (new))
                  {
                    DECL_ALIGN (new) = align;
                    DECL_USER_ALIGN (new) = 1;



More information about the llvm-dev mailing list