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

            Bug ID: 125736
           Summary: GCC doesn't use implicit zero-extended register in
                    address
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lh_mouse at 126 dot com
  Target Milestone: ---

(https://gcc.godbolt.org/z/G8qnqdvP1)
```
typedef __UINT32_TYPE__ uint32_t;
typedef __UINTPTR_TYPE__ uintptr_t;

inline
uintptr_t
read_gs_ptr(uint32_t offset)
  {
    uintptr_t value;
#ifdef __clang__
    value = *(uintptr_t __seg_gs*)(uintptr_t) offset;
#else
    __asm__ ("gs mov %k0, %a1" 
             : "=r"(value) : "Ts"((uintptr_t) offset) 
             : "memory");
#endif
    return value;
  }

extern uint32_t tls_index;

uintptr_t
read_tls(void)
  {
    return read_gs_ptr(0x1480 + tls_index * sizeof(uintptr_t));
  }
 ```

Clang gives:

```
read_tls:
  mov    eax, [rip+0x0]
  lea    eax, [rax*8+0x1480]  # EAX = tls_index * 8 + 0x1480
                              # which is zero-extended to RAX,
  mov    rax, gs:[rax]        # so this may use a 64-bit address.
 ret
```

but GCC gives this, despite the cast in source code:

```
read_tls:
  mov    eax, [rip+0x0]
  mov    eax, gs:[eax*8+0x1480]  # this uses a 32-bit address which
                                 # requires an address-size override
                                 # prefix (0x67).
  ret
```

Ideally it should be:

```
read_tls:
  mov    eax, [rip+0x0]
  mov    eax, gs:[rax*8+0x1480]
  ret
```

Reply via email to