[llvm] X86: Stop using MachineFunction in getPointerRegClass (PR #156880)

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 11 03:13:04 PDT 2025


mstorsjo wrote:

I've got one breakage pinpointed down to this snippet:
```c
__extension__ typedef unsigned long long size_t;
  void * __attribute__((__cdecl__)) memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _Size) ;
typedef struct {
  long long __clang_max_align_nonce1
      __attribute__((__aligned__(__alignof__(long long))));
  long double __clang_max_align_nonce2
      __attribute__((__aligned__(__alignof__(long double))));
} max_align_t;
__extension__ typedef unsigned long long uintptr_t;
typedef enum memory_order {
  memory_order_relaxed = 0,
  memory_order_consume = 1,
  memory_order_acquire = 2,
  memory_order_release = 3,
  memory_order_acq_rel = 4,
  memory_order_seq_cst = 5
} memory_order;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef union {
    void *nc;
    const void *c;
} AVRefStructOpaque;
typedef struct RefCount {
    atomic_uintptr_t refcount;
    AVRefStructOpaque opaque;
    void (*free_cb)(AVRefStructOpaque opaque, void *obj);
    void (*free)(void *ref);
} RefCount;
static RefCount *get_refcount(void *obj)
{
    RefCount *ref = (RefCount*)((char*)obj - (((sizeof(RefCount))+(((64) > (_Alignof(max_align_t)) ? (64) : (_Alignof(max_align_t))))-1)&~((((64) > (_Alignof(max_align_t)) ? (64) : (_Alignof(max_align_t))))-1)));
    ((void)0);
    return ref;
}
void av_refstruct_unref(void *objp)
{
    void *obj;
    RefCount *ref;
    memcpy(&obj, objp, sizeof(obj));
    if (!obj)
        return;
    memcpy(objp, &(void *){ ((void*)0) }, sizeof(obj));
    ref = get_refcount(obj);
    if (__c11_atomic_fetch_sub(&ref->refcount, 1, memory_order_acq_rel) == 1) {
        if (ref->free_cb)
            ref->free_cb(ref->opaque, obj);
        ref->free(ref);
    }
    return;
}
```

Compiled like this:
```console
$ clang-good -target x86_64-windows-gnu repro.c -O2 -S -o out-good.s
$ clang-bad -target x86_64-windows-gnu repro.c -O2 -S -o out-bad.s
$ diff -u out-good.s out-bad.s
```

```diff
--- out-good.s  2025-09-11 13:10:33.754494513 +0300
+++ out-bad.s   2025-09-11 13:10:34.988497370 +0300
@@ -22,31 +22,30 @@
        subq    $40, %rsp
        .seh_stackalloc 40
        .seh_endprologue
-       movq    (%rcx), %rdx
-       testq   %rdx, %rdx
+       movq    (%rcx), %rsi
+       testq   %rsi, %rsi
        je      .LBB0_5
 # %bb.1:                                # %if.end
        movq    $0, (%rcx)
-       lock            decq    -64(%rdx)
+       lock            decq    -64(%rsi)
        jne     .LBB0_5
 # %bb.2:                                # %if.then1
-       leaq    -64(%rdx), %rsi
-       movq    -48(%rdx), %rax
+       leaq    -64(%rsi), %rdi
+       movq    -48(%rsi), %rax
        testq   %rax, %rax
        je      .LBB0_4
 # %bb.3:                                # %if.then3
-       movq    -56(%rdx), %rcx
-       movq    %rdx, %rdi
+       movq    -56(%rsi), %rcx
+       movq    %rsi, %rdx
        callq   *%rax
-       movq    %rdi, %rdx
 .LBB0_4:                                # %if.end5
-       movq    %rsi, %rcx
+       movq    %rdi, %rcx
        .seh_startepilogue
        addq    $40, %rsp
        popq    %rdi
        popq    %rsi
        .seh_endepilogue
-       rex64 jmpq      *-40(%rdx)              # TAILCALL
+       rex64 jmpq      *-40(%rsi)              # TAILCALL
 .LBB0_5:                                # %cleanup
        .seh_startepilogue
        addq    $40, %rsp
```
Most of this is just cosmetic changes where different registers are used, but one instruction, `movq %rdi, %rdx`, is entirely lost after this change.

https://github.com/llvm/llvm-project/pull/156880


More information about the llvm-commits mailing list