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

Reply via email to