[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c

Chris Lattner lattner at cs.uiuc.edu
Fri Jul 15 19:14:19 PDT 2005



Changes in directory llvm-gcc/gcc:

llvm-expand.c updated: 1.103 -> 1.104
---
Log message:

Fix PR594: http://llvm.cs.uiuc.edu/PR594 , a really nasty miscompilation of bitfields on big-endian targets
like PPC and sparc.


---
Diffs of the changes:  (+19 -6)

 llvm-expand.c |   25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)


Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.103 llvm-gcc/gcc/llvm-expand.c:1.104
--- llvm-gcc/gcc/llvm-expand.c:1.103	Thu Jul  7 12:32:46 2005
+++ llvm-gcc/gcc/llvm-expand.c	Fri Jul 15 21:14:08 2005
@@ -2858,6 +2858,13 @@
   llvm_value *Idx;
 
   if (BitSize == 0) return Src;   /* Not a bitfield reference */
+
+  /* If this target has bitfields laid out in big-endian order, invert the bit
+    * in the word if needed.
+    */
+  if (BITS_BIG_ENDIAN)
+    BitStart = ValSize-BitStart-BitSize;
+  
   if (BitStart+BitSize != ValSize) {
     Idx = llvm_constant_new_integral(UByteTy, ValSize-(BitStart+BitSize));
     Src = append_inst(Fn, create_binary_inst("tmp", O_Shl, Src, Idx));
@@ -2872,15 +2879,23 @@
                                  unsigned BitStart, unsigned BitSize,
                                  int isVolatile) {
   llvm_value *OldVal;
-  llvm_type *ResultType;
+  llvm_type *ResultType = GET_POINTER_TYPE_ELEMENT(Ptr->Ty);
+  unsigned ResultTypeSizeInBits = llvm_type_get_size(ResultType)*8;
 
   /* Get a mask of all ones of the right size */
   long long Mask = (1LL << BitSize)-1;
-  /* Shift it over to the right place. */
-  Mask <<= BitStart;
 
   if (BitSize == 0) return Src;
   
+  /* If this target has bitfields laid out in big-endian order, invert the bit
+   * in the word if needed.
+   */
+  if (BITS_BIG_ENDIAN)
+    BitStart = ResultTypeSizeInBits-BitStart-BitSize;
+
+  /* Shift it over to the right place. */
+  Mask <<= BitStart;
+  
   /* If we are not storing starting at the zero'th bit, emit a shift of the
    * computed value.
    */
@@ -2889,10 +2904,8 @@
     Src = append_inst(Fn, create_binary_inst("tmp", O_Shl, Src, Idx));
   }
 
-  ResultType = GET_POINTER_TYPE_ELEMENT(Ptr->Ty);
-
   /* Mask off any upper bits of the value we computed, but don't want. */
-  if (BitStart + BitSize != llvm_type_get_size(ResultType)) {
+  if (BitStart + BitSize != ResultTypeSizeInBits) {
     /* Make an LLVM value for the constant. */
     llvm_value *MaskVal = llvm_constant_new_integral(ResultType, Mask);
     Src = append_inst(Fn, create_binary_inst("tmp", O_And, Src, MaskVal));






More information about the llvm-commits mailing list