This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR middle-end/19874: Tweak STRIP_USELESS_TYPE_CONVERSION
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 24 Feb 2005 21:30:36 -0700 (MST)
- Subject: [PATCH] PR middle-end/19874: Tweak STRIP_USELESS_TYPE_CONVERSION
The following patch is my proposed change to resolve PR middle-end/19874
which is an ICE-on-valid regression on mainline caused by emit_move_insn
being passed incompatible modes for source and destination. The problem,
analaysed by Jakub Jelinek was that STRIP_USELESS_TYPE_CONVERSION was
stripping a mode changing conversion due to lang_hooks.types_compatible_p
for the C/C++ front-ends claiming that two types were compatible as they
have the same TYPE_MAIN_VARIANT.
Jakub's suggested fix, described in the bugzilla PR, was to tweak the
handle_mode_attribute function in c-common.c and comptypes function in
c-typeck.c, to change "types_compatible_p", which unfortunately breaks
the C++ front-end.
The alternate solution below is to tweak tree_ssa_useless_type_conversion
such that no conversion that changes the mode of it's operand is
considered "useless". This intuitive approach also simplifies the code
in that function, which guarantees the modes match in every case except
for the front-end's notion of type compatability. Indeed, I'm not sure
the front-end's type system should be affecting the optimizations
performed at this point in tree-ssa.
This approach is probably contentious, so I'll check with folks whether
they feel this fix is too conservative and potentially misses useful
optimizations.
The following patch has been tested on i686-pc-linux-gnu with a full "make
bootstrap", all default languages, and regression tested with a top-level
"make -k check" with no new failures. Jakub's testcase passes with this
patch but fails without it.
Ok for mainline?
2005-02-24 Roger Sayle <roger@eyesopen.com>
PR middle-end/19874
* tree-ssa.c (tree_ssa_useless_type_conversion_1): A conversion
between different machine modes is never a "useless" conversion.
2005-02-24 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20050119-2.c: New test case.
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa.c,v
retrieving revision 2.78
diff -c -3 -p -r2.78 tree-ssa.c
*** tree-ssa.c 23 Feb 2005 05:08:24 -0000 2.78
--- tree-ssa.c 24 Feb 2005 00:06:13 -0000
*************** delete_tree_ssa (void)
*** 778,788 ****
bool
tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
{
/* If the inner and outer types are effectively the same, then
strip the type conversion and enter the equivalence into
the table. */
! if (inner_type == outer_type
! || (lang_hooks.types_compatible_p (inner_type, outer_type)))
return true;
/* If both types are pointers and the outer type is a (void *), then
--- 778,794 ----
bool
tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
{
+ if (inner_type == outer_type)
+ return true;
+
+ /* Changes in machine mode are never useless conversions. */
+ if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type))
+ return false;
+
/* If the inner and outer types are effectively the same, then
strip the type conversion and enter the equivalence into
the table. */
! if (lang_hooks.types_compatible_p (inner_type, outer_type))
return true;
/* If both types are pointers and the outer type is a (void *), then
*************** tree_ssa_useless_type_conversion_1 (tree
*** 793,799 ****
implement the ABI. */
else if (POINTER_TYPE_P (inner_type)
&& POINTER_TYPE_P (outer_type)
- && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
&& TYPE_REF_CAN_ALIAS_ALL (inner_type)
== TYPE_REF_CAN_ALIAS_ALL (outer_type)
&& TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
--- 799,804 ----
*************** tree_ssa_useless_type_conversion_1 (tree
*** 803,809 ****
so strip conversions that just switch between them. */
else if (POINTER_TYPE_P (inner_type)
&& POINTER_TYPE_P (outer_type)
- && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
&& TYPE_REF_CAN_ALIAS_ALL (inner_type)
== TYPE_REF_CAN_ALIAS_ALL (outer_type)
&& lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
--- 808,813 ----
*************** tree_ssa_useless_type_conversion_1 (tree
*** 819,825 ****
mean that testing of precision is necessary. */
else if (INTEGRAL_TYPE_P (inner_type)
&& INTEGRAL_TYPE_P (outer_type)
- && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
&& TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
&& TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
{
--- 823,828 ----
/* PR middle-end/19874 */
typedef enum { A, B, C, D } E;
struct S {
E __attribute__ ((mode (__byte__))) a;
E __attribute__ ((mode (__byte__))) b;
E __attribute__ ((mode (__byte__))) c;
E __attribute__ ((mode (__byte__))) d;
};
extern void abort (void);
extern void exit (int);
E
foo (struct S *s)
{
if (s->a != s->b)
abort ();
if (s->c != C)
abort ();
return s->d;
}
int
main (void)
{
struct S s[2];
s[0].a = B;
s[0].b = B;
s[0].c = C;
s[0].d = D;
s[1].a = D;
s[1].b = C;
s[1].c = B;
s[1].d = A;
if (foo (s) != D)
abort ();
exit (0);
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833