Bug 101469 - wrong code with "-O2 -fPIE" for SH
Summary: wrong code with "-O2 -fPIE" for SH
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 10.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2021-07-16 09:48 UTC by Rin Okuyama
Modified: 2021-07-21 16:40 UTC (History)
4 users (show)

See Also:
Host:
Target: sh3-none-elf, shle--netbsdelf
Build:
Known to work:
Known to fail: 10.3.0, 5.5.0, 7.5.0, 9.3.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rin Okuyama 2021-07-16 09:48:24 UTC
This Bug is for GCC 10.3 for shle:

----
$ shle--netbsdelf-gcc -v
Using built-in specs.
COLLECT_GCC=/build/gcc10/tools/bin/shle--netbsdelf-gcc
COLLECT_LTO_WRAPPER=/build/gcc10/tools/libexec/gcc/shle--netbsdelf/10.3.0/lto-wrapper
Target: shle--netbsdelf
Configured with: /usr/src/tools/gcc/../../external/gpl3/gcc/dist/configure --target=shle--netbsdelf --enable-long-long --enable-threads --with-bugurl=http://www.NetBSD.org/support/send-pr.html --with-pkgversion='NetBSD nb1 20210411' --with-system-zlib --without-isl --enable-__cxa_atexit --enable-libstdcxx-time=rt --enable-libstdcxx-threads --with-diagnostics-color=auto-if-env --with-default-libstdcxx-abi=new --with-sysroot=/build/gcc10/dest/landisk --with-mpc=/build/gcc10/tools --with-mpfr=/build/gcc10/tools --with-gmp=/build/gcc10/tools --disable-nls --disable-multilib --program-transform-name='s,^,shle--netbsdelf-,' --enable-languages='c c++ objc' --prefix=/build/gcc10/tools
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.3.0 (NetBSD nb1 20210411)
----

GCC miscompile this code with "-O2 -fPIE":

----
typedef struct {
	int pad[16];
	int i;
	int *p;
} struct_t;

struct_t *sp;

void *ptr(void);

void func(void) {
	sp = ptr();
	sp->p = &sp->i;
}
----

The following is objdump with comments:

----
00000000 <func>:
   0:	mov.l	r12,@-r15
   2:	mova	24 <func+0x24>,r0
   4:	mov.l	24 <func+0x24>,r12
   6:	sts.l	pr,@-r15
   8:	add	r0,r12			! r12 = .got
   a:	mov.l	28 <func+0x28>,r1
   c:	bsrf	r1			! r0 = ptr()
   e:	nop
  10:	mov.l	2c <func+0x2c>,r1
  12:	mov	r0,r2			! r2 = r0
  14:	mov	r12,r0
  16:	mov.l	r2,@(r0,r1)		! @(.got, 2c) = sp = r2
  18:	add	#64,r2			! r2 = &sp->i
  1a:	mov.l	r2,@(4,r12)		! XXX
  1c:	lds.l	@r15+,pr
  1e:	rts
  20:	mov.l	@r15+,r12
  22:	nop
  24:	.word 0x0000
  26:	.word 0x0000
  28:	sett
  2a:	.word 0x0000
  2c:	.word 0x0000
----

The problem is marked by XXX in comment; if this line were

----
  1a:	mov.l	r2,@(4,r2)
----

it would make sense, i.e.,

----
  @(4, &sp->i) = sp->p = r2 = &sp->i
----

However, unfortunately, GCC somehow mistakes r12 (= .got) with r2.
As a result, sp->p is not correctly set, and .got gets corrupted.

Note that generated code is almost same for "-Os -fPIE". And the
problem occurs also for GCC 9.3.
Comment 1 Rin Okuyama 2021-07-18 04:18:04 UTC
I've confirmed that the problem also occurs for sh3-none-elf:

----
$ sh3-none-elf-gcc -v
Using built-in specs.
COLLECT_GCC=/usr/pkg/cross-sh3-none-elf/bin/sh3-none-elf-gcc
COLLECT_LTO_WRAPPER=/usr/pkg/cross-sh3-none-elf/libexec/gcc/sh3-none-elf/10.3.0/lto-wrapper
Target: sh3-none-elf
Configured with: /build/pkgsrc/cross/sh3-none-elf-gcc/work.x86_64/gcc-10.3.0/configure --target=sh3-none-elf --enable-languages=c,c++ --with-newlib --disable-nls --disable-libstdcxx-pch --prefix=/usr/pkg/cross-sh3-none-elf --build=x86_64--netbsd --host=x86_64--netbsd --infodir=/usr/pkg/cross-sh3-none-elf/info --mandir=/usr/pkg/cross-sh3-none-elf/man
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 10.3.0 (GCC)
----

So, this is not NetBSD-specific.

Also, for shle--netbsdelf, GCC 7.5 and 5.5 has the same problem; this is
not a recent regression.

Thanks,
rin
Comment 2 Valeriy E. Ushakov 2021-07-18 17:04:57 UTC
I don't have the latest gcc handy, but I see this bug already in an old netbsd tree from about an year ago with gcc 8.4.0

As hgutch@n.o pointed out, this seems to be a problem with this peephole2:

;;	mov	r12,r0
;;	add	#-48,r0     ->	add	#-48,r12
;;	mov.l	r0,@(4,r10)	mov.l	r12,@(4,r10)
;;	(r12 dead)
(define_peephole2
  [(set (match_operand:SI 0 "arith_reg_dest")
	(match_operand:SI 1 "arith_reg_dest"))
   (set (match_dup 0) (plus:SI (match_dup 0)
			       (match_operand:SI 2 "const_int_operand")))
   (set (match_operand:SI 3 "general_movdst_operand") (match_dup 0))]


as far as I can tell, it optimizes

  r0 = r2
  r0 += 64
  *(r0+4) = r0

to

  r2 += 64
  *(r0+4) = r2

failing to notice that the the destination uses r0 too.

Then in the cprop-registers step that r0 is replaced with r12 b/c of r0 = r12 done a bit earlier.
Comment 3 Rin Okuyama 2021-07-19 05:23:01 UTC
Thank you very much for your analysis!

If that peephole is removed, GCC 10.3 generates working codes.

NetBSD/shle built by this compiler works fine as far as I can see.
I'm carrying out full regression tests of NetBSD on this system.
(It takes about a day to finish.)

Is there a better fix than mechanically removing that peephole?

Thanks,
rin
Comment 4 Oleg Endo 2021-07-19 05:55:36 UTC
(In reply to Rin Okuyama from comment #3)
> Thank you very much for your analysis!
> 
> If that peephole is removed, GCC 10.3 generates working codes.
> 
> NetBSD/shle built by this compiler works fine as far as I can see.
> I'm carrying out full regression tests of NetBSD on this system.
> (It takes about a day to finish.)
> 
> Is there a better fix than mechanically removing that peephole?

Thanks for reporting and analyzing this issue.

I was suspecting that to be a broken peephole pattern.  Of course it's better to fix the broken pattern instead of deleting it completely.

I'll try to come up with a patch during this week.
Comment 5 Rin Okuyama 2021-07-19 06:13:08 UTC
Thank you for your kind attention! I look forward to hearing from you.
Comment 6 Rin Okuyama 2021-07-21 16:40:42 UTC
(In reply to Rin Okuyama from comment #3)
> If that peephole is removed, GCC 10.3 generates working codes.
> 
> NetBSD/shle built by this compiler works fine as far as I can see.
> I'm carrying out full regression tests of NetBSD on this system.
> (It takes about a day to finish.)

It took more time due to minor troubles for my side, but it finished.
Fallout from this bug is fixed, whereas no new regressions are observed!

Thanks,
rin