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