[Bug c/71598] Wrong optimization with aliasing enums

2019-04-05 Thread clyon at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #16 from Christophe Lyon  ---
Author: clyon
Date: Fri Apr  5 15:10:12 2019
New Revision: 270168

URL: https://gcc.gnu.org/viewcvs?rev=270168=gcc=rev
Log:
[testsuite] PR71598: Fix testcases again

2019-04-05  Christophe Lyon  

PR c/71598
* gcc.dg/torture/pr71598-1.c: dg-prune arm linker messages about
size of enums.
* gcc.dg/torture/pr71598-2.c: Likewise.


Modified:
trunk/gcc/testsuite/ChangeLog
trunk/gcc/testsuite/gcc.dg/torture/pr71598-1.c
trunk/gcc/testsuite/gcc.dg/torture/pr71598-2.c

[Bug c/71598] Wrong optimization with aliasing enums

2019-04-03 Thread clyon at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #15 from Christophe Lyon  ---
Author: clyon
Date: Wed Apr  3 13:17:04 2019
New Revision: 270126

URL: https://gcc.gnu.org/viewcvs?rev=270126=gcc=rev
Log:
[testsuite] PR71598: Fix testcases

2019-04-13  Christophe Lyon  

PR c/71598
* gcc.dg/torture/pr71598-1.c: Skip if short_enums target.
* gcc.dg/torture/pr71598-2.c: Skip if not short_enums target.


Modified:
trunk/gcc/testsuite/ChangeLog
trunk/gcc/testsuite/gcc.dg/torture/pr71598-1.c
trunk/gcc/testsuite/gcc.dg/torture/pr71598-2.c

[Bug c/71598] Wrong optimization with aliasing enums

2019-04-01 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #13 from Richard Biener  ---
Author: rguenth
Date: Mon Apr  1 07:16:38 2019
New Revision: 270052

URL: https://gcc.gnu.org/viewcvs?rev=270052=gcc=rev
Log:
2019-04-01  Richard Biener  

PR c/71598
* gimple.c: Include langhooks.h.
(gimple_get_alias_set): Treat enumeral types as the underlying
integer type.

c/
* c-tree.h (c_get_alias_set): Declare.
* c-objc-common.h (LANG_HOOKS_GET_ALIAS_SET): Use c_get_alias_set.
* c-objc-common.c (c_get_alias_set): Treat enumeral types
as the underlying integer type.

* gcc.dg/torture/pr71598-1.c: New testcase.
* gcc.dg/torture/pr71598-2.c: Likewise.
* gcc.dg/torture/pr71598-3.c: Likewise.

Added:
trunk/gcc/testsuite/gcc.dg/torture/pr71598-1.c
trunk/gcc/testsuite/gcc.dg/torture/pr71598-2.c
trunk/gcc/testsuite/gcc.dg/torture/pr71598-3.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/c/ChangeLog
trunk/gcc/c/c-objc-common.c
trunk/gcc/c/c-objc-common.h
trunk/gcc/c/c-tree.h
trunk/gcc/gimple.c
trunk/gcc/testsuite/ChangeLog

[Bug c/71598] Wrong optimization with aliasing enums

2019-04-01 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

Richard Biener  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
  Known to work||9.0
 Resolution|--- |FIXED
  Known to fail||7.4.0, 8.3.0

--- Comment #14 from Richard Biener  ---
Fixed for GCC 9+.

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-15 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #12 from Richard Biener  ---
Created attachment 45973
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45973=edit
patch I am testing

I am testing the following.  I needed to adjust the testcase a bit to make
the C++ FE happy, in particular casting the arguments to the function to
pointer-to-enum type and storing an enum member rather than an integer
(the conversion on the return stmts seems to work):

enum e1 { c1 };

__attribute__((noinline,noclone))
int f(enum e1 *p, unsigned *q)
{
  *p = c1;
  *q = 2;
  return *p;
}

int main()
{
  unsigned x;

  if (f((enum e1 *), ) != 2)
__builtin_abort();
  return 0;
}

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-15 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #11 from Eric Botcazou  ---
> I see.  Do you prefer a langhook solution that would "fix" this only
> for C/C++ and LTO then?

That sounds like the best approach to me, but I'm no expert here.

> OK, I see.  VRP still expects it to exist though (just not for
> pointer types).  Anyhow, I'm probably leaning towards looking at
> TYPE_SIZE.  Hopefully "incomplete" enums do not exist ;)

Yes, sorry, we do call set_min_and_max_values_for_integral_type to set the
bounds on them so you're probably running into the dreaded circularity.

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-15 Thread rguenther at suse dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #10 from rguenther at suse dot de  ---
On Fri, 15 Mar 2019, ebotcazou at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598
> 
> --- Comment #9 from Eric Botcazou  ---
> > Btw, I tried to use TREE_TYPE (TYPE_MIN_VALUE ()) of the ENUMERAL_TYPE but
> > that breaks with Ada (bah, no libbacktrace support there...):
> 
> Probably because of:
> 
>   /* Note that the bounds are updated at the end of this function
>  to avoid an infinite recursion since they refer to the type.  */
>   goto discrete_type;
> 
> > That is, input from language frontend maintainers is still needed as to
> > how to get at the integer type an enum type has to be compatible with
> > TBAA-wise and how to query whether there is any.  For the above Ada issue
> > the code could be amended to simply not do anything special for
> > ENUMERAL_TYPE without a TYPE_MIN_VALUE.
> 
> In Ada, enumeration and integer types are totally unrelated to each other.

I see.  Do you prefer a langhook solution that would "fix" this only
for C/C++ and LTO then?

> > I didn't yet try to debug what the Ada issue above is and what weird
> > kind of ENUMERAL_TYPEs Ada has ...
> 
> We probably don't set TYPE_MIN_VALUE at all to avoid the circularity.

OK, I see.  VRP still expects it to exist though (just not for
pointer types).  Anyhow, I'm probably leaning towards looking at
TYPE_SIZE.  Hopefully "incomplete" enums do not exist ;)

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-15 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #9 from Eric Botcazou  ---
> Btw, I tried to use TREE_TYPE (TYPE_MIN_VALUE ()) of the ENUMERAL_TYPE but
> that breaks with Ada (bah, no libbacktrace support there...):

Probably because of:

  /* Note that the bounds are updated at the end of this function
 to avoid an infinite recursion since they refer to the type.  */
  goto discrete_type;

> That is, input from language frontend maintainers is still needed as to
> how to get at the integer type an enum type has to be compatible with
> TBAA-wise and how to query whether there is any.  For the above Ada issue
> the code could be amended to simply not do anything special for
> ENUMERAL_TYPE without a TYPE_MIN_VALUE.

In Ada, enumeration and integer types are totally unrelated to each other.

> I didn't yet try to debug what the Ada issue above is and what weird
> kind of ENUMERAL_TYPEs Ada has ...

We probably don't set TYPE_MIN_VALUE at all to avoid the circularity.

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-15 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |rguenth at gcc dot 
gnu.org

--- Comment #8 from Richard Biener  ---
Btw, I tried to use TREE_TYPE (TYPE_MIN_VALUE ()) of the ENUMERAL_TYPE but
that breaks with Ada (bah, no libbacktrace support there...):

make[3]: ***
[/space/rguenther/src/svn/trunk/gcc/ada/gcc-interface/Make-lang.in:1033:
ada/libgnat/a-except.o] Error 1
+===GNAT BUG DETECTED==+
| 9.0.1 20190314 (experimental) (x86_64-pc-linux-gnu) Storage_Error stack
overflow or erroneous memory access|
| Error detected at lib-xref-spark_specific.adb:39:37  |
| Please submit a bug report; see https://gcc.gnu.org/bugs/ .  |
| Use a subject line meaningful to you and us to track the bug.|
| Include the entire contents of this bug box in the report.   |
| Include the exact command that you entered.  |
| Also include sources listed below.   |
+==+

Please include these source files with error report


btw, fixing this in get_alias_set would make this transitive (but exact
behavior is still implementation defined!).

That is, input from language frontend maintainers is still needed as to
how to get at the integer type an enum type has to be compatible with
TBAA-wise and how to query whether there is any.  For the above Ada issue
the code could be amended to simply not do anything special for
ENUMERAL_TYPE without a TYPE_MIN_VALUE.

For C I guess the type of TYPE_MIN_VALUE matches the type the enum is
compatible with, for C++ I would hope so as well.  Testcases covering
also -fshort-enum should be easy to write.

Note anything involving a langhook is going to not work with LTO.

Note another possibility would be (given that most FEs, including LTO,
make unsigned and signed type variants compatible) to look at the
ENUMERAL_TYPEs mode and use the corresponding (unsigned) integer type
as compatible type.  That may not work for under-aligned enums though
where the mode may end up as BLKmode...  which means we'd need to look
at TYPE_SIZE instead.

I didn't yet try to debug what the Ada issue above is and what weird
kind of ENUMERAL_TYPEs Ada has ...

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-14 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #7 from joseph at codesourcery dot com  ---
The relation definitely is not transitive (so you can't declare the same 
function to return two different enum types, for example).

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-14 Thread amonakov at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #6 from Alexander Monakov  ---
... and even considering that the standard never actually says that "compatible
type" relation is transitive, and so two enums technically need not be
compatible with each other, the following should follow the standard to the
letter, but is still optimized to 'return 1':

enum e1 { c1=2 };

int f(unsigned *p, enum e1 *q)
{
  *p = 1;
  *q = c1;
  return *p;
}

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-14 Thread amonakov at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #5 from Alexander Monakov  ---
C11 6.7.2.2 p4 says,

  Each enumerated type shall be compatible with char, a signed integer type, or
an unsigned integer type [...]

and 6.5 p7 says,

  An object shall have its stored value accessed only by an lvalue expression
that has one of the following types:

* a type compatible with the effective type of the object

(and the third bullet answers my implicit question in comment #2 about
signed/unsigned aliases).

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-14 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

--- Comment #4 from Richard Biener  ---
Note I can't find any bit in the C standard that would make the testcase
well-defined and support reporters view.  My clang version doesn't "miscompile"
it though.

With LTO we'd treat both enum declarations as compatible wrt TBAA but they
wouldn't be compatible with unsigned int (so in GCC speak both enums get
the same TYPE_CANONICAL but that isn't TYPE_CANONICAL of unsigned int).

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-14 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

Richard Biener  changed:

   What|Removed |Added

 CC||ebotcazou at gcc dot gnu.org,
   ||jason at gcc dot gnu.org,
   ||jsm28 at gcc dot gnu.org

--- Comment #3 from Richard Biener  ---
get_alias_set does nothing special for ENUMERAL_TYPE which means distinct
enums get distinct alias sets.  Iff the C standard says that from a TBAA
perspective an enumeral type is to be treated as one of the standard
integer types then we need a way to represent such type in the middle-end
or the frontends need to not expose the distinct ENUMERAL_TYPE (at least
in accesses) but whatever underlying type is to be used.

Note since this targets the middle-end behavior the required language
semantics of other languages play a role as well.

A conservative middle-end only patch could look like the following - possibly
also a good idea for LTO.  Eventually we could settle on the ENUMERAL_TYPEs
TYPE_VALUES first entry type to specify that underlying type, but that would
need agreement.  It looks like TREE_TYPE of an ENUMERAL_TYPE is also not
"taken" (but all FEs needing the get_alias_set treatment would need adjustment,
at least it could be conditional on TREE_TYPE set).  The TYPE_VALUES idea
would leave us with no way to handle empty enums.  Another thing to look
at would be TREE_TYPE (TYPE_MIN/MAX_VALUE), for the testcase and the C FE
it is unsigned int.

diff --git a/gcc/alias.c b/gcc/alias.c
index b64e3ea264d..8fbf34bf4dc 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -931,6 +931,11 @@ get_alias_set (tree t)
   if (set != -1)
 return set;

+  /* Enums inter-operate with the corresponding integer type.  */
+  else if (TREE_CODE (t) == ENUMERAL_TYPE)
+return get_alias_set (build_nonstandard_integer_type
+   (TYPE_PRECISION (t), TYPE_UNSIGNED (t)));
+
   /* There are no objects of FUNCTION_TYPE, so there's no point in
  using up an alias set for them.  (There are, of course, pointers
  and references to functions, but that's different.)  */

[Bug c/71598] Wrong optimization with aliasing enums

2019-03-14 Thread amonakov at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

Alexander Monakov  changed:

   What|Removed |Added

   Keywords||wrong-code
   Last reconfirmed|2017-07-29 00:00:00 |2019-3-14
 CC||amonakov at gcc dot gnu.org,
   ||rguenth at gcc dot gnu.org

--- Comment #2 from Alexander Monakov  ---
Optimized to 'return 1' already in fre1.

At the same time, accesses via 'int *' vs. 'unsigned *' potentially conflict in

int f(int *p, unsigned *q)
{
  *p = 1;
  *q = 2;
  return *p;
}

[Bug c/71598] Wrong optimization with aliasing enums

2017-07-29 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71598

Eric Gallager  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2017-07-29
 CC||egallager at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #1 from Eric Gallager  ---
Confirmed (that the testcase aborts when run)