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: 00000000 <bar>: 0: 2403 beqz a0,8 <bar+0x8> 2: 9c40 lw v0,0(a0) 4: 4aff addiu v0,-1 6: dc40 sw v0,0(a0) 8: e8a0 jrc ra a: 6500 nop 0000000c <baz>: c: f000 6a00 li v0,0 c: R_MIPS16_HI16 _gp_disp 10: f000 0b00 la v1,10 <baz+0x4> 10: R_MIPS16_LO16 _gp_disp 14: f400 3240 sll v0,16 18: e269 addu v0,v1 1a: 64c4 save 32,ra 1c: 659a move gp,v0 1e: d204 sw v0,16(sp) 20: 675c move v0,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: ea40 jalr v0 2c: 653a move t9,v0 2e: 6444 restore 32,ra 30: e8a0 jrc ra 32: 6500 nop 00000034 <foo>: 34: f000 6a00 li v0,0 34: R_MIPS16_HI16 _gp_disp 38: f000 0b00 la v1,38 <foo+0x4> 38: R_MIPS16_LO16 _gp_disp 3c: f400 3240 sll v0,16 40: e269 addu v0,v1 42: 64c4 save 32,ra 44: 659a move gp,v0 46: d204 sw v0,16(sp) 48: 675c move v0,gp 4a: f000 9a40 lw v0,0(v0) 4a: R_MIPS16_CALL16 ext 4e: ea40 jalr v0 50: 653a move t9,v0 52: 6444 restore 32,ra 54: e8a0 jrc ra 56: 6500 nop 00000058 <test>: 58: f000 6a00 li v0,0 58: R_MIPS16_HI16 _gp_disp 5c: f000 0b00 la v1,5c <test+0x4> 5c: R_MIPS16_LO16 _gp_disp 60: f400 3240 sll v0,16 64: e269 addu v0,v1 66: 659a move gp,v0 68: 677c move v1,gp 6a: 64f5 save 40,ra,s0-s1 6c: f000 9b00 lw s0,0(v1) 6c: R_MIPS16_GOT16 baz 70: d204 sw v0,16(sp) 72: f000 4800 addiu s0,0 72: R_MIPS16_LO16 baz 76: 6538 move t9,s0 78: e840 jalr s0 7a: 6724 move s1,a0 7c: 9604 lw a2,16(sp) 7e: f000 9b60 lw v1,0(v1) 7e: R_MIPS16_CALL16 foo 82: 659e move gp,a2 84: eb40 jalr v1 86: 653b move t9,v1 88: 6791 move a0,s1 8a: e840 jalr s0 8c: 6538 move t9,s0 8e: 6475 restore 40,ra,s0-s1 90: e8a0 jrc ra 92: 6500 nop 94: 6500 nop 96: 6500 nop 98: 6500 nop 9a: 6500 nop 9c: 6500 nop 9e: 6500 nop 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-mips_24kc_gcc-7.3.0_musl/libexec/gcc/mips-openwrt-linux-musl/7.3.0/lto-wrapper Target: mips-openwrt-linux-musl Configured with: /home/neoraider/Devel/OpenWrt/openwrt/build_dir/toolchain-mips_24kc_gcc-7.3.0_musl/gcc-7.3.0/configure --with-bugurl=http://www.lede-project.org/bugs/ --with-pkgversion='OpenWrt GCC 7.3.0 r6401-edab12ec79aa' --prefix=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=mips-openwrt-linux-musl --with-gnu-ld --enable-target-optspace --disable-libgomp --disable-libmudflap --disable-multilib --disable-libmpx --disable-nls --without-isl --without-cloog --with-host-libstdcxx=-lstdc++ --with-float=soft --with-gmp=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/host --with-mpfr=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/host --with-mpc=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/host --disable-decimal-float --with-mips-plt --with-diagnostics-color=auto-if-env --disable-libssp --enable-__cxa_atexit --with-headers=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/include --disable-libsanitizer --enable-languages=c,c++ --enable-shared --enable-threads --with-slibdir=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/lib --enable-lto --with-libelf=/home/neoraider/Devel/OpenWrt/openwrt/staging_dir/host Thread model: posix gcc version 7.3.0 (OpenWrt GCC 7.3.0 r6401-edab12ec79aa)