Just to add to my previous email, tail call void @callee(i32 3, double %0, i64 %1, i64 %2, i64 %3) nounwind
Without alignment information attached to "double %0", this is how the backend will pass arguments in registers, when the function above is lowered: i32 3 => 1st integer register double %0 => 2nd FP register i64 %1 => 3rd integer register i64 %2, i64 %3 => 4th and 5th integer register The correct way to pass arguments is the following: i32 3 => 1st integer register double %0 => 3rd FP register i64 %1 => 4th integer register i64 %2, i64 %3 => 5th and 6th integer register ________________________________________ From: Hatanaka, Akira Sent: Monday, November 07, 2011 6:52 PM To: Eli Friedman Cc: [email protected] Subject: RE: [cfe-commits] r143596 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp One more question. Suppose I want to compile the following program: ### source program typedef struct { double d1; long double f1; } S4; void callee(int, S4); extern S4 g1; void foo100() { callee(3, g1); } This is the bitcode clang currently procudes: // bitcode target datalayout = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v64:64:64-n32" target triple = "mips64el-unknown-linux" %struct.S4 = type { double, fp128 } @g1 = external global %struct.S4 define void @foo100() nounwind { entry: %0 = load double* getelementptr inbounds (%struct.S4* @g1, i64 0, i32 0), align 16 %1 = load i64* getelementptr ({ double, i64, i64, i64 }* bitcast (%struct.S4* @g1 to { double, i64, i64, i64 }*), i64 0, i32 1), align 8 %2 = load i64* bitcast (fp128* getelementptr inbounds (%struct.S4* @g1, i64 0, i32 1) to i64*), align 16 %3 = load i64* getelementptr ({ double, i64, i64, i64 }* bitcast (%struct.S4* @g1 to { double, i64, i64, i64 }*), i64 0, i32 3), align 8 tail call void @callee(i32 3, double %0, i64 %1, i64 %2, i64 %3) nounwind ret void } declare void @callee(i32, double, i64, i64, i64) ### end of bitcode Since S4 has a long double field, whose alignment is 16, the second argument call to callee (g1) must also be 16-byte aligned, meaning it must be passed in even-odd FP register pairs. How do I convey this information to the backend? There is nothing in this line that tells "double %0" has to be aligned to a 16-byte boundary. tail call void @callee(i32 3, double %0, i64 %1, i64 %2, i64 %3) nounwind I understand you can attach alignment information to byval arguments, but I don't know if it is possible to do that to doubles or i64s. Even if it were possible, it seems that I would still need to override TargetLowering::LowerCallTo to retrieve alignment of arguments that are not byval. ________________________________________ From: Hatanaka, Akira Sent: Thursday, November 03, 2011 4:15 PM To: Eli Friedman Cc: [email protected] Subject: RE: [cfe-commits] r143596 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp Thanks for the information, that is a better solution. ________________________________________ From: Eli Friedman [[email protected]] Sent: Wednesday, November 02, 2011 6:27 PM To: Hatanaka, Akira Cc: [email protected] Subject: Re: [cfe-commits] r143596 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp On Wed, Nov 2, 2011 at 6:09 PM, Hatanaka, Akira <[email protected]> wrote: > Yes, that should be 40-bits. > > The structure with sub-doubleword fields was needed to handle packed > structures whose size is not a multiple of 64. When I test it with the > program below, a full double word load is used to load the last field of > struct S4 instead of a byte load. Is this legal? It seems incorrect to me to > load from a memory location outside the global g2. Oh, I see... no, that's not legal (at least, not in the general case). x86-64 uses a trick to get around this for cases like "struct { char x[13]; }": the last parameter has the type i40. -Eli _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
