[LLVMdev] RFC: llvm-convert.cpp Patch

Devang Patel dpatel at apple.com
Fri Oct 26 11:32:48 PDT 2007


On Oct 26, 2007, at 11:12 AM, Bill Wendling wrote:

> 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.

llvm.memcpy docs says, " the caller guarantees that both the source  
and destination pointers are aligned to that boundary.". Would it  
possible to run into a situation where selecting min. of src and dest  
alignment will not meet this criteria ?

> (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.)

In this case, I *think* (not guarantee :) it is ok to change  
alignment of "{0}" expression node in place, because, I don't think  
this expr node will be shared with any another "{0}" expression.  
However, your conservative approach is also fine.

-
Devang
>
> 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
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list