[clang] [Clang][CodeGen] Use ptrtoaddr for pointer diff (PR #210729)

Alexis Engelke via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 27 03:26:52 PDT 2026


aengelke wrote:

> I'm okay with reverting if it would be helpful for you.

Agreed.

> Not sure where the inttoptr is coming from, though.

Clang coerces llvm::iterator_range (pointer pair) into [2 x i64] on AArch64. (Which is also unfortunate, because Clang could easily use [ptr, ptr] here.)

> Though looking at the IR shared above, I kind of suspect we're incorrectly CSEing ptrtoint and ptrtoaddr somewhere (i.e. CSEing to ptrtoaddr instead of to ptrtoint).

Probably. The interesting question is where the ptrtoaddr comes from in the first place, even in the non-inlined function call.

In the code, we have two calls to TestRev, one not inlined and one inlined. The second one is triggers makes the bug visible, but I believe that the first one is broken as well and just happens to work. This makes me think that SCEV might not be the problem here.

```llvm
  %14 = ptrtoaddr ptr %13 to i64 ; Where does this come from??? This ought to be a ptrtoint!
  call void @llvm.assume(i1 true) [ "align"(ptr %9, i64 4) ]
  %15 = ptrtoint ptr %9 to i64
  ; The function does inttoptr on its arguments.
  ; The inliner would fold inttoptr(%15) to %9 and EarlyCSE kills the dead %15, so the provenance is no longer exposed -- which is what happens for the second call.
  tail call fastcc void @TestRev_xxx(i64 %14, i64 %15)
; ... second call
  %19 = ptrtoaddr ptr %18 to i64
  call void @llvm.assume(i1 true) [ "align"(ptr %16, i64 4) ]
  %20 = inttoptr i64 %19 to ptr ; yeah, that's problematic.
```

After spending some hours looking into this (and playing around with several libc++ options), I couldn't get an input where there's that ptrtoaddr. I think a module dump at an earlier stage would help.

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


More information about the cfe-commits mailing list