[Bug middle-end/4210] should not warn in dead code

2020-06-05 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #43 from Marc Glisse  ---
(In reply to Niels Möller from comment #42)
> And what's the easiest way to run the the right compiler process (I guess
> that's cc1) under gdb?

gcc -c t.c -wrapper gdb,--args

[Bug middle-end/4210] should not warn in dead code

2020-06-04 Thread nisse at lysator dot liu.se
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #42 from Niels Möller  ---
Created attachment 48678
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48678&action=edit
Add a new pass for emitting the warning (not working)

Since adding a new pass seems to be the right way, I've given that a try. See
patch. By my printf debugging I can see that the pass is instantiated and the
execute method is invoked twice (same example program):

unsigned 
shift_dead (unsigned x)
{
  if (0)
return x >> 32;
  else
return x >> 1;
}

unsigned 
shift_invalid (unsigned x)
{
  return x >> 32;
}

But no further printouts, it seems my loop 

+void
+do_warn_shift_count_range (gimple_seq seq)
+{
+  gimple_stmt_iterator i;
+  for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))

exits before a single iteration. My intention was that it should iterate over
the body of the current function (i.e., fun->gimple_body), which I expect to be
a single return statement after the cfg pass has removed dead code. I'm
probably misunderstanding the data structures.

And what's the easiest way to run the the right compiler process (I guess
that's cc1) under gdb?

[Bug middle-end/4210] should not warn in dead code

2020-05-06 Thread nisse at lysator dot liu.se
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #41 from Niels Möller  ---
(In reply to Manuel López-Ibáñez from comment #39)

> You can easily find which pass does something by dumping (-ftree-dump-*)
> all of them and comparing them.

It's -ftree-dump-all, and also -fdump-passes was useful. Thanks! I'm now
compiling without optimization to (i) reduce number of passes, and (ii) because
it would be nice to get it right also in absence of optimization options.

It looks like the dead code is eliminated by the "cfg" (control flow graph)
pass, in gcc/tree-cfg.c. In the .cfg dumpfile it says "Removing basic block 3",
and the invalid shift disappears in that dump. That's nice. Immediately after
this pass comes *warn_function_return, implemented in the same file.

It would make sense to me to add a pass to warn about shift operations with
invalid constant operands at about the same place. Is it easy to traverse a
gimple function, and check all expressions? The "*warn_unused_result" pass
seems to do a similar traversal (but examining statements rather than
expressions, and done *before* the cfg pass).

[Bug middle-end/4210] should not warn in dead code

2020-05-06 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

Eric Gallager  changed:

   What|Removed |Added

 CC||egallager at gcc dot gnu.org

--- Comment #40 from Eric Gallager  ---
(In reply to Manuel López-Ibáñez from comment #39)
> I think these questions are more appropriate for the mailing list, since
> few people are subscribed to this bug.

There were more previously, but a lot of people got dropped from cc lists all
throughout bugzilla in the process of transferring servers... I was on this one
previously, for example, but now I'm having to re-subscribe... 

> 
> You can easily find which pass does something by dumping (-ftree-dump-*)
> all of them and comparing them.
> 
> On Wed, 6 May 2020, 09:11 nisse at lysator dot liu.se, <
> gcc-bugzi...@gcc.gnu.org> wrote:
> 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
> >
> > --- Comment #38 from Niels Möller  ---
> > Just a brief update.
> >
> > 1. Tried adding fprintf warnings to c_gimplify_expr (btw, what's the right
> > way
> > to display a pretty warning with line numbers etc in later passes?). But it
> > seems that's too early, I still get warnings for dead code.
> >
> > 2. The pass_remove_useless_stmts, mentioned in the docs, was deleted in
> > 2009
> > (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41573), and I take it
> > it was
> > obsoleted earlier, since there's no mention of a replacement. So what pass
> > should I look at that is related to basic control flow analysis, and
> > discarding
> > unreachable statements?
> >
> > --
> > You are receiving this mail because:
> > You are on the CC list for the bug.

[Bug middle-end/4210] should not warn in dead code

2020-05-06 Thread lopezibanez at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #39 from Manuel López-Ibáñez  ---
I think these questions are more appropriate for the mailing list, since
few people are subscribed to this bug.

You can easily find which pass does something by dumping (-ftree-dump-*)
all of them and comparing them.

On Wed, 6 May 2020, 09:11 nisse at lysator dot liu.se, <
gcc-bugzi...@gcc.gnu.org> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
>
> --- Comment #38 from Niels Möller  ---
> Just a brief update.
>
> 1. Tried adding fprintf warnings to c_gimplify_expr (btw, what's the right
> way
> to display a pretty warning with line numbers etc in later passes?). But it
> seems that's too early, I still get warnings for dead code.
>
> 2. The pass_remove_useless_stmts, mentioned in the docs, was deleted in
> 2009
> (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41573), and I take it
> it was
> obsoleted earlier, since there's no mention of a replacement. So what pass
> should I look at that is related to basic control flow analysis, and
> discarding
> unreachable statements?
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.

[Bug middle-end/4210] should not warn in dead code

2020-05-06 Thread nisse at lysator dot liu.se
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #38 from Niels Möller  ---
Just a brief update.

1. Tried adding fprintf warnings to c_gimplify_expr (btw, what's the right way
to display a pretty warning with line numbers etc in later passes?). But it
seems that's too early, I still get warnings for dead code.

2. The pass_remove_useless_stmts, mentioned in the docs, was deleted in 2009
(see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41573), and I take it it was
obsoleted earlier, since there's no mention of a replacement. So what pass
should I look at that is related to basic control flow analysis, and discarding
unreachable statements?

[Bug middle-end/4210] should not warn in dead code

2020-05-05 Thread nisse at lysator dot liu.se
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #37 from Niels Möller  ---
(In reply to Manuel López-Ibáñez from comment #35)
> There is no such place. Dead code is identified in the middle-end and by
> then, there is no parse tree, only GIMPLE and SSA:
> https://gcc.gnu.org/onlinedocs/gccint/Passes.html#Passes

So if emission of the warning is postponed to after the Tree SSA passes
(https://gcc.gnu.org/onlinedocs/gccint/Tree-SSA-passes.html#Tree-SSA-passes).
Could perhaps be inserted just after (or as part of) pass_remove_useless_stmts?

> > 3. Alternatively, [...] construct a special tree object representing an
> > expression with invalid/undefined behavior, and any meta data needed to emit
> > a warning or error to describe it? Then emission of the warning could be
> > postponed to later, say, close to the conversion to SSA form?
> 
> That is still too early, since the dead code elimination happens after SSA.

Then that special value needs to be passed through the conversions to gimple
and SSA. I imagine it could be treated much like a compile time constant, but
with an annotation saying it's invalid, and why, to be displayed in case the
compiler thinks it needs to generate any code to evaluate it. (And if we go
that route, we should probably do the same for most or all warnings on invalid
operands detected by the frontend).

[Bug middle-end/4210] should not warn in dead code

2020-05-05 Thread nisse at lysator dot liu.se
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #36 from Niels Möller  ---
(In reply to Martin Sebor from comment #34)
> 
> The front ends can eliminate simple subexpressions (as in '0 ? x >> 32 : x
> >> 1') but they don't do the same for statements.  Moving the warning from
> the front end to some later pass would avoid diagnosing code in those cases
> (it would also avoid duplicating the same code between different front
> ends).  The earliest is probably gimplify.c.  That would avoid warning on
> statements rendered dead as a result of constant expressions (as defined by
> the language) but not [...]

Thanks. So moving the warning to the gimplify pass would be an improvement over
the current situation. Maybe I can try it out, it sounds reasonably simple.

[Bug middle-end/4210] should not warn in dead code

2020-05-05 Thread manu at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

--- Comment #35 from Manuel López-Ibáñez  ---
(In reply to Niels Möller from comment #32)
> 1. There's similar code in c_fully_fold_internal, in gcc/c/c-fold.c, close
> to line 400. But that code does *not* emit any warning for the example
> above, which surprised me a bit. Maybe that's only for the case that both
> operands to the shift operator are constants?

In general, front-ends should avoid emitting warnings while folding
(simplifying) expressions. I think there is an open bug about this but I cannot
find it now.

Of course, if the code is doing the same, it should be factored out into a
common function. A good first patch to submit:
https://gcc.gnu.org/wiki/GettingStarted#Basics:_Contributing_to_GCC_in_10_easy_steps

> 2. More importantly, if the warning is deleted from build_binary_op, we need
> to add a check for this case, and an appropriate warning, somewhere later in
> the compilation process. It has to be done after dead code is identified,
> i.e., in a phase processing only non-dead code. And preferably as early as
> possibly, when we're still working close to the parse-tree representation.
> Is there such a place? Some other functions traversing the tree are
> c_gimplify_expr (gcc/c-family/c-gimplify.c) and verify_tree
> (gcc/c-family/c-common.c), are any of those called after elimination of dead
> code?

There is no such place. Dead code is identified in the middle-end and by then,
there is no parse tree, only GIMPLE and SSA:
https://gcc.gnu.org/onlinedocs/gccint/Passes.html#Passes

Of course, you could add some kind of unreachable code pass to the FE, but that
would require a lot of work from your side. Clang has something similar that
you could use as an inspiration: 

https://github.com/llvm/llvm-project/blob/2946cd701067404b99c39fb29dc9c74bd7193eb3/clang/include/clang/Analysis/Analyses/ReachableCode.h

> 3. Alternatively, if there's no place after dead code elimination where the
> parse tree is still easily available, a different alternative could be to
> leave the check for invalid shift counts in c-typeck.c, but instead of
> emitting a warning, construct a special tree object representing an
> expression with invalid/undefined behavior, and any meta data needed to emit
> a warning or error to describe it? Then emission of the warning could be
> postponed to later, say, close to the conversion to SSA form?

That is still too early, since the dead code elimination happens after SSA.

[Bug middle-end/4210] should not warn in dead code

2020-05-05 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210

Martin Sebor  changed:

   What|Removed |Added

Summary|should not warning with |should not warn in dead
   |dead code   |code
 CC||msebor at gcc dot gnu.org

--- Comment #34 from Martin Sebor  ---
(In reply to Niels Möller from comment #32)

The front ends can eliminate simple subexpressions (as in '0 ? x >> 32 : x >>
1') but they don't do the same for statements.  Moving the warning from the
front end to some later pass would avoid diagnosing code in those cases (it
would also avoid duplicating the same code between different front ends).  The
earliest is probably gimplify.c.  That would avoid warning on statements
rendered dead as a result of constant expressions (as defined by the language)
but not those whose constant value GCC later propagates from prior assignments,
such as in

  const int zero = 0;

  unsigned 
  shift_dead (unsigned x)
  {
if (zero)
  return x >> 32;
else
  return x >> 1;
  }

The later the warning is moved the more statements will be eliminated as dead,
but the more other transformations will also be applied that might eliminate
the warning where it might be desirable, or perhaps even introduce it where it
wouldn't be issued otherwise.