nikic wrote:
AI flagged a possible miscompile introduced in this change. Consider a case
like this:
```llvm
define i32 @f(i32 %v) {
entry:
%p = alloca i32, align 4
store i32 0, ptr %p, align 4
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %loop.latch ]
call void @llvm.experimental.noalias.scope.decl(metadata !2)
%c = icmp eq i32 %i, 0
br i1 %c, label %if, label %else
if:
call void @llvm.memset.p0.i64(ptr align 4 %p, i8 1, i64 4, i1 false),
!alias.scope !2
br label %loop.latch
else:
%ld = load i32, ptr %p, align 4, !noalias !2
%new = add i32 %ld, %v
store i32 %new, ptr %p, align 4, !noalias !2
%e = icmp ugt i32 %i, 2
br i1 %e, label %exit, label %loop.latch
loop.latch:
%i.next = add i32 %i, 1
br label %loop
exit:
%r = load i32, ptr %p, align 4
ret i32 %r
}
!0 = !{!0}
!1 = !{!1, !0}
!2 = !{!1}
```
Notably, we have a noalias.scope.decl inside the loop, which means that the
noalias metadata only holds within one loop iteration. As the if/else code
paths are disjoint, the alias scope metadata is correct and there is no UB.
However, we now preserve the noalias metadata in `else`, which is is an exiting
block, so we do know that it must hold on the last iteration. But we use it to
prove noalias with the memset on a different iteration.
(After seeing this, I suspect that we have some other places that may not
handle per-iteration scoped alias metadata correctly. Any place using the AA
cross iteration mode is suspect. LAA has explicit handling for this, but DA
probably gets it wrong, and MSSA translation across phis likely as well...)
https://github.com/llvm/llvm-project/pull/222686
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits