I have a question about the meaning of NoAlias in LLVM’s alias analysis. The documentation clearly states that
"The NoAlias response may be used when there is never an immediate dependence between any memory reference based on one pointer and any memory reference based the other […] Another is when the two pointers are only ever used for reading memory." from LLVM Alias Analysis Infrastructure — LLVM 15.0.0git documentation
Now consider this C program
int f ( int* p, int* q ) {
return p[1] + q[1];
}
which clearly only reads pointers. Compiling it with
clang -O1 -Xclang -disable-llvm-passes -S -emit-llvm
opt -S -mem2reg
I get the IR below, at the bottom of this post, and when I then print the alias analysis information with
opt -aa-eval -aa -scev-aa -print-alias-sets -print-all-alias-modref-info
I get the following alias analysis
Function: f: 4 pointers, 0 call sites
MayAlias: i32* %0, i32* %1
NoAlias: i32* %0, i32* %3
MayAlias: i32* %1, i32* %3
MayAlias: i32* %0, i32* %5
NoAlias: i32* %1, i32* %5
MayAlias: i32* %3, i32* %5
Alias sets for function 'f':
Alias Set Tracker: 1 alias sets for 2 pointer values.
AliasSet[0x6000000cb200, 2] may alias, Ref Pointers: (i32* %3, LocationSize::prec\
ise(4)), (i32* %5, LocationSize::precise(4))
===== Alias Analysis Evaluator Report =====
6 Total Alias Queries Performed
2 no alias responses (33.3%)
4 may alias responses (66.6%)
0 partial alias responses (0.0%)
0 must alias responses (0.0%)
Alias Analysis Evaluator Pointer Alias Summary: 33%/66%/0%/0%
Alias Analysis Mod/Ref Evaluator Summary: no mod/ref!
In the light of the quote above that read-only implies NoAlias, I don’t understand
why i get 4 may alias responses at all. should it not be all NoAlias?
; ModuleID = 'main.c.ll'
source_filename = "main.c"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S1\
28"
target triple = "x86_64-apple-macosx12.0.0"
; Function Attrs: nounwind ssp uwtable
define i32 @f(i32* %0, i32* %1) #0 {
%3 = getelementptr inbounds i32, i32* %0, i64 1
%4 = load i32, i32* %3, align 4, !tbaa !6
%5 = getelementptr inbounds i32, i32* %1, i64 1
%6 = load i32, i32* %5, align 4, !tbaa !6
%7 = add nsw i32 %4, %6
ret i32 %7
}
attributes #0 = { nounwind ssp uwtable "darwin-stkchk-strong-link" "frame-pointer"="all" \
"min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="___chkstk_darwin" "\
stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxs\
r,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
!llvm.module.flags = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 12, i32 3]}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 7, !"PIC Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 1}
!4 = !{i32 7, !"frame-pointer", i32 2}
!5 = !{!"Apple clang version 13.1.6 (clang-1316.0.21.2.5)"}
!6 = !{!7, !7, i64 0}
!7 = !{!"int", !8, i64 0}
!8 = !{!"omnipotent char", !9, i64 0}
!9 = !{!"Simple C/C++ TBAA"}