avr-gcc: incorrect first operand of a subreg? (PR71103)
Hi, avr-gcc was crashing for below test case. command line: avr-gcc -mmcu=atmega328p -O1 test.c struct ResponseStruct{ unsigned char responseLength; char *response; }; static char response[5]; struct ResponseStruct something(){ struct ResponseStruct returnValue; returnValue.responseLength = 5; returnValue.response = response + 1; return returnValue; } Output: > test.c:12:1: error: unrecognizable insn: > } > ^ > (insn 6 5 7 2 (set (subreg:QI (reg:PSI 42 [ D.1499 ]) 1) > (subreg:QI (const:HI (plus:HI (symbol_ref:HI ("response") > [flags 0x2]) > (const_int -1 [0x > ]))) 0)) test.c:11 -1 > (nil)) > test.c:12:1: internal compiler error: in extract_insn, at > recog.c:2287 > 0xd51195 _fatal_insn(char const*, rtx_def const*, char const*, int, > char const*) > /home/rudran/code/gcc/gcc/rtl-error.c:108 Source operand is a subreg which has const operand as first operand. Subreg shall have pseudo, mem or hard registers as fist operand. Ref: https://gcc.gnu.org/onlinedocs/gccint/Regs-and-Memory.html For the reported case it has const expression. Isn't that incorrect? validate_subreg doesn't seem to reject this case. How can we avoid such case (avr target)? Regards, Pitchumani
Re: avr-gcc: incorrect first operand of a subreg? (PR71103)
Ping! On Tue, 2016-05-31 at 19:47 +, Pitchumani Sivanupandi wrote: > Hi, > > avr-gcc was crashing for below test case. > command line: avr-gcc -mmcu=atmega328p -O1 test.c > > struct ResponseStruct{ > unsigned char responseLength; > char *response; > }; > > static char response[5]; > struct ResponseStruct something(){ > struct ResponseStruct returnValue; > returnValue.responseLength = 5; > returnValue.response = response + 1; > return returnValue; > } > > Output: > > > > test.c:12:1: error: unrecognizable insn: > > } > > ^ > > (insn 6 5 7 2 (set (subreg:QI (reg:PSI 42 [ D.1499 ]) 1) > > (subreg:QI (const:HI (plus:HI (symbol_ref:HI ("response") > > [flags 0x2] <var_decl 0x7fda2ef3b900 response>) > > (const_int -1 [0x > > ]))) 0)) test.c:11 -1 > > (nil)) > > test.c:12:1: internal compiler error: in extract_insn, at > > recog.c:2287 > > 0xd51195 _fatal_insn(char const*, rtx_def const*, char const*, int, > > char const*) > > /home/rudran/code/gcc/gcc/rtl-error.c:108 > Source operand is a subreg which has const operand as first operand. > Subreg shall have pseudo, mem or hard registers as fist operand. > Ref: https://gcc.gnu.org/onlinedocs/gccint/Regs-and-Memory.html > > For the reported case it has const expression. Isn't that incorrect? > validate_subreg doesn't seem to reject this case. How can we avoid > such > case (avr target)? > > Regards, > Pitchumani
un-optimal code because of forwprop after gcc-5?
Found a code size regression for AVR target in gcc-5 and higher. Looks like it is applicable to x86_64 also. 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; } ssa dump _3 = instance_2(D)->dio_intcurrent _4 = (int) _3 _5 = 1 << _4 time_6 = (uint32_t)_5 _7 = time_6 * 128 ticks_8 = _7 / 1000 instance_2(D)->dio_next_delay = ticks_8 _10 = ticks_8 / 2 _11 = ticks_8 / 2 _13 = random_rand() _14 = (unsigned int) _13 _15 = _11 * _14 _16 = _15 / 65535 ticks_17 = _11 + _16 _18 = instance_2(D)->dio_next_delay _19 = _18 - ticks_17 instance_2(D)->dio_next_delay = _19 return gcc-5 or higher generates un-optimal code for _10 definition as below: _10 = _7 / 2000 where as gcc-4 generates _10 = ticks_8 >> 1. Below are few differences in the passes that lead to this un-optimal code. pass |gcc 4 | gcc 5 and higher | --+---+--+ ccp1 | _10 definition removed as dce | No change| | | | forwprop1 | No change | gimple_simplified _10 & _11 | | |_10 = _7 / 2000 | | |_11 = _7 / 2000 | | | | cddce1| No change | _10 definition removed | | | | ccp2 | No change | No change| | | | vrp1 | _10 = ticks_8 / 2 | No change| | changed to | | | _10 = ticks_8 >> 1 | | --+---+--+ Forward propagation in gcc-4 doesn't propagate ticks_8 to _11. Where as gcc-5 propagates to two expressions (_10 and _11). Is that valid? This prevents vrp pass from optimizing rhs expressions of _11 in this testcase. Regards, Pitchumani
Re: un-optimal code because of forwprop after gcc-5?
On Friday 06 January 2017 09:42 PM, Jeff Law wrote: On 01/06/2017 03:09 AM, Pitchumani Sivanupandi wrote: Found a code size regression for AVR target in gcc-5 and higher. Looks like it is applicable to x86_64 also. Please file a bug. http://gcc.gnu.org/bugzilla Filed. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79028 Regards, Pitchumani