On Thu, Apr 26, 2012 at 3:12 PM, Georg-Johann Lay <[email protected]> wrote:
> Richard Guenther wrote:
>> Georg-Johann Lay wrote:
>>> Georg-Johann Lay wrote:
>>>> Richard Guenther wrote:
>>>>> Georg-Johann Lay wrote:
>>>>>> [...]
>>>>>>
>>>>>> http://gcc.gnu.org/PR51527
>>>>>>
>>>>>> It works with 4.8 trunk but crashes with 4.7.
>>>>>> Did not yet track what changes made it work with 4.8, though.
>>>>>> Unfortunately, noone remembers :-(
>>>>>>
>>>>>> http://gcc.gnu.org/ml/gcc/2012-03/msg00440.html
>>>>> I have done changes in this area, trying to remove the type_for_size
>>>>> langhook.
>>>>>
>>>>> Richard.
>>>> One apparent change is tree.c:signed_or_unsigned_type_for
>>>>
>>>> that changed [...] at 2012-03-12
>>>>
>>>> http://gcc.gnu.org/viewcvs?view=revision&revision=185226
>>>>
>>>> Is this appropriate to backport?
>>
>> No, it's not.
>>
>>>> Or is the preferred solution to override lang_hooks.types.type_for_size in
>>>> the
>>>> backend, if applicable?
>>
>> Neither. It is a "lang"-hook, not a target-hook after all.
>>
>> I already told you what the right fix is - the callers of
>> type_for_size have to cater
>> for the returned type to be of different precision. Btw, I already see it
>> does
>>
>> /* But now perhaps TYPEX is as wide as INPREC.
>> In that case, do nothing special here.
>> (Otherwise would recurse infinitely in convert. */
>> if (TYPE_PRECISION (typex) != inprec)
>>
>> Richard
>
> Would you help me with the code? It's almost impossible to understand the
> convert stuff for a noob. I tried TARGET_CONVERT_TO_TYPE
>
> static tree
> avr_convert_to_type (tree type, tree expr)
> {
> tree xtype = TREE_TYPE (expr);
>
> /* convert enters infinite recursion for __int24 -> unsigned long
> convertsions. */
>
> if (/* From __int24 ... */
> TREE_CODE (xtype) == INTEGER_TYPE
> && TYPE_PRECISION (xtype) == 24
> && !TYPE_UNSIGNED (xtype)
> /* ... to unsigned long. */
> && TREE_CODE (type) == INTEGER_TYPE
> && TYPE_PRECISION (type) > 24
> && TYPE_UNSIGNED (type))
> {
> /* Perform an intermediate conversion:
> __int24 -> long -> unsigned long */
>
> /* Signed variant of type */
> tree stype = lang_hooks.types.type_for_mode (TYPE_MODE (type), 0);
>
> expr = convert (stype, expr);
> // expr = build1 (CONVERT_EXPR, stype, expr);
> expr = build1 (NOP_EXPR, type, expr);
>
> return expr;
> }
>
> return NULL_TREE;
> }
>
> #undef TARGET_CONVERT_TO_TYPE
> #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
>
>
> but with no avail. The explicit, intermediate conversion from __int24 to long
> does not prevent the infinite recursion.
I think the fix would be sth like
Index: gcc/convert.c
===================================================================
--- gcc/convert.c (revision 186871)
+++ gcc/convert.c (working copy)
@@ -769,6 +769,7 @@ convert_to_integer (tree type, tree expr
(Otherwise would recurse infinitely in convert. */
if (TYPE_PRECISION (typex) != inprec)
{
+ tree otypex = typex;
/* Don't do unsigned arithmetic where signed was wanted,
or vice versa.
Exception: if both of the original operands were
@@ -806,10 +807,11 @@ convert_to_integer (tree type, tree expr
typex = unsigned_type_for (typex);
else
typex = signed_type_for (typex);
- return convert (type,
- fold_build2 (ex_form, typex,
- convert (typex, arg0),
- convert (typex, arg1)));
+ if (TYPE_PRECISION (otypex) == TYPE_PRECISION (typex))
+ return convert (type,
+ fold_build2 (ex_form, typex,
+ convert (typex, arg0),
+ convert (typex, arg1)));
}
}
}
> Johann
>