[cfe-commits] r143596 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp

Hatanaka, Akira ahatanaka at mips.com
Mon Nov 7 18:52:01 PST 2011


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: cfe-commits at cs.uiuc.edu
Subject: RE: [cfe-commits] r143596 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp

Thanks for the information, that is a better solution.

________________________________________
From: Eli Friedman [eli.friedman at gmail.com]
Sent: Wednesday, November 02, 2011 6:27 PM
To: Hatanaka, Akira
Cc: cfe-commits at cs.uiuc.edu
Subject: Re: [cfe-commits] r143596 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp

On Wed, Nov 2, 2011 at 6:09 PM, Hatanaka, Akira <ahatanaka at mips.com> 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




More information about the cfe-commits mailing list