[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