Bug 81408 - Lots of new -Wunsafe-loop-optimizations warnings with 7 compared to 6
Summary: Lots of new -Wunsafe-loop-optimizations warnings with 7 compared to 6
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.1.0
: P3 normal
Target Milestone: ---
Assignee: amker
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2017-07-12 08:45 UTC by Julian Andres Klode
Modified: 2017-08-07 13:49 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-07-12 00:00:00


Attachments
Minimized example (196 bytes, text/x-csrc)
2017-07-12 08:45 UTC, Julian Andres Klode
Details
preprocessed source of a.cc (101.55 KB, text/plain)
2017-07-12 08:46 UTC, Julian Andres Klode
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Julian Andres Klode 2017-07-12 08:45:20 UTC
Created attachment 41726 [details]
Minimized example

Compiling a recent apt with g++-7 causes a lot more unsafe loop optimizations warnings than g++ 6 did (134 vs 8). That's a massive regression.

7.1.0 build log: https://launchpadlibrarian.net/327296659/buildlog_ubuntu-artful-i386.apt_1.5~beta1_BUILDING.txt.gz

6.3.0 build log: https://launchpadlibrarian.net/326714445/buildlog_ubuntu-artful-i386.apt_1.5~beta1_BUILDING.txt.gz

It seems these are for-each kind of loops.

I attached a simple minimized example from one of the cases mentioned in the log.
Comment 1 Julian Andres Klode 2017-07-12 08:46:47 UTC
Created attachment 41727 [details]
preprocessed source of a.cc
Comment 2 Julian Andres Klode 2017-07-12 08:48:37 UTC
Build log with -v:

Using built-in specs.
COLLECT_GCC=/usr/bin/g++-7
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 7.1.0-9' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.1.0 (Debian 7.1.0-9) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-Wunsafe-loop-optimizations' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/7/cc1plus -E -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE a.cc -mtune=generic -march=x86-64 -Wunsafe-loop-optimizations -O2 -fpch-preprocess -o a.ii
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/7"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/7
 /usr/include/x86_64-linux-gnu/c++/7
 /usr/include/c++/7/backward
 /usr/lib/gcc/x86_64-linux-gnu/7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-Wunsafe-loop-optimizations' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/7/cc1plus -fpreprocessed a.ii -quiet -dumpbase a.cc -mtune=generic -march=x86-64 -auxbase a -O2 -Wunsafe-loop-optimizations -version -o a.s
GNU C++14 (Debian 7.1.0-9) version 7.1.0 (x86_64-linux-gnu)
	compiled by GNU C version 7.1.0, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++14 (Debian 7.1.0-9) version 7.1.0 (x86_64-linux-gnu)
	compiled by GNU C version 7.1.0, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 3681302eda59faba4e53a905eca4bf72
a.cc: In function ‘void ShowHelpListCommands(const std::vector<aptDispatchWithHelp>&)’:
a.cc:11:24: warning: missed loop optimization, the loop counter may overflow [-Wunsafe-loop-optimizations]
    for (auto const &c: Cmds)
                        ^~~~
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-Wunsafe-loop-optimizations' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -v --64 -o a.o a.s
GNU assembler version 2.28 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.28
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-O2' '-Wunsafe-loop-optimizations' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
Comment 3 Julian Andres Klode 2017-07-12 08:50:50 UTC
7.1.0-9 corresponds to "SVN 20170705 (r250006) from the gcc-7-branch."
Comment 4 Julian Andres Klode 2017-07-12 08:55:54 UTC
Note that apt has 1219 loops, so 134 is almost 11% of the loops causing the warning, compared to about 0.7% (8) before.
Comment 5 Martin Liška 2017-07-12 09:38:49 UTC
Confirmed, I reduced one test-case:

$ cat pr81408.ii
template <typename b, typename> class d
{
  b e;

public:
  int operator* () {}
  void operator++ () { ++e; }
  b
  base ()
  {
    return e;
  }
};
template <typename f, typename g, typename h>
bool
operator!= (d<f, h> i, d<g, h> j)
{
  return i.base () - j.base ();
}
template <typename> class k;
template <typename> struct m;
template <typename a> struct m<k<a>>
{
  using l = a *;
};
struct p : m<k<int>>
{
  d<l, int> begin ();
  d<l, int> end ();
} n;
void
o ()
{
  for (auto c : n)
    ;
}

Which started to be recognized with r242638. And I also noticed the original unreduced test-case started to be diagnosed with r238641.
That said it's probably better optimizer work that shows more warnings, am I right?
Comment 6 Martin Liška 2017-07-12 10:16:40 UTC
And there's sample which started to be reported with Bin's revision r238641:

namespace a {
void b () __attribute__ ((__noreturn__));
template <typename> struct d;
template <typename e> struct d<e *>
{
  typedef e f;
};
struct g
{
  template <typename h> using i = h *;
};
}
using a::d;
template <typename j, typename> class k
{
  j l;

public:
  typename d<j>::f operator* () {}
  void operator++ () { ++l; }
  j
  aa ()
  {
    return l;
  }
};
template <typename m, typename n, typename ab>
bool
operator!= (k<m, ab> o, k<n, ab> p2)
{
  return o.aa () != p2.aa ();
}
struct p;
namespace a {
struct F
{
  struct q
  {
    using ai = g::i<p>;
  };
  using r = q::ai;
};
class H
{
public:
  k<F::r, int> begin ();
  k<F::r, int> end ();
};
int s;
class I
{
public:
  void
  aq (char)
  {
    if (s)
      b ();
  }
};
class u : public I
{
public:
  void
  operator<< (u o (u))
  {
    o (*this);
  }
  u operator<< (void *);
};
template <typename at, typename au>
at
av (au o)
{
  o.aq ('\n');
}
u ax;
}
struct p
{
  char *ay;
};
a::H t;
void
ShowHelpListCommands ()
{
  for (auto c : t)
    a::ax << c.ay << a::av;
}
Comment 7 amker 2017-07-12 10:45:53 UTC
(In reply to Martin Liška from comment #6)
> And there's sample which started to be reported with Bin's revision r238641:
> 
> namespace a {
> void b () __attribute__ ((__noreturn__));
> template <typename> struct d;
> template <typename e> struct d<e *>
> {
>   typedef e f;
> };
> struct g
> {
>   template <typename h> using i = h *;
> };
> }
> using a::d;
> template <typename j, typename> class k
> {
>   j l;
> 
> public:
>   typename d<j>::f operator* () {}
>   void operator++ () { ++l; }
>   j
>   aa ()
>   {
>     return l;
>   }
> };
> template <typename m, typename n, typename ab>
> bool
> operator!= (k<m, ab> o, k<n, ab> p2)
> {
>   return o.aa () != p2.aa ();
> }
> struct p;
> namespace a {
> struct F
> {
>   struct q
>   {
>     using ai = g::i<p>;
>   };
>   using r = q::ai;
> };
> class H
> {
> public:
>   k<F::r, int> begin ();
>   k<F::r, int> end ();
> };
> int s;
> class I
> {
> public:
>   void
>   aq (char)
>   {
>     if (s)
>       b ();
>   }
> };
> class u : public I
> {
> public:
>   void
>   operator<< (u o (u))
>   {
>     o (*this);
>   }
>   u operator<< (void *);
> };
> template <typename at, typename au>
> at
> av (au o)
> {
>   o.aq ('\n');
> }
> u ax;
> }
> struct p
> {
>   char *ay;
> };
> a::H t;
> void
> ShowHelpListCommands ()
> {
>   for (auto c : t)
>     a::ax << c.ay << a::av;
> }

Yes, it's very likely my fault.  Thanks for reducing the test case.  I will investigate it.
Comment 8 amker 2017-07-13 16:23:18 UTC
After I deleted -funsafe-loop-optimizations in GIMPLE passes, there is no "unsafe-loop-optimizations" for any GIMPLE optimizers.  This message in actuality means missed loop optimizations.  I am preparing patch dumping the message to category MSG_MISSED_OPTIMIZATION.

On the other hand, I noticed the niter analysis for c++ iterator loop is bad.  I will create another PR for it.
Comment 9 Richard Biener 2017-07-17 11:17:26 UTC
Note that -Wunsafe-loop-optimizations is enabled at any -W level.  But yes, I agree it should be -fopt-info stuff.
Comment 10 amker 2017-07-18 11:41:10 UTC
Author: amker
Date: Tue Jul 18 11:40:38 2017
New Revision: 250304

URL: https://gcc.gnu.org/viewcvs?rev=250304&root=gcc&view=rev
Log:
	PR target/81408
	* tree-ssa-loop-niter.c (number_of_iterations_exit): Dump missed
	optimization for loop niter analysis.

	gcc/testsuite
	* g++.dg/tree-ssa/pr81408.C: New.
	* gcc.dg/tree-ssa/pr19210-1.c: Check dump message rather than warning.

Added:
    trunk/gcc/testsuite/g++.dg/tree-ssa/pr81408.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c
    trunk/gcc/tree-ssa-loop-niter.c
Comment 11 amker 2017-08-07 13:49:48 UTC
Fixed.