This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/59820] alpha: incorrect optimisation with -mcpu=ev4 and -O2
- From: "ubizjak at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 15 Jan 2014 22:13:23 +0000
- Subject: [Bug c/59820] alpha: incorrect optimisation with -mcpu=ev4 and -O2
- Auto-submitted: auto-generated
- References: <bug-59820-4 at http dot gcc dot gnu dot org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59820
--- Comment #1 from UroÅ Bizjak <ubizjak at gmail dot com> ---
(In reply to Michael Cree from comment #0)
> Created attachment 31837 [details]
> Test code exhibiting problem
>
> Compiling the attached test (which is a cut down version of a test from
> glibc test suite) on an Alpha with -mcpu=ev4 at optimisation -O2 leads
> to a segmentation fault when the test is run. Output is:
>
> $ gcc -mcpu=ev4 -O2 -o gcc-optim-test gcc-optim-test.c
> $ ./gcc-optim-test
> set bar to 1 (LE)
> Segmentation fault
>
> Compiling at lower optimisation works correctly, e.g.:
>
> $ gcc -mcpu=ev4 -O1 -o gcc-optim-test gcc-optim-test.c
> $ ./gcc-optim-test
> set bar to 1 (LE)
> get sum of foo and bar (LD) = 1
>
> Compiling for more advanced Alpha CPU works correctly, even at -O2, e.g.:
>
> $ gcc -mcpu=ev5 -O2 -o gcc-optim-test gcc-optim-test.c
> $ ./gcc-optim-test
> set bar to 1 (LE)
> get sum of foo and bar (LD) = 1
>
> Bug is seen on all versions of gcc tested ranging from gcc-4.4 upto gcc-4.8
> from Debian, and gcc git master at commit eb5d7331da45b675e (SVN trunk
> 206563).
>
> Running the failing version under gdb:
>
> $ gcc -g -mcpu=ev4 -O2 -o gcc-optim-test gcc-optim-test.c
> $ gdb ./gcc-optim-test
> (gdb) run
> Starting program: /home/mjc/test/./gcc-optim-test
> set bar to 1 (LE)
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x000002000001545c in __tls_get_addr () from /lib/ld-linux.so.2
> (gdb) bt full
> #0 0x000002000001545c in __tls_get_addr () from /lib/ld-linux.so.2
> No symbol table info available.
> #1 0x00000001200005a4 in do_test () at gcc-optim-test.c:44
> __result = 0x20000031230
> result = 0
> ap = <optimized out>
> bp = <optimized out>
> #2 main () at gcc-optim-test.c:63
> No locals.
>
> (gdb) disass
> Dump of assembler code for function __tls_get_addr:
> 0x0000020000015420 <+0>: ldah gp,2(t12)
> 0x0000020000015424 <+4>: lda gp,27728(gp)
> 0x0000020000015428 <+8>: lda sp,-32(sp)
> 0x000002000001542c <+12>: rduniq
> 0x0000020000015430 <+16>: clr a1
> 0x0000020000015434 <+20>: ldq t0,-28776(gp)
> 0x0000020000015438 <+24>: stq s0,8(sp)
> 0x000002000001543c <+28>: mov a0,s0
> 0x0000020000015440 <+32>: ldq a0,0(v0)
> 0x0000020000015444 <+36>: stq s1,16(sp)
> 0x0000020000015448 <+40>: mov v0,s1
> 0x000002000001544c <+44>: stq ra,0(sp)
> 0x0000020000015450 <+48>: ldq t1,0(a0)
> 0x0000020000015454 <+52>: cmpeq t1,t0,t0
> 0x0000020000015458 <+56>: beq t0,0x20000015494 <__tls_get_addr+116>
> => 0x000002000001545c <+60>: ldq a2,0(s0)
>
> (gdb) info registers
> v0 0x20000030b10 2199023454992
> t0 0x1 1
> t1 0x1 1
> t2 0x29 41
> t3 0x20000025ff0 2199023411184
> t4 0x72616220646e6120 8241976684328149280
> t5 0x6f660029444c2820 8027103563073988640
> t6 0x61206f6f6620666f 6998716345179203183
> t7 0x6120000000000000 6998593820933750784
> s0 0x1200185d8 4831938008
> s1 0x20000030b10 2199023454992
> s2 0x120138388 4833117064
> s3 0x0 0
> s4 0x120143d90 4833164688
> s5 0x120145330 4833170224
> fp 0x0 0
> a0 0x20000031230 2199023456816
> a1 0x0 0
> a2 0x0 0
> a3 0x200001c8798 2199025125272
> a4 0xffffffffffffffff -1
> a5 0x0 0
> t8 0x28 40
> t9 0x200000b7280 2199024005760
> t10 0x11 17
> t11 0x400 1024
> ra 0x1200005a4 4831839652
> t12 0x20000015420 2199023342624
> at 0x7c8ad2d8 2089472728
> gp 0x2000003c070 0x2000003c070
> sp 0x11f8cd5c0 0x11f8cd5c0
> pc 0x2000001545c 0x2000001545c <__tls_get_addr+60>
> (gdb) print (long)*0x1200185d8
> Cannot access memory at address 0x1200185d8
>
> So it would appear that the argument passed to __tls_get_addr() was not
> a valid address.
Because TLS_LD is defined in a wrong way.
ldah $29,0($26) !gpdisp!9
.set macro
# 44 "gcc-optim-test.c" 1
lda $16, foo($gp) !tlsldm
# 0 "" 2
.set nomacro
lda $29,0($29) !gpdisp!9
ldq $27,__tls_get_addr($29) !literal!10
jsr $26,($27),__tls_get_addr !lituse_jsr!10
Please note how !gpdisp!9 gets emitted after !tlsldm load. Moving "lda
$29,0($29)" (and corresponding bar related insn) in front of !tlsldm load fixes
the ICE.