Bug 841598 - Miscompilation on s390 with -O2
Miscompilation on s390 with -O2
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: gcc (Show other bugs)
6.4
Unspecified Unspecified
unspecified Severity unspecified
: rc
: ---
Assigned To: Jakub Jelinek
qe-baseos-tools
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2012-07-19 10:15 EDT by Jaroslav Škarvada
Modified: 2012-07-20 08:15 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2012-07-19 11:42:38 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Stripped down reproducer (185 bytes, text/plain)
2012-07-19 10:44 EDT, Jaroslav Škarvada
no flags Details

  None (edit)
Description Jaroslav Škarvada 2012-07-19 10:15:20 EDT
Description of problem:
When backporting fix from grep I encountered code that miscompiles on s390 with -O2.

Version-Release number of selected component (if applicable):
gcc-4.4.6-4.el6.s390

How reproducible:
Always

Steps to Reproduce:
1. Try to build grep-2.13-2.fc18.src.rpm (currently the latest Fedora version) for RHEL-6.4 on s390.
  
Actual results:
Build fails

Expected results:
Build pass

Additional info:
It compiles correctly on:
- any arch other than s390 (e.g 390x compiles OK)
- on s390 with -O0 or -O1
- on s390 with -O2 if newer gcc is used (gcc from Fedora 16 and up seems to work correctly).

Stripped down reproducer will be attached.
Comment 2 Jaroslav Škarvada 2012-07-19 10:44:08 EDT
Created attachment 599173 [details]
Stripped down reproducer

Reproducer:
On s390, gcc-4.4.6-4.el6.s390
$ gcc -O2 -o test test.c
$ ./test
1

In all other cases (e.g. -O1 or -O2 on s390x, x86, ...):
$ gcc -O2 -o test test.c
$ ./test
2

Warning reported to grep upstream, ticket:
https://savannah.gnu.org/bugs/index.php?36883

But I think the warning is not the core of this problem.

Assembly for the first case:
0040052c <main>:
  40052c:	90 ef f0 38       	stm	%r14,%r15,56(%r15)
  400530:	c0 20 00 00 00 88 	larl	%r2,400640 <__dso_handle+0x10>
  400536:	a7 fa ff 98       	ahi	%r15,-104
  40053a:	a7 38 00 01       	lhi	%r3,1
  40053e:	a7 18 00 02       	lhi	%r1,2
  400542:	50 10 f0 64       	st	%r1,100(%r15)
  400546:	c0 e5 ff ff ff 07 	brasl	%r14,400354 <printf@plt>
  40054c:	98 ef f0 a0       	lm	%r14,%r15,160(%r15)
  400550:	07 fe             	br	%r14
  400552:	07 07             	nopr	%r7

I guess the opcode on 40053a is wrong.

Assembly for s390x:
    8000056c:	eb ef f0 70 00 24 	stmg	%r14,%r15,112(%r15)
    80000572:	a7 39 00 02       	lghi	%r3,2
    80000576:	e3 f0 ff 58 ff 71 	lay	%r15,-168(%r15)
    8000057c:	c0 20 00 00 00 9a 	larl	%r2,800006b0 <__dso_handle+0x10>
    80000582:	e3 30 f0 a0 00 24 	stg	%r3,160(%r15)
    80000588:	c0 e5 ff ff ff 46 	brasl	%r14,80000414 <printf@plt>
    8000058e:	eb ef f1 18 00 04 	lmg	%r14,%r15,280(%r15)
    80000594:	07 fe             	br	%r14
    80000596:	07 07             	nopr	%r7
Comment 3 Jakub Jelinek 2012-07-19 11:42:38 EDT
That testcase is not valid C.  On s390 32-bit ptrdiff_t is int while size_t is unsigned long int, so the above violates ISO C99 6.5 (7).  While those two types have on s390 32-bit the same size, size_t isn't signed/unsigned versions corresponding to the effective type of ptrdiff_t.  On most of the other architectures size_t/ptrdiff_t types are actually either unsigned int/int or
unsigned long/long or unsigned long long/long long, so it is valid C then.
You can work around it by using -fno-strict-aliasing, or much better just fix the code not to violate C/C++ aliasing requirements.
Comment 4 Jaroslav Škarvada 2012-07-20 08:15:31 EDT
Sorry for false positive. I was checking both types in stddef.h and through sizeof() and didn't notice that they are built-ins and differ.

Note You need to log in before you can comment on or make changes to this bug.