[Bug rtl-optimization/58066] __tls_get_addr is called with misaligned stack on x86-64
ubizjak at gmail dot com
gcc-bugzilla@gcc.gnu.org
Mon Jul 13 09:16:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
Uroš Bizjak <ubizjak at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|target |rtl-optimization
--- Comment #12 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Uroš Bizjak from comment #11)
> Please make 64bit TLS patterns dependant on SP_REG, in the same way as 32bit
> are.
This wont't fix this particular case, but this dependency would be nice to
have.
The problem with the testcase from Comment #10 is caused by stack
anti-adjustment, emitted from calls.c:
1: NOTE_INSN_DELETED
4: NOTE_INSN_BASIC_BLOCK 2
2: r96:SI=di:SI
3: NOTE_INSN_FUNCTION_BEG
6: {sp:DI=sp:DI-0x8;clobber flags:CC;} <<--- *** here ***
REG_ARGS_SIZE 0x8
7: {r98:SI=r96:SI 0>>0x10;clobber flags:CC;}
8: {r99:QI=r98:SI#0&0xffffffffffffffff;clobber flags:CC;}
9: r100:SI=zero_extend(r99:QI)
10: r101:QI#0=zero_extract(r96:SI,0x8,0x8)
11: r102:SI=zero_extend(r101:QI)
12: r103:SI=zero_extend(r96:SI#0)
13: ax:DI=call [`__tls_get_addr'] argc:0
REG_EH_REGION 0xffffffff80000000
14: r105:DI=ax:DI
REG_EQUAL unspec[0] 21
15: {r106:DI=r105:DI+const(unspec[`buffer'] 6);clobber flags:CC;}
16: r104:DI=r106:DI
REG_EQUAL `buffer'
17: {r108:SI=r96:SI 0>>0x18;clobber flags:CC;}
18: r109:SI=zero_extend(r108:SI#0)
19: [pre sp:DI+=0xfffffffffffffff8]=r109:SI
REG_ARGS_SIZE 0x10
20: r9:SI=r100:SI
21: r8:SI=r102:SI
22: cx:SI=r103:SI
23: dx:DI=`*.LC0'
24: si:DI=0x12
25: di:DI=r104:DI
26: ax:QI=0
27: call [`__snprintf'] argc:0x10
REG_CALL_DECL `__snprintf'
28: ax:DI=call [`__tls_get_addr'] argc:0
REG_EH_REGION 0xffffffff80000000
29: r111:DI=ax:DI
REG_EQUAL unspec[0] 21
30: {r112:DI=r111:DI+const(unspec[`buffer'] 6);clobber flags:CC;}
31: r95:DI=r112:DI
REG_EQUAL `buffer'
32: {sp:DI=sp:DI+0x10;clobber flags:CC;}
REG_ARGS_SIZE 0
36: ax:DI=r95:DI
37: use ax:DI
Putting a breakpoint on anti_adjust_stack will show where it happens:
Breakpoint 1, anti_adjust_stack (adjust=0x2aaaae7b0500) at
/home/uros/gcc-svn/trunk/gcc/explow.c:902
902 if (adjust == const0_rtx)
(gdb) bt
#0 anti_adjust_stack (adjust=0x2aaaae7b0500) at
/home/uros/gcc-svn/trunk/gcc/explow.c:902
#1 0x000000000080f24c in expand_call (exp=0x2aaaae7b3680, target=0x0,
ignore=1) at /home/uros/gcc-svn/trunk/gcc/calls.c:3165
#2 0x0000000000966084 in expand_expr_real_1 (exp=0x2aaaae7b3680, target=0x0,
tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0, inner_reference_p=false)
at /home/uros/gcc-svn/trunk/gcc/expr.c:10362
There is already precompute_register_parameters function where:
/* If the value is a non-legitimate constant, force it into a
pseudo now. TLS symbols sometimes need a call to resolve. */
if (CONSTANT_P (args[i].value)
&& !targetm.legitimate_constant_p (args[i].mode, args[i].value))
args[i].value = force_reg (args[i].mode, args[i].value);
So, the core of the problem is in the call infrastructure that should emit
precomputed register parameters before anti_adjust_stack is emitted
After this infrastructure problem is fixed, proposed SP_REG dependency will
prevent stack adjustment to be scheduled above TLS patterns.
Re-confirmed as RTL-optimization problem.
More information about the Gcc-bugs
mailing list