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.