https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79191
Bug ID: 79191 Summary: potentially truncating unsigned conversion defeats range propagation Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- As mentioned in a recent discussion (https://gcc.gnu.org/ml/gcc-patches/2017-01/msg01617.html), a truncating unsigned conversion such as from unsigned long to unsigned in LP64 appears to defeat VRP and prevent GCC from emitting optimal code. In the test case below, the indirect call to abort() in g() is optimized away because n is known to be less than 3. However, the same indirect call to abort() is not optimized away in h(). $ cat t.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.c void f (unsigned long n) { if (n > 3) __builtin_abort (); } void g (unsigned n) { if (n < 3) f (n); } void h (unsigned long m) { unsigned n = m; if (n < 3) f (n); } ;; Function f (f, funcdef_no=0, decl_uid=1795, cgraph_uid=0, symbol_order=0) f (long unsigned int n) { <bb 2> [100.00%]: if (n_1(D) > 3) goto <bb 3>; [0.04%] else goto <bb 4>; [99.96%] <bb 3> [0.04%]: __builtin_abort (); <bb 4> [99.96%]: return; } ;; Function g (g, funcdef_no=1, decl_uid=1798, cgraph_uid=1, symbol_order=1) g (unsigned int n) { <bb 2> [100.00%]: return; } ;; Function h (h, funcdef_no=2, decl_uid=1801, cgraph_uid=2, symbol_order=2) Removing basic block 6 Removing basic block 7 h (long unsigned int m) { unsigned int n; long unsigned int _5; <bb 2> [100.00%]: n_2 = (unsigned int) m_1(D); if (n_2 <= 2) goto <bb 3>; [54.00%] else goto <bb 5>; [46.00%] <bb 3> [54.00%]: _5 = m_1(D) & 4294967295; if (_5 > 3) goto <bb 4>; [0.04%] else goto <bb 5>; [99.96%] <bb 4> [0.02%]: __builtin_abort (); <bb 5> [99.98%]: return; }