Issue 136275
Summary Trivial comparison of pointer defeats store->load forwarding
Labels llvm:analysis
Assignees
Reporter mhjacobson
    LLVM version 20.1.1
target: x86_64-apple-darwin20.6.0

Given the following IR:

```llvm
declare ptr @calloc(i64, i64)
declare void @free(ptr)
declare void @bar(ptr noalias nocapture readonly %0, i1 %info)

define void @foo(i32 %argc, ptr nocapture readnone %argv) local_unnamed_addr {
entry:
  %0 = tail call ptr @calloc(i64 1, i64 64)
 %1 = icmp ult ptr %0, inttoptr (i64 u0xFFFFFFFFFFFFFFFF to ptr)
  store i64 0, ptr %0, align 4

  ; NOTE: the %1 here causes %0 to be considered captured and therefore potentially aliased.
  ; So the load and branch below the call can't be optimized away.
  tail call void @bar(ptr %0, i1 %1)
  %2 = load i64, ptr %0, align 4
  %3 = add nsw i64 %2, -1
  store i64 %3, ptr %0, align 4
  %4 = icmp eq i64 %2, 0
  br i1 %4, label %free_it, label %end

free_it:
  tail call void @free(ptr %0)
  ret void

end:
  ret void
}
```

I would expect the load at `%2`, the add at `%3`, the icmp at `%4`, and the branch to be optimized away.  But they aren't, because `%0` is considered captured by `llvm::DetermineUseCaptureKind()`:

```c++
  case Instruction::ICmp: {
    unsigned Idx = U.getOperandNo();
    unsigned OtherIdx = 1 - Idx;
    if (auto *CPN = dyn_cast<ConstantPointerNull>(I->getOperand(OtherIdx))) { ... }

    // Otherwise, be conservative. There are crazy ways to capture pointers
    // using comparisons.
    return UseCaptureKind::MAY_CAPTURE;
```

And therefore `%0` is assumed potentially aliased.

Even passing `%1` to `@llvm.assume` (which is how I initially hit this condition) prevents the optimization.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to