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

            Bug ID: 83247
           Summary: simplify (int)a_long < 0 when we know a_long fits in
                    int
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: glisse at gcc dot gnu.org
  Target Milestone: ---

This code is based on basic_string_view::_S_compare, which should probably be
improved (just cast if int is big enough, otherwise always return something in
{-1,0,1}), but here is the missed optimization:

bool f(long long l){
  if(l>1000) return false;
  if(l<-1000) return true;
  return (int)l<0;
}

It is equivalent to l<0, but not that easy for the compiler. Without the cast
in the last line, reassoc1 manages to get rid of the test l<-1000 and reassoc2
deals with l>1000. But with the cast, we are stuck. The easiest way I can think
of is in VRP to notice that l fits in int and simplify (int)l<0 to l<0 (which
the reassoc passes can handle later). On the other hand, as with all those
narrowing / promotion transformations, it isn't always clear if it is
beneficial by itself. If long long is emulated using 2 int-sized registers,
(int)l<0 is clearly cheaper than l<0, which only becomes worth it because of
the simplifications it allows.

Reply via email to