[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