[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