https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71654
Bug ID: 71654 Summary: missing VRP optimization on c++ unsigned char and short expressions Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- In C mode, GCC optimizes the both of the following functions into "return 0" as one would expect. But in C++ mode, it emits suboptimal code for guc: it does the computation at runtime. The same limitation exists if the type of the argument is unsigned short. From the dumps it looks as though the promotion from the narrower type to int that's done in C++ before the inequality test might be what prevents VRP from doing the expected thing. $ cat vrp.c && /build/gcc-49905/gcc/xgcc -B /build/gcc-49905/gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout -xc++ vrp.c int gui (unsigned i) { return i < 4 ? i & 4 : 0; } int guc (unsigned char i) { return i < 4 ? i & 4 : 0; } ;; Function int gui(unsigned int) (_Z3guij, funcdef_no=0, decl_uid=2248, cgraph_uid=0, symbol_order=0) int gui(unsigned int) (unsigned int i) { <bb 2>: return 0; } ;; Function int guc(unsigned char) (_Z3guch, funcdef_no=1, decl_uid=2251, cgraph_uid=1, symbol_order=1) Removing basic block 5 int guc(unsigned char) (unsigned char i) { int _1; unsigned char _5; unsigned char _7; int prephitmp_8; <bb 2>: _1 = (int) i_3(D); if (_1 <= 3) goto <bb 3>; else goto <bb 4>; <bb 3>: _5 = i_3(D) & 4; <bb 4>: # _7 = PHI <_5(3), 0(2)> prephitmp_8 = (int) _7; return prephitmp_8; }