avr-gcc: incorrect first operand of a subreg? (PR71103)

2016-05-31 Thread Pitchumani Sivanupandi
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)

2016-06-13 Thread Pitchumani Sivanupandi
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?

2017-01-06 Thread Pitchumani Sivanupandi
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?

2017-01-08 Thread Pitchumani Sivanupandi

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