[llvm-commits] [llvm-gcc-4.2] r51866 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Duncan Sands baldrick at free.fr
Mon Jun 2 08:56:49 PDT 2008


Author: baldrick
Date: Mon Jun  2 10:56:49 2008
New Revision: 51866

URL: http://llvm.org/viewvc/llvm-project?rev=51866&view=rev
Log:
Fix 2003-10-09-UnionInitializerBug.c on x86-64.
The problem was that in ConvertUNION if the
new field was less aligned than a previous one
but was also the biggest field seen so far then
it was selected.  But the most aligned field is
supposed to always be selected.  This caused a
crash in ConvertStructFieldInitializerToType
which relies on initializers not being more
aligned than the LLVM type.  In the long run
I think ConvertStructFieldInitializerToType
should be modified to not care about the
alignment.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=51866&r1=51865&r2=51866&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon Jun  2 10:56:49 2008
@@ -2179,7 +2179,7 @@
   const TargetData &TD = getTargetData();
   const Type *UnionTy = 0;
   tree GccUnionTy = 0;
-  unsigned MaxSize = 0, MaxAlign = 0;
+  unsigned MaxAlignSize = 0, MaxAlign = 0;
   for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
     if (TREE_CODE(Field) != FIELD_DECL) continue;
 //    assert(getFieldOffsetInBits(Field) == 0 && "Union with non-zero offset?");
@@ -2233,29 +2233,27 @@
     const Type *TheTy = ConvertType(TheGccTy);
     unsigned Size  = TD.getABITypeSize(TheTy);
     unsigned Align = TD.getABITypeAlignment(TheTy);
-    
+
     adjustPaddingElement(GccUnionTy, TheGccTy);
 
-    // Select TheTy as union type if it meets one of the following criteria
-    // 1) UnionTy is 0
-    // 2) TheTy alignment is more then UnionTy
-    // 3) TheTy size is greater than UnionTy size and TheTy alignment is 
-    //    equal to UnionTy
-    // 4) TheTy size is greater then UnionTy size and TheTy is packed
-    bool useTheTy = false;
+    // Select TheTy as union type if it is more aligned than any other.  If more
+    // than one field achieves the maximum alignment then choose the biggest.
+    bool useTheTy;
     if (UnionTy == 0)
       useTheTy = true;
+    else if (Align < MaxAlign)
+      useTheTy = false;
     else if (Align > MaxAlign)
       useTheTy = true;
-    else if (MaxAlign == Align && Size > MaxSize)
-      useTheTy = true;
-    else if (Size > MaxSize)
+    else if (Size > MaxAlignSize)
       useTheTy = true;
+    else
+      useTheTy = false;
 
     if (useTheTy) {
       UnionTy = TheTy;
       GccUnionTy = TheGccTy;
-      MaxSize = MAX(MaxSize, Size);
+      MaxAlignSize = Size;
       MaxAlign = Align;
     }
 





More information about the llvm-commits mailing list