https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89501

--- Comment #11 from Jeffrey A. Law <law at redhat dot com> ---
WRT c#9.  Linus is right.  THe condition is dynamic and we don't want to remove
it in this circumstance.

More generally we  have considered whether or not we could eliminate the
control dependent path which leads to undefined behavior.  But you have to be
careful  because statements on the path prior to the actual undefined behavior
may have observable side effects.

So what we do in those cases is isolate the path  via block copying and CFG
manipulations (usually it's just a subset of paths to a particular statement
which result in undefined behavior).  Once the path is isolated we can replace
the statement which triggers the undefined behavior with a trap.  That in turn
allows some CFG simplifications, const/copy propagation and usually further
dead code elimination.

Right now we do this just for NULLs that are dereferenced and division by zero.
 But I can see doing it for out of bounds array indexing, bogus mem* calls and
perhaps other cases of undefined behavior.  ie, if you have something like

char foo[10];

if (shouldn't happen)
  indx = -1;
else
  indx = whatever ();
something = foo[indx];
... more work ...

This kind of idiom occurs fairly often when -1 is used to represent a can't
happen case and you've got abstraction layers that get eliminated via inlining.
 Path isolation would turn that into something like this:

if (shouldn't happen) {
  indx = -1
  trap;
} else {
  indx = whatever ();
  something = foo[indx];
}
... more work ...

Which will simplify in various useful ways.



--

If we were to apply those concepts to this example we'd conceptually turn the
code into something like this:

if (somecondition) {
    ret = functioncall(x);
    if (ret)
      return ret;
}
... some more work ...
trap

Reply via email to