Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does gcc complain about my loops?

Tags:

I have some fairly trivial code, still gcc complains (in -O3 -march=native) about loop unrolling:

cannot optimize loop, the loop counter may overflow [-Wunsafe-loop-optimizations] for(auto& plan : fw) ^ 

Here is a (stripped of all fftw stuff, else it would be quite long) version of my code

class FFTWManager {     public:         void setChannels(unsigned int n)         {             fw.resize(n);             bw.resize(n);                             //some fftw-specific stuff comes here         }          void forward()         {             for(auto& plan : fw)                 fftw_execute(plan);         }          void backward()         {             for(auto& plan : bw)                 fftw_execute(plan);         }      private:         std::vector<fftw_plan> fw = {};         std::vector<fftw_plan> bw = {}; }; 

The vectors never exceed a size of 2 in my code.


Edits according to comments : I use a lot of flags.

-pedantic -Wextra -Weffc++ -Wall -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wconversion -Wdisabled-optimization -Wformat -Wformat=1 -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimport -Winit-self -Winline -Winvalid-pch -Wunsafe-loop-optimizations -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstack-protector -Wstrict-aliasing=3 -Wswitch -Wswitch-default -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings

I don't see the point of speaking of putting infos about fftw_execute here but if you want to see the whole code (that I judged too long for a SO post), it's here : https://github.com/jcelerier/watermarking/blob/master/src/libwatermark/transform/FFTWManager.h

GCC : gcc version 4.8.2 (Debian 4.8.2-10)

I don't see why changing from unsigned int to size_type would change anything since I don't get any warning in my setChannels method (even if I think it's long unsigned int on my platform) and once the size is set, the original type of the variable that was used to set it seems quite irrelevant to me.

There is no warning with the basic for(int i = 0; i < bw.size(); i++) or with the iterator version for(auto i = bw.begin(); i != bw.end(); i++).

I also tried with clang, which seems to recognize the warning swich so I guess they also implemented the optimization, and I don't get any warnings (but much quicker compile times \o)

Sorry about long feedback, I was out.

like image 605
Jean-Michaël Celerier Avatar asked Dec 31 '13 14:12

Jean-Michaël Celerier


1 Answers

From gcc manual:

-funsafe-loop-optimizations

This option tells the loop optimizer to assume that loop indices do not overflow, and that loops with nontrivial exit condition are not infinite. This enables a wider range of loop optimizations even if the loop optimizer itself cannot prove that these assumptions are valid. If you use -Wunsafe-loop-optimizations, the compiler warns you if it finds this kind of loop.

Thus, apparently, the implementation of range-for loop in the compiler is somehow broken in that it triggers this warning. You could either disable this particular warning or disable this particular optimization... I would advise the latter as it is unclear to me whether the optimization is actually done or not when the warning is triggered.

like image 67
Matthieu M. Avatar answered Sep 20 '22 15:09

Matthieu M.