[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
Dale Johannesen
dalej at apple.com
Mon Jun 2 19:35:29 PDT 2008
Not saying you're wrong, but why do you think it's this patch?
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