https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128437

--- Comment #16 from George Cox <george.cox at gmail dot com> ---
Created attachment 66105
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=66105&action=edit
Reduced testcase, still ICEs after r17-6003-gc147997f4f3

Attachment 66083 compiles with r17-6003-gc147997f4f3, but the source it was
reduced from still fails with the same ICE on that revision. The attached new
reduction shows this.

  $ g++ -O2 -fPIC -fvisibility=hidden -c pr128437-2.cpp
  pr128437-2.cpp:46:1: internal compiler error: output_operand: '%&' used
  without any local dynamic TLS references

This fails with Debian's g++-16 16.2.0 and with 17.0.0 20261106 built at the
above revision. The file needs -std=c++20 or later, which is the default for
both.

It compiles when -mtls-dialect=gnu2 is added. That compile gives no warnings:

  $ g++ -Wall -Wextra -O2 -fPIC -fvisibility=hidden -mtls-dialect=gnu2 \
      -c pr128437-2.cpp

To check that the file has no undefined behaviour, I ran it with this driver,
drv.cpp, which takes both paths through retire_owned:

  #include "pr128437-2.cpp"
  int prefix_calls;
  void allocation_prefix() { ++prefix_calls; }
  int main() {
    retire_owned();
    int x = 0;
    current = 1;
    is_pointer___trans_tmp_3 = 1;
    bits_ = 1;
    views = &x;
    retire_owned();
    return prefix_calls == 2 ? 0 : 1;
  }

  $ g++ -O2 -g -fsanitize=undefined,address -fno-sanitize-recover=all \
      drv.cpp -o drv
  $ ./drv; echo $?
  0

The result is the same at -O0.

The RTL dump below comes from this command. The dump is written before the ICE:

  $ g++ -O2 -fPIC -fvisibility=hidden -fdump-rtl-mach-slim -c pr128437-2.cpp

It writes pr128437-2.cpp.359r.mach on 17.0.0 (360r on 16.2.0). In the function
retire_owned, both compilers show:

   72: ax:DI=call [`__tls_get_addr'] argc:0
      REG_EH_REGION 0xffffffff80000000
  ...
   80: [sp:DI+0x8]=ax:DI
      REG_DEAD ax:DI

Insn 72 has no REG_UNUSED note. Insn 80 stores its result to a stack slot, and
no other insn in that function's dump mentions [sp:DI+0x8].
ix86_remove_dead_tls_ld_base requires the REG_UNUSED note, which may be why it
does not remove the call. I have not confirmed this.

Reply via email to