[llvm-commits] [llvm-gcc-4.2] r46726 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Duncan Sands baldrick at free.fr
Fri Feb 8 10:03:13 PST 2008


Hi Dale,

> > It is possible that I'm not solving the real problem here.
> >
> > struct {
> > 	char a;
> > 	char b;
> > 	int c:8;
> > 	int d:20;
> > } S;
> >
> > When this struct is packed and S is aligned at 4 byte, what alignment
> > should be specified on load instruction to load 'd' ?
> 
> The struct is only 6 bytes long in this case (try it with gcc), so  
> representing d with a 32-bit load is probably not a good idea; there   
> are machines where such misaligned loads are valid (e.g. x86) and a 32- 
> bit load will read off the end of the structure.

right, potentially causing a page fault or other badness.

> In general I prefer the IR to be target-independent where possible,  
> but I don't see a good alternative to having the FE break up the load  
> of d into 3 pieces here (or perhaps char + short).  Having the IR  
> include a load off the end of the object, that wasn't there in the  
> source, and requiring the BE to figure this out seems very wrong.  So  
> to answer your question, there needs to be more than one load.

I can't help feeling that a bitfield load or store should touch the
minimum amount of bytes possible: only those that contain some part
of the bitfield.  In some situations touching other bytes could be
fatal, for example if the type is overlaid on some memory mapped io
region, or multiple threads are accessing different parts of the
type simulteneously.  In the above example you could try accessing
d using 4 bytes starting from b, but this would give wrong results
if some other thread was accessing b at the same time.  I'm fairly
sure that Ada has quite strict requirements about this, and I have
the vague idea (I don't know where I got it from) that there is talk
of requiring a minimum disturbance rule of some kind in C.

> However, if we modify the packed struct thus (it's now 7 bytes)
> 
> > struct {
> > 	char a;
> > 	char b;
> > 	int c:8;
> > 	int d:32;
> > } S;
> 
> 
> referring to d with misaligned 32-bit loads and stores is sensible.   
> That's valid code on x86, and representing it as byte operations and  
> expecting the BE to stick them back together is a lot of trouble for  
> no benefit.  Of course, on many other targets, that load must be  
> broken into pieces.   That could be done in either end, but since  
> we've got to break up 20-bit fields in the FE anyway, I guess we might  
> as well do so for 32-bit fields when the target requires that.  I  
> could probably be convinced to do this one in the BE though.

Doesn't the BE already do this?  It has some code at least for turning
unaligned loads into multiple aligned loads.

Best wishes,

Duncan.



More information about the llvm-commits mailing list