llvm / llvm/llvm-project

[MSSA][MDA] Incorrect handling of single iteration scoped alias metadata across backedge

Open
#223,170 6 comments 0 reactions 0 assignees View on GitHub
confirmed llvm:optimizations miscompilation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

```llvm
; RUN: opt -passes='early-cse' -S < %s

; Assume %p and %q are the same pointer
define i32 @f(ptr %p, ptr %q) {
entry:
store i32 7, ptr %p, align 4
br label %loop

loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
call void @llvm.experimental.noalias.scope.decl(metadata !2)
%c = icmp eq i32 %i, 0
br i1 %c, label %write, label %exit

write:
store i32 42, ptr %q, align 4, !alias.scope !2
br label %latch

latch:
%i.next = add nuw nsw i32 %i, 1
br label %loop

exit:
%v = load i32, ptr %p, align 4, !noalias !2
ret i32 %v
}

!0 = !{!0}
!1 = !{!1, !0}
!2 = !{!1}
```

This folds to return 7, however the value 42 is stored in the loop. There is no UB because the write and the read are on different iterations, passing through noalias.scope.decl in between.

The issue also occurs with `-passes=gvn` via MDA.

Based on https://github.com/llvm/llvm-project/pull/222686#issuecomment-5647760268.

Contributor guide

Open the contributing guide

Research direction

Start by running the provided opt reproducer with early-cse and then with gvn to compare the behavior through MDA. Trace how scoped alias metadata and llvm.experimental.noalias.scope.decl are handled across the loop backedge; done means the passes no longer fold this case to return 7, while preserving the valid cross-iteration store and load behavior.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.