https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79028
Bug ID: 79028 Summary: Un-optimal/ incorrect forward propagation Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pitchumani.s at hotmail dot com Target Milestone: --- test case: (options: -Os) typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); typedef struct rpl_instance rpl_instance_t; struct rpl_instance { uint8_t dio_intcurrent; uint32_t dio_next_delay; }; unsigned short random_rand(void); void new_dio_interval(rpl_instance_t *instance) { uint32_t time; uint32_t ticks; time = 1UL << instance->dio_intcurrent; ticks = (time * 128) / 1000; instance->dio_next_delay = ticks; ticks = ticks / 2 + (ticks / 2 * (uint32_t)random_rand()) / 65535U; instance->dio_next_delay -= ticks; } tree dump before and after optimizations (snip from ssa dump) _1 = instance_14(D)->dio_intcurrent; _2 = (int) _1; _3 = 1 << _2; time_15 = (uint32_t) _3; _4 = time_15 * 128; ticks_16 = _4 / 1000; instance_14(D)->dio_next_delay = ticks_16; _5 = ticks_16 / 2; _6 = ticks_16 / 2; _7 = random_rand (); _8 = (unsigned int) _7; _9 = _6 * _8; _10 = _9 / 65535; ticks_19 = _5 + _10; _11 = instance_14(D)->dio_next_delay; _12 = _11 - ticks_19; instance_14(D)->dio_next_delay = _12; return; (snip) gcc-7 propagates ticks_16 to definitions of _5 and _6 as part of forwprop1 pass. It contradicts the descriptions "substituting variables that are used once into the expression". (snip from optimized dump) <bb 2> [100.00%]: _1 = instance_13(D)->dio_intcurrent; _2 = (int) _1; _3 = 1 << _2; time_14 = (uint32_t) _3; _4 = time_14 * 128; ticks_15 = _4 / 1000; instance_13(D)->dio_next_delay = ticks_15; _5 = _4 / 2000; _6 = random_rand (); _7 = (unsigned int) _6; _8 = _5 * _7; _9 = _8 / 65535; _10 = instance_13(D)->dio_next_delay; _23 = _10 - _5; _11 = _23 - _9; instance_13(D)->dio_next_delay = _11; return; (snip) Without that forward propagation, _5 would be _5 = ticks_15 >> 1, that is optimal than the current code. Till gcc-4 it was optimal for this case, got changed gcc-5 onwards.