<div dir="ltr">And another case:<div><br></div><div>- Clang [-> LLVM-IR]: <a href="https://llvm.godbolt.org/z/SGeJZw">https://llvm.godbolt.org/z/SGeJZw</a><br>- [LLVM-IR ->] opt: <a href="https://llvm.godbolt.org/z/dNi-k2">https://llvm.godbolt.org/z/dNi-k2</a><br></div><div><br></div><div>Is there any chance that we can smoothly infer that:</div><div>- x and &c are "must alias"</div><div>- x and b are "must alias"</div><div><br></div><div>I don't know how to interpret the current results, in particular the following outputs:</div><div><br></div><div>AliasSet[0x5584ab7e5f30, 1] must alias, Mod/Ref Pointers: (i32** %x, LocationSize::precise(8))<br></div><div>AliasSet[0x5584ab7e6020, 1] must alias, Mod Pointers: (i32* %y, LocationSize::precise(4))<br></div><div><br></div><div>It means we have two "must alias" sets, each of which contain only one pointer? That seems quite confusing to me.. </div><div><br></div><div>Best,</div><div>Shuai</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 9, 2020 at 6:51 PM Shuai Wang <<a href="mailto:wangshuai901@gmail.com">wangshuai901@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Hey Matt,<div><br></div><div>That's awesome. Thank you very much for all the information and clarification! Just a few follow up questions. Could you kindly shed some lights on it? Thank you!</div><div><br></div><div>1. I tried to tweak the code in the following way:</div><div><br></div><div>- Clang [-> LLVM-IR]: <a href="https://llvm.godbolt.org/z/n9rGrs" target="_blank">https://llvm.godbolt.org/z/n9rGrs</a><br>- [LLVM-IR ->] opt: <a href="https://llvm.godbolt.org/z/Uc6h5Y" target="_blank">https://llvm.godbolt.org/z/Uc6h5Y</a><br></div><div><br></div><div>And i note that the outputs are:</div><div><br></div><div><pre style="box-sizing:border-box;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;margin-top:0px;margin-bottom:0px;overflow:auto;color:rgb(33,37,41);width:1748px;padding-top:3px;padding-bottom:0px;background-color:rgb(245,245,245);height:367.105px"><p style="box-sizing:border-box;margin:0px">Alias sets for function 'main':</p><p style="box-sizing:border-box;margin:0px">Alias Set Tracker: 2 alias sets for 4 pointer values.</p><p style="box-sizing:border-box;margin:0px"> <b>AliasSet[0x563faa6c6260, 5] may alias, Mod/Ref Pointers: (i8* %0, LocationSize::precise(4)), (i32* %a, LocationSize::precise(4)), (i8* %1, LocationSize::precise(4)), (i32* %b, LocationSize::precise(4))</b></p><p style="box-sizing:border-box;margin:0px"><b> </b> 1 Unknown instructions: call void @NOALIAS(i8* nonnull %0, i8* nonnull %1) #3</p><p style="box-sizing:border-box;margin:0px"> <b>AliasSet[0x563faa6b45e0, 1] must alias, Mod/Ref forwarding to 0x563faa6c6260</b></p><p style="box-sizing:border-box;margin:0px"><br style="box-sizing:border-box"></p><p style="box-sizing:border-box;margin:0px">===== Alias Analysis Evaluator Report =====</p><p style="box-sizing:border-box;margin:0px"> 6 Total Alias Queries Performed</p><p style="box-sizing:border-box;margin:0px"> 4 no alias responses (66.6%)</p><p style="box-sizing:border-box;margin:0px"> <b> 0 may alias responses (0.0%)</b></p><p style="box-sizing:border-box;margin:0px"> 0 partial alias responses (0.0%)</p><p style="box-sizing:border-box;margin:0px"> <b>2 must alias responses (33.3%)</b></p></pre></div></div><div><br></div><div>I am trying to interpret the outputs, so if I understand correctly, the output indicates that we have an alias set of 4 pointers which "potentially" point to the same memory region, correct? Then is there any more accurate analysis pass that I could use to somewhat infer that "there are two must alias sets, each set has two pointers"? Correct me if I was wrong here.. Using my local opt (version 6.0), I tried to iterate all feasible alias analysis passes but the results are not changed.</div><div><br></div><div>Also, what is the "must alias, Mod/Ref forwarding to 0x563faa6c6260"? </div><div><br></div><div>And how to interpret that we have "2 must alias responses"? Where does it come from? And why do we have "0 may alias response"? I would expect to have at least "4 may alias responses" as well? </div><div><br></div><div>2. I note that using the latest opt (version 11.0?) gives different outputs with my local opt (version 6.0). For opt (version 6.0), it reports: 2 alias sets for 2 pointer values.</div><div><br></div><div>More importantly, can I expect to get generally better alias analysis results when switching to version 11.0? </div><div><br></div><div>Thank you very much! </div><div><br></div><div>Best,</div><div>Shuai</div><div><br></div><div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 9, 2020 at 6:14 PM Matt P. Dziubinski <<a href="mailto:matdzb@gmail.com" target="_blank">matdzb@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 7/9/2020 10:15, Shuai Wang via llvm-dev wrote:<br>
> Hello,<br>
> <br>
> I am performing alias analysis toward the following simple code:<br>
> <br>
> [...]<br>
> <br>
> I checked the generated .ll code, and it shows that within the main <br>
> function and NOALIAS functions, there is only a "ret" statement, with no <br>
> global or local variables used. Could anyone shed some lights on where <br>
> the "1 may alias" come from? And is there a way that I can force the <br>
> alias analysis algorithm to focus only the "main" function? Thank you <br>
> very much.<br>
<br>
Hi!<br>
<br>
Here's more information after initializing the variables (assuming the <br>
intent in the source code was, e.g., to initialize `a` and `b` to `0` <br>
and the pointers `f1` and `f2` to `NULL`, using aggregate initialization <br>
for `s`):<br>
- Clang [-> LLVM-IR]: <a href="https://llvm.godbolt.org/z/WT7V3E" rel="noreferrer" target="_blank">https://llvm.godbolt.org/z/WT7V3E</a><br>
- [LLVM-IR ->] opt: <a href="https://llvm.godbolt.org/z/Veswa4" rel="noreferrer" target="_blank">https://llvm.godbolt.org/z/Veswa4</a><br>
<br>
Alias sets for function 'main': Alias Set Tracker: 1 alias sets for 2 <br>
pointer values.<br>
AliasSet[0x55ec7f9a23e0, 3] may alias, Mod/Ref Pointers: (i8* %0, <br>
LocationSize::precise(4)), (i32* %a, LocationSize::precise(4))<br>
<br>
Note that in the original source code `a`, `b` are <br>
uninitialized--consequently, attempting to access `s[a].f1` and <br>
`s[b].f2` is undefined behavior (as we're using automatic storage <br>
duration objects `a` and `b` while their values are indeterminate): <br>
<a href="https://taas.trust-in-soft.com/tsnippet/t/acff56c8" rel="noreferrer" target="_blank">https://taas.trust-in-soft.com/tsnippet/t/acff56c8</a><br>
<br>
Cf. <a href="https://cigix.me/c17#6.7.9.p10" rel="noreferrer" target="_blank">https://cigix.me/c17#6.7.9.p10</a> ("If an object that has automatic <br>
storage duration is not initialized explicitly, its value is <br>
indeterminate.") & <a href="https://cigix.me/c17#J.2.p1" rel="noreferrer" target="_blank">https://cigix.me/c17#J.2.p1</a><br>
("The behavior is undefined in the following circumstances: [...] The <br>
value of an object with automatic storage duration is used while it is <br>
indeterminate").<br>
<br>
As such, you can notice that most of the code is going to be optimized <br>
away between mem2reg and dead argument elimination:<br>
<a href="https://llvm.godbolt.org/z/iEdKE_" rel="noreferrer" target="_blank">https://llvm.godbolt.org/z/iEdKE_</a><br>
<br>
(Similarly, even if `a` and `b` were initialized to `0`, we only wrote <br>
to `f1` for `s[0]` and `s[1]`, so accessing `s[b].f2` is again using an <br>
object while it is indeterminate and undefined behavior.)<br>
<br>
*** IR Dump After Promote Memory to Register ***<br>
<br>
; the following corresponds to loading `s[a].f1`<br>
%3 = load i32, i32* %a, align 4, !tbaa !7<br>
%idxprom = sext i32 %3 to i64<br>
%arrayidx3 = getelementptr inbounds [2 x %struct.MyStruct], [2 x <br>
%struct.MyStruct]* %s, i64 0, i64 %idxprom<br>
%f14 = getelementptr inbounds %struct.MyStruct, %struct.MyStruct* <br>
%arrayidx3, i32 0, i32 0<br>
%4 = load i32*, i32** %f14, align 16, !tbaa !2<br>
%5 = bitcast i32* %4 to i8*<br>
<br>
; the following corresponds to loading `s[b].f2`<br>
%6 = load i32, i32* %b, align 4, !tbaa !7<br>
%idxprom5 = sext i32 %6 to i64<br>
%arrayidx6 = getelementptr inbounds [2 x %struct.MyStruct], [2 x <br>
%struct.MyStruct]* %s, i64 0, i64 %idxprom5<br>
%f2 = getelementptr inbounds %struct.MyStruct, %struct.MyStruct* <br>
%arrayidx6, i32 0, i32 1<br>
%7 = load i32*, i32** %f2, align 8, !tbaa !9<br>
%8 = bitcast i32* %7 to i8*<br>
call void @NOALIAS(i8* %5, i8* %8)<br>
<br>
*** IR Dump After Dead Argument Elimination ***<br>
; note how the arguments have been rewritten to `undef` in the following:<br>
call void @NOALIAS(i8* undef, i8* undef)<br>
<br>
> And is there a way that I can force the alias analysis algorithm to <br>
focus only the "main" function?<br>
<br>
One way is to make the definition of `NOALIAS` unavailable (as if <br>
external) by only providing the declaration (as in the above examples).<br>
<br>
Best,<br>
Matt<br>
</blockquote></div></div>
</blockquote></div>