hi, please consider following code snippet from large CairoMM base application. it creates a planar region with top left and bottom right points from two points passed to RegionT constructor. $ cat 0.cpp static inline int min( int a, int b ) { if ( a < b ) return a; return b; } static inline int max( int a, int b ) { if ( a > b ) return a; return b; } struct PointT { explicit PointT () { x = 0; y = 0; } explicit PointT ( int xVal, int yVal ) : x( xVal ), y( yVal ) {} int x, y; }; struct RegionT { explicit RegionT ( PointT const& p1, PointT const& p2 ) { // calculate top_left and bottom_right coordinates. // (0,0) ---> X // | // | // \/ // Y #ifdef WARN_AND_OPTIMIZE if ( p1.x < p2.x ) { tl.x = p1.x; br.x = p2.x; } else { tl.x = p2.x; br.x = p1.x; } if ( p1.y < p2.y ) { tl.y = p1.y; br.y = p2.y; } else { tl.y = p2.y; br.y = p1.y; } #else tl.x = min( p1.x, p2.x ); tl.y = min( p1.y, p2.y ); br.x = max( p1.x, p2.x ); br.y = max( p1.y, p2.y ); #endif } PointT tl, br; }; the application contains lots of places where a region is created from one base point and constant offsets, e.g.: RegionT foo ( PointT const& p ) { RegionT r ( p, PointT ( p.x - 2, p.y + 2 ) ); return r; } for such constructions and -DWARN_AND_OPTIMIZE gcc optimizes RegionT coordinates calculation at compile time and produces warnings about strict overflow assumptions. $ g++ 0.cpp -c -Wall -O2 -fdump-tree-optimized --save-temps -DWARN_AND_OPTIMIZE 0.cpp: In function 'RegionT foo(const PointT&)': 0.cpp:23:4: warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false 0.cpp:30:4: warning: assuming signed overflow does not occur when assuming that (X + c) >= X is always true RegionT foo(const PointT&) (const struct PointT & p) { int r$tl$y; int r$tl$x; struct RegionT D.2181; <bb 2>: r$tl$y_2 = p_1(D)->y; r$tl$y_3 = r$tl$y_2 + 2; r$tl$x_4 = p_1(D)->x; r$tl$x_5 = r$tl$x_4 + -2; D.2181.tl.x = r$tl$x_5; D.2181.tl.y = r$tl$y_2; D.2181.br.x = r$tl$x_4; D.2181.br.y = r$tl$y_3; return D.2181; } i known signed integer overflow rules but such construction is human readable and intended, so i would like to still have '-Wall -Werror' in action for all code and avoid disabling strict-overflow warings for *global* scope (originally RegionT is implemented as a template in header). for now, i've hacked in ugly way the if-logic in RegionT constructor to std::min/max variant. it doesn't warn but produces unoptimal code with CMOVs for compile time constants. RegionT foo(const PointT&) (const struct PointT & p) { int a; int a; struct RegionT D.2182; const int D.2178; <bb 2>: D.2178_2 = p_1(D)->y; a_3 = D.2178_2 + 2; a_4 = p_1(D)->x; a_7 = a_4 + -2; a_41 = MIN_EXPR <a_7, a_4>; a_45 = MIN_EXPR <a_3, D.2178_2>; a_42 = MAX_EXPR <a_7, a_4>; a_46 = MAX_EXPR <a_3, D.2178_2>; D.2182.tl.x = a_41; D.2182.tl.y = a_45; D.2182.br.x = a_42; D.2182.br.y = a_46; return D.2182; } _Z3fooRK6PointT: movl (%rdi), %edx movl 4(%rdi), %eax leal -2(%rdx), %esi leal 2(%rax), %ecx movl %edx, %edi cmpl %edx, %esi cmovle %esi, %edi cmpl %eax, %ecx movl %edi, -24(%rsp) movl %eax, %edi cmovle %ecx, %edi cmpl %edx, %esi cmovge %esi, %edx cmpl %eax, %ecx movl %edi, -20(%rsp) cmovge %ecx, %eax movl %edx, -16(%rsp) movl %eax, -12(%rsp) movq -24(%rsp), %rax movq -16(%rsp), %rdx ret how can i disable these warnings for intended part of source code and get nicely optimized binaries? the gcc rejects my attempts to '#pragma GCC diagnostic ignore' inside RegionT contstructor with error: #pragma GCC diagnostic not allowed inside functions :/ thanks in advance for creative hints.
Place the pragma outside of the function (though it'll probably not help due to the inlining). The min/max expression missed-optimization is due to the lack of a tree combiner. tree forwprop would be the natural candidate to optimize them.
(In reply to comment #1) > Place the pragma outside of the function (though it'll probably not help > due to the inlining). with new function attribute "warning(string...)" similary to existing "target" and "optimize" atributtes/pragmas it would be possible to manage warnings for intended parts of code. currently diagnostic system reports the location of strict-overflow, so i suppose it's able to check a function attributes and skip some warnings. am i right?
(In reply to comment #2) > (In reply to comment #1) > > Place the pragma outside of the function (though it'll probably not help > > due to the inlining). > > with new function attribute "warning(string...)" similary to existing > "target" and "optimize" atributtes/pragmas it would be possible to manage > warnings for intended parts of code. currently diagnostic system reports > the location of strict-overflow, so i suppose it's able to check a function > attributes and skip some warnings. am i right? Huh. In theory yes.
So the missed optimization with -UWARN_AND_OPTIMIZE is fixed in GCC 5. The warning is fully gone in GCC 8 for both cases since moving over to match and simplify.