[llvm-commits] [llvm-gcc-4.2] r51723 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h config/i386/llvm-i386.cpp config/rs6000/llvm-rs6000.cpp llvm-abi.h

Evan Cheng evan.cheng at apple.com
Mon Jun 2 17:49:40 PDT 2008


Thanks!

Evan

On Jun 2, 2008, at 5:40 PM, Dale Johannesen wrote:

> I'll look.
>
> On Jun 2, 2008, at 5:35 PM, Evan Cheng wrote:
>
>> Hi Dale,
>>
>> Looks like this patch broke 447.dealII on x86-64. Try this:
>>
>> make ENABLE_OPTIMIZED=1 TEST=nightly TARGET_FLAGS="-m64 - 
>> DSPEC_CPU2000_LP64 -DSPEC_CPU_LP64" TARGET_LLCFLAGS="-relocation- 
>> model=pic -disable-fp-elim" EXTRA_LLI_OPTS="-relocation-model=pic - 
>> disable-fp-elim" clean Output/447.dealII.diff-llc
>>
>> Evan
>>
>> On May 29, 2008, at 6:23 PM, Dale Johannesen wrote:
>>
>>> Author: johannes
>>> Date: Thu May 29 20:23:12 2008
>>> New Revision: 51723
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=51723&view=rev
>>> Log:
>>> X86-64 ABI fix.  Revert isSingleElementStructOrArray
>>> change in favor of a more general version which handles
>>> the case where there's more than one element correctly.
>>> Fixes gcc.dg/compat/struct-layout-1.exp/t003
>>> and many more.
>>>
>>>
>>> Modified:
>>>  llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
>>>  llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
>>>  llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp
>>>  llvm-gcc-4.2/trunk/gcc/llvm-abi.h
>>>
>>> Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=51723&r1=51722&r2=51723&view=diff
>>>
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h (original)
>>> +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Thu May  
>>> 29 20:23:12 2008
>>> @@ -95,17 +95,18 @@
>>>  considered as if they were the type of the data field. */
>>> #ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
>>> #define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
>>> -  isSingleElementStructOrArray(X, true, false, false)
>>> +  isSingleElementStructOrArray(X, true, false)
>>> #endif
>>>
>>> +extern bool llvm_x86_should_pass_aggregate_in_integer_regs(tree,  
>>> unsigned*);
>>> +
>>> /* LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS - Return true if  
>>> this aggregate
>>>  value should be passed in integer registers.  This differs from  
>>> the usual
>>> -   handling in that x86-64 passes single-int-element unions as  
>>> the type of the
>>> -   field. */
>>> -#define  
>>> LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X)                \
>>> -   
>>> (TARGET_64BIT ?                                                    \
>>> -   !isSingleElementStructOrArray((X), true, true,  
>>> true) :            \
>>> -   !isSingleElementStructOrArray((X), false, true, false))
>>> +   handling in that x86-64 passes 128-bit structs and unions  
>>> which only
>>> +   contain data in the first 64 bits, as 64-bit objects.  (These  
>>> can be
>>> +   created by abusing __attribute__((aligned)).  */
>>> +#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X,  
>>> Y)             \
>>> +  llvm_x86_should_pass_aggregate_in_integer_regs((X), (Y))
>>>
>>> extern bool llvm_x86_should_pass_vector_in_integer_regs(tree);
>>>
>>>
>>> Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=51723&r1=51722&r2=51723&view=diff
>>>
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
>>> +++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Thu May 29  
>>> 20:23:12 2008
>>> @@ -1288,4 +1288,38 @@
>>> return Loc;
>>> }
>>>
>>> +/// llvm_x86_should_pass_aggregate_in_integer_regs - x86-32 is  
>>> same as the
>>> +/// default.  x86-64 detects the case where a type is 16 bytes  
>>> long but
>>> +/// only 8 of them are passed, the rest being padding (*size is  
>>> set to 8
>>> +/// to identify this case).
>>> +bool llvm_x86_should_pass_aggregate_in_integer_regs(tree type,  
>>> unsigned *size)
>>> +{
>>> +  *size = 0;
>>> +  if (TARGET_64BIT) {
>>> +    enum x86_64_reg_class Class[MAX_CLASSES];
>>> +    enum machine_mode Mode = ix86_getNaturalModeForType(type);
>>> +    int NumClasses = ix86_ClassifyArgument(Mode, type, Class, 0);
>>> +    if (NumClasses == 1 && (Class[0] == X86_64_INTEGERSI_CLASS ||
>>> +                            Class[0] == X86_64_INTEGER_CLASS)) {
>>> +      /* 8 byte object, one int register */
>>> +      return true;
>>> +    }
>>> +    if (NumClasses == 2 && (Class[0] == X86_64_INTEGERSI_CLASS ||
>>> +                            Class[0] == X86_64_INTEGER_CLASS)) {
>>> +      if (Class[1] == X86_64_INTEGERSI_CLASS ||
>>> +          Class[1] == X86_64_INTEGER_CLASS)
>>> +        /* 16 byte object, 2 int registers */
>>> +        return true;
>>> +      if (Class[1] == X86_64_NO_CLASS) {
>>> +        /* 16 byte object, only 1st register has information */
>>> +        *size = 8;
>>> +        return true;
>>> +      }
>>> +    }
>>> +    return false;
>>> +  }
>>> +  else
>>> +    return !isSingleElementStructOrArray(type, false, true);
>>> +}
>>> +
>>> /* LLVM LOCAL end (ENTIRE FILE!)  */
>>>
>>> Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp?rev=51723&r1=51722&r2=51723&view=diff
>>>
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp (original)
>>> +++ llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp Thu May  
>>> 29 20:23:12 2008
>>> @@ -404,7 +404,7 @@
>>> // some zero-length fields as well, must be passed as the field  
>>> type.
>>> // Note this does not apply to long double.
>>> // This is required for ABI correctness.
>>> -  tree tType = isSingleElementStructOrArray(TreeType, true,  
>>> false, false);
>>> +  tree tType = isSingleElementStructOrArray(TreeType, true, false);
>>> if (tType && int_size_in_bytes(tType)==Bytes && TYPE_MODE(tType)! 
>>> =TFmode &&
>>>     (TREE_CODE(tType)!=VECTOR_TYPE || Bytes==16))
>>>   return false;
>>> @@ -437,7 +437,7 @@
>>> // Other single-element structs may be passed this way as well, but
>>> // only if the type size matches the element's type size (structs  
>>> that
>>> // violate this can be created with __aligned__).
>>> -  tree tType = isSingleElementStructOrArray(TreeType, true,  
>>> false, false);
>>> +  tree tType = isSingleElementStructOrArray(TreeType, true, false);
>>> if (tType && int_size_in_bytes(tType)==SrcSize && TYPE_MODE(tType)! 
>>> =TFmode &&
>>>     (TREE_CODE(tType)!=VECTOR_TYPE || SrcSize==16)) {
>>>   Elts.push_back(ConvertType(tType));
>>>
>>> Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=51723&r1=51722&r2=51723&view=diff
>>>
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
>>> +++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu May 29 20:23:12 2008
>>> @@ -138,21 +138,17 @@
>>> /// rejectFatBitField, and the single element is a bitfield of a  
>>> type that's
>>> /// bigger than the struct, return null anyway.
>>> static tree isSingleElementStructOrArray(tree type, bool  
>>> ignoreZeroLength,
>>> -                                         bool rejectFatBitfield,
>>> -                                         bool acceptUnions) {
>>> +                                         bool rejectFatBitfield) {
>>> // Scalars are good.
>>> if (!isAggregateTreeType(type)) return type;
>>>
>>> tree FoundField = 0;
>>> switch (TREE_CODE(type)) {
>>> case QUAL_UNION_TYPE:
>>> +  case UNION_TYPE:     // Single element unions don't count.
>>> case COMPLEX_TYPE:   // Complex values are like 2-element records.
>>> default:
>>>   return 0;
>>> -  case UNION_TYPE:     // Single element unions don't count.
>>> -    if (!acceptUnions)
>>> -      return 0;
>>> -    // fall through
>>> case RECORD_TYPE:
>>>   // If this record has variable length, reject it.
>>>   if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST)
>>> @@ -178,15 +174,13 @@
>>>       }
>>>     }
>>>   return FoundField ? isSingleElementStructOrArray(FoundField,
>>> -                                                      
>>> ignoreZeroLength, false,
>>> -                                                     false)
>>> +                                                      
>>> ignoreZeroLength, false)
>>>                     : 0;
>>> case ARRAY_TYPE:
>>>   const ArrayType *Ty = dyn_cast<ArrayType>(ConvertType(type));
>>>   if (!Ty || Ty->getNumElements() != 1)
>>>     return 0;
>>> -    return isSingleElementStructOrArray(TREE_TYPE(type), false,  
>>> false,
>>> -                                        false);
>>> +    return isSingleElementStructOrArray(TREE_TYPE(type), false,  
>>> false);
>>> }
>>> }
>>>
>>> @@ -283,8 +277,8 @@
>>> // single element is a bitfield of a type bigger than the struct;  
>>> the code
>>> // for field-by-field struct passing does not handle this one right.
>>> #ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS
>>> -#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) \
>>> -   !isSingleElementStructOrArray(X, false, true, false)
>>> +#define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X, Y) \
>>> +   !isSingleElementStructOrArray((X), false, true)
>>> #endif
>>>
>>> // LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR - Return a TYPE tree  
>>> if this single
>>> @@ -295,7 +289,7 @@
>>> // by abusing the __aligned__ attribute.)
>>> #ifndef LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR
>>> #define LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(X) \
>>> -  isSingleElementStructOrArray(X, false, false, false)
>>> +  isSingleElementStructOrArray(X, false, false)
>>> #endif
>>>
>>> // LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR - Return a TYPE tree if  
>>> this vector type
>>> @@ -408,6 +402,7 @@
>>> /// their fields.
>>> void HandleArgument(tree type, std::vector<const Type*> &ScalarElts,
>>>                     ParameterAttributes *Attributes = NULL) {
>>> +    unsigned Size = 0;
>>>   const Type *Ty = ConvertType(type);
>>>   // Figure out if this field is zero bits wide, e.g. {} or [0 x  
>>> int].  Do
>>>   // not include variable sized fields here.
>>> @@ -418,7 +413,7 @@
>>>     ScalarElts.push_back(PtrTy);
>>>   } else if (Ty->getTypeID()==Type::VectorTyID) {
>>>     if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type)) {
>>> -        PassInIntegerRegisters(type, Ty, ScalarElts);
>>> +        PassInIntegerRegisters(type, Ty, ScalarElts, 0);
>>>     } else {
>>>       C.HandleScalarArgument(Ty, type);
>>>       ScalarElts.push_back(Ty);
>>> @@ -444,8 +439,8 @@
>>>       *Attributes |=
>>>          
>>> ParamAttr::constructAlignmentFromInt(LLVM_BYVAL_ALIGNMENT(type));
>>>     }
>>> -    } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(type)) {
>>> -      PassInIntegerRegisters(type, Ty, ScalarElts);
>>> +    } else if (LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(type,  
>>> &Size)) {
>>> +      PassInIntegerRegisters(type, Ty, ScalarElts, Size);
>>>   } else if (isZeroSizedStructOrUnion(type)) {
>>>     // Zero sized struct or union, just drop it!
>>>     ;
>>> @@ -526,10 +521,15 @@
>>>
>>> /// PassInIntegerRegisters - Given an aggregate value that should  
>>> be passed in
>>> /// integer registers, convert it to a structure containing ints  
>>> and pass all
>>> -  /// of the struct elements in.
>>> +  /// of the struct elements in.  If Size is set we pass only  
>>> that many bytes.
>>> void PassInIntegerRegisters(tree type, const Type *Ty,
>>> -                              std::vector<const Type*>  
>>> &ScalarElts) {
>>> -    unsigned Size = TREE_INT_CST_LOW(TYPE_SIZE(type))/8;
>>> +                              std::vector<const Type*> &ScalarElts,
>>> +                              unsigned origSize) {
>>> +    unsigned Size;
>>> +    if (origSize)
>>> +      Size = origSize;
>>> +    else
>>> +      Size = TREE_INT_CST_LOW(TYPE_SIZE(type))/8;
>>>
>>>   // FIXME: We should preserve all aggregate value alignment  
>>> information.
>>>   // Work around to preserve some aggregate value alignment  
>>> information:
>>> @@ -568,7 +568,7 @@
>>>     Elts.push_back(Type::Int8Ty);
>>>     Size -= 1;
>>>   }
>>> -    assert(Size == 0 && "Didn't cover value?");
>>> +    assert((origSize || Size == 0) && "Didn't cover value?");
>>>   const StructType *STy = StructType::get(Elts, false);
>>>
>>>   unsigned i = 0;
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>




More information about the llvm-commits mailing list