This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Avoid coalescing enum and int variables


The new testcase fails on the 4.3 branch because we end up coalescing
a variable of type my_enum and one of type unsigned int to the
unsigned int one.  This causes the comparison to be changed from
performed in type unsinged int to my_enum which causes VRP to
optimize the test away.

The following patch presents a workaround to this issue (on
newer branches the issue has gone latent because there is a
copyprop before the coalescing which removes the opportunity).

The main problem here is that the middle-end type-system does not
care about TYPE_MIN/MAX_VALUE but assumes they are equal to ones
derived from TYPE_PRECISION (which means that the middle-end doesn't
want to have arithmetic one on types where there is a mismatch in
this properties).  Now, at least on the 4.3 branch the C++ frontend
has a TYPE_PRECISION of 32 for my_enum which makes conversions
useless between my_enum and unsigned int.  Oops.

Now, VRP is the only pass that makes use of TYPE_MIN/MAX_VALUE
and we could change it to just derive the min/max values it uses
from TYPE_PRECISION.

As one of the reasons we perform the coalescing is to get back
user-variables from temporaries gimplification introduced it
is sensible to not glob different type kinds to the same base
variable (it might even be sensible to require strict type
equivalence instead of using types_compatible_p).

Now, with all the above written, are there any comments on the issue?

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Thanks,
Richard.

2010-08-26  Richard Guenther  <rguenther@suse.de>

        * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Do not
        coalesce different type kinds.

        * g++.dg/torture/20100825.C: New testcase.

Index: gcc/tree-ssa-copyrename.c
===================================================================
*** gcc/tree-ssa-copyrename.c	(revision 163549)
--- gcc/tree-ssa-copyrename.c	(working copy)
*************** copy_rename_partition_coalesce (var_map
*** 227,233 ****
      }
  
    /* Don't coalesce if the two variables aren't type compatible.  */
!   if (!types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2)))
      {
        if (debug)
  	fprintf (debug, " : Incompatible types.  No coalesce.\n");
--- 227,234 ----
      }
  
    /* Don't coalesce if the two variables aren't type compatible.  */
!   if (TREE_CODE (TREE_TYPE (root1)) != TREE_CODE (TREE_TYPE (root2))
!       || !types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2)))
      {
        if (debug)
  	fprintf (debug, " : Incompatible types.  No coalesce.\n");
Index: gcc/testsuite/g++.dg/torture/20100825.C
===================================================================
*** gcc/testsuite/g++.dg/torture/20100825.C	(revision 0)
--- gcc/testsuite/g++.dg/torture/20100825.C	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ // { dg-do run }
+ 
+ typedef enum { zero = 0, one = 1, two = 2, ENUM_MAX = 3 } my_enum;
+ my_enum e;
+ extern "C" void abort (void);
+ int __attribute__((noinline)) foo() { return 10; }
+ int main()
+ {
+   int r;
+   r = foo();
+   if ((r < 0) || (r >= ENUM_MAX))
+     return 0;
+   e = (my_enum)r;
+   abort ();
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]