[LLVMdev] RFC: llvm-convert.cpp Patch
Bill Wendling
isanbard at gmail.com
Fri Oct 26 11:12:38 PDT 2007
Hi all,
The patch below is to fix a problem with unaligned memcpys. This program:
void Bork() {
int Qux[33] = {0};
}
will currently produce this LLVM code on PPC64:
@C.0.937 = internal constant [33 x i8] zeroinitializer
define void @Bork() {
entry:
%Qux = alloca [33 x i8]
%Qux1 = bitcast [33 x i8]* %Qux to i8*
call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33
x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 )
br label %return
return:
ret void
}
declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
Notice that the alignment of the llvm.memcpy.i64 is 8 but the
alignment of Qux isn't -- it's 1 (n.b. the object is placed into the
redzone). The problem stems from from llvm-convert.cpp getting the
memcpy statement's alignment from the source pointer. The change below
will set its alignment to the minimum of the dest and src pointers'
alignments. (I do a copy because I didn't want to change it for all
cases. If it's okay to change it for all cases, I can take the copy
out.)
Is this a good thing? Will it break the world?
-bw
Index: gcc/llvm-convert.cpp
===================================================================
--- gcc/llvm-convert.cpp (revision 43366)
+++ gcc/llvm-convert.cpp (working copy)
@@ -3020,8 +3020,26 @@
Emit(TREE_OPERAND(exp, 1), LV.Ptr);
EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), isVolatile, false,
Alignment);
} else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0))!=RESULT_DECL) {
- Emit(TREE_OPERAND(exp, 1), LV.Ptr);
+ // At this point, Alignment is the alignment of the destination
+ // pointer. It may not match the alignment of the source pointer. So, we
+ // need to make sure that it's has at least its alignment.
+ tree new_exp = copy_node(TREE_OPERAND(exp, 1));
+ unsigned NewAlignment = expr_align(new_exp) / 8;
+ Alignment = (Alignment < NewAlignment) ? Alignment : NewAlignment;
+ TYPE_ALIGN(TREE_TYPE(new_exp)) = Alignment;
+
+ switch (TREE_CODE(new_exp)) {
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ DECL_ALIGN (new_exp) = Alignment * 8;
+ break;
+ default:
+ break;
+ }
+
+ Emit(new_exp, LV.Ptr);
} else {
// Need to do a volatile store into TREE_OPERAND(exp, 1). To do this, we
// emit it into a temporary memory location, then do a volatile copy into
More information about the llvm-dev
mailing list