[Bug c/84790] New: Miscompilation for MIPS16 with -fpic and -Os or -O2

2018-03-09 Thread mschif...@universe-factory.net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84790

Bug ID: 84790
   Summary: Miscompilation for MIPS16 with -fpic and -Os or -O2
   Product: gcc
   Version: 7.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: mschif...@universe-factory.net
  Target Milestone: ---

Created attachment 43609
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43609&action=edit
Reproducer C code

Compiling the following piece of C code:

void ext(void);

struct A {
unsigned v;
};


__attribute__((noinline))
void foo(void) {
ext();
}


__attribute__((noinline))
static void bar(struct A *a) {
if (a)
a->v--;
}

__attribute__((noinline))
static void baz(struct A *a) {
bar(a);
}


void test(struct A *a) {
baz(a);
foo();
baz(a);
}

using the command

mips-openwrt-linux-musl-gcc -Os -mips32r2 -mtune=24kc -mips16 -fpic -Wall
-Wextra -c -o reproducer.o reproducer.c

(current OpenWrt toolchain) generates the following code:

 :
   0:   2403beqza0,8 
   2:   9c40lw  v0,0(a0)
   4:   4affaddiu   v0,-1
   6:   dc40sw  v0,0(a0)
   8:   e8a0jrc ra
   a:   6500nop

000c :
   c:   f000 6a00   li  v0,0
c: R_MIPS16_HI16_gp_disp
  10:   f000 0b00   la  v1,10 
10: R_MIPS16_LO16   _gp_disp
  14:   f400 3240   sll v0,16
  18:   e269adduv0,v1
  1a:   64c4save32,ra
  1c:   659amovegp,v0
  1e:   d204sw  v0,16(sp)
  20:   675cmovev0,gp
  22:   f000 9a40   lw  v0,0(v0)
22: R_MIPS16_GOT16  bar
  26:   f000 4a00   addiu   v0,0
26: R_MIPS16_LO16   bar
  2a:   ea40jalrv0
  2c:   653amovet9,v0
  2e:   6444restore 32,ra
  30:   e8a0jrc ra
  32:   6500nop

0034 :
  34:   f000 6a00   li  v0,0
34: R_MIPS16_HI16   _gp_disp
  38:   f000 0b00   la  v1,38 
38: R_MIPS16_LO16   _gp_disp
  3c:   f400 3240   sll v0,16
  40:   e269adduv0,v1
  42:   64c4save32,ra
  44:   659amovegp,v0
  46:   d204sw  v0,16(sp)
  48:   675cmovev0,gp
  4a:   f000 9a40   lw  v0,0(v0)
4a: R_MIPS16_CALL16 ext
  4e:   ea40jalrv0
  50:   653amovet9,v0
  52:   6444restore 32,ra
  54:   e8a0jrc ra
  56:   6500nop

0058 :
  58:   f000 6a00   li  v0,0
58: R_MIPS16_HI16   _gp_disp
  5c:   f000 0b00   la  v1,5c 
5c: R_MIPS16_LO16   _gp_disp
  60:   f400 3240   sll v0,16
  64:   e269adduv0,v1
  66:   659amovegp,v0
  68:   677cmovev1,gp
  6a:   64f5save40,ra,s0-s1
  6c:   f000 9b00   lw  s0,0(v1)
6c: R_MIPS16_GOT16  baz
  70:   d204sw  v0,16(sp)
  72:   f000 4800   addiu   s0,0
72: R_MIPS16_LO16   baz
  76:   6538movet9,s0
  78:   e840jalrs0
  7a:   6724moves1,a0
  7c:   9604lw  a2,16(sp)
  7e:   f000 9b60   lw  v1,0(v1)
7e: R_MIPS16_CALL16 foo
  82:   659emovegp,a2
  84:   eb40jalrv1
  86:   653bmovet9,v1
  88:   6791movea0,s1
  8a:   e840jalrs0
  8c:   6538movet9,s0
  8e:   6475restore 40,ra,s0-s1
  90:   e8a0jrc ra
  92:   6500nop
  94:   6500nop
  96:   6500nop
  98:   6500nop
  9a:   6500nop
  9c:   6500nop
  9e:   6500nop

This is incorrect: The GOT lookup for foo at 7e assumes that v1 still contains
the gp value set at 68, even though it is not valid anymore after the baz call
at 78.

We noticed this issue as it started to affect real software with GCC 7, but for
this reproducer code, GCC 5.4 and 5.5 produce identical code, so it is not a
regression per se.

Version: mips-openwrt-linux-musl-gcc -v
Reading specs from
/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/lib/gcc/mips-openwrt-linux-musl/7.3.0/specs
COLLECT_GCC=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/bin/mips-openwrt-linux-musl-gcc
COLLECT_LTO_WRAPPER=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/toolchain-mip

[Bug target/84790] Miscompilation for MIPS16 with -fpic and -Os or -O2

2018-03-10 Thread mschif...@universe-factory.net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84790

--- Comment #1 from Matthias Schiffer  ---
Issue still present in gcc version 8.0.1 20180310 (experimental) (GCC). Again,
output it identical to that of GCC 5 and 7.

[Bug target/84790] Miscompilation for MIPS16 with -fpic and -Os or -O2

2018-03-10 Thread mschif...@universe-factory.net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84790

--- Comment #2 from Matthias Schiffer  ---
The problem seems to be that the gp init sequence

li  $2,%hi(_gp_disp)
addiu   $3,$pc,%lo(_gp_disp)
sll $2,16
addu$2,$3

is generated very late and does not appear in the RTL in any way, so optimizing
passes are not aware of the $3 (and possibly $2?) clobber. I don't know enough
about GCC internals for further analysis.