<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Dec 24, 2017 at 4:55 AM, Nuno Lopes <span dir="ltr"><<a href="mailto:nunoplopes@sapo.pt" target="_blank">nunoplopes@sapo.pt</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ah, this was my misunderstanding; the picture of the lattice I sent before was wrong..<br>
<br>
Ok, now assuming I understand the meaning of each value, I'll claim the lattice now has 3 bottom values: NoModRef, MustRef, MustMod. These 3 are the most precise values and intersection of these with any other value cannot yield a more precision value (well, assuming there's no UB that could lead to some ⊥ value, which we don't have).<br></blockquote><div><br></div><div>Hmm, I haven't thought about this a lot, but I was intending to have only NoModRef as the bottom of the lattice.</div><div>From MustRef and MustMod you could in theory go to Must, which will "default" to NoModRef (meaning, I'm going in the code and re-setting that Must bit to get NoModRef if we reach Must).</div><div>The reason for not having MustRef or MustMod as bottoms, is that, say you have a call with only one argument, A, so you know there's Must alias with A. So you have MustModRef. Then say you find the call cannot write, you'll get MustRef. Then say you find the call does not read either, you're left with Must. (As I mentioned above this has to be reset to NoModRef).</div><div><br></div><div>In this patch already committed I removed most (all?) of the processing for calls, and I have a follow-up patch that addresses precisely the above.</div><div>In this follow-up it's pretty obvious you can end up with Must, and you have to rest that to NoModRef as the single lattice bottom.</div><div><br></div><div>I send the follow-up patch out after the holidays.</div><div><br></div><div>Let me know what you think in the mean time :)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
This function doesn't seem right to me:<br>
inline bool isNoModRef(const ModRefInfo MRI) {<br>
 return (MRI & MustModRef) == Must;<br>
}<br>
<br>
There's only one value representing NoModRef, so shouldn't this function just do a simple comparison "MRI == NoModRef"?<br>
<br>
<br>
This function is then used here (and in other similar places):<br>
<br>
ModRefInfo AAResults::getArgModRefInfo(Im<wbr>mutableCallSite CS, unsigned ArgIdx) {<br>
 ModRefInfo Result = ModRefInfo::ModRef;<br>
<br>
 for (const auto &AA : AAs) {<br>
   Result = intersectModRef(Result, AA->getArgModRefInfo(CS, ArgIdx));<br>
<br>
   // Early-exit the moment we reach the bottom of the lattice.<br>
   if (isNoModRef(Result))<br>
     return Result;<br>
 }<br>
<br>
<br>
NoModRef is only one of the bottom lattice values. I think that's not the correct function to call here. I think you need that check if the value is a power of 2 or 0 (just in case of UB):<br>
inline bool isBottomModRef(const ModRefInfo MRI) {<br>
 return MRI & (MRI-1) == 0;<br>
}<br>
<br>
<br>
Have a nice Christmas! :)<br></blockquote><div><br></div><div>Thanks, you too! :) </div><div><br></div><div>Best,</div><div>Alina</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Nuno<br>
<br>
<br>
-----Original Message----- From: Alina Sbirlea<br>
Sent: Friday, December 22, 2017 9:19 PM<br>
To: Nuno Lopes<br>
Cc: llvm-commits<br>
Subject: Re: [llvm] r321309 - [ModRefInfo] Add must alias info to ModRefInfo.<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
Hi Nuno,<br>
<br>
The definition for setting Must is whether must alias with the location was found and there is no alias with other locations.<br>
Yes, it's possible a write does not occur for cmpxchg, and that's fine. ModRef means it may read and it may write, but it doesn't necessarily mean it will. MustModRef means it may read and it may write, and if so, there is a must alias with that location and with no other locations. It doesn't mean it must read and write to that location.<br>
<br>
<br>
The opposite scenario: if, say, you knew for sure statement S writes to A, and may write to B, then Must will not be set, because of B. So you get Mod.<br>
Whereas if S *may* write to A and accesses nothing else, then you get MustMod.<br>
<br>
<br>
Does this make sense?<br>
<br>
Please let me know if I'm missing something obvious here or whether I should update the documentation to make this clearer.<br>
<br>
Thanks,<br>
Alina<br>
<br>
<br>
<br>
On Fri, Dec 22, 2017 at 8:10 AM, Nuno Lopes <<a href="mailto:nunoplopes@sapo.pt" target="_blank">nunoplopes@sapo.pt</a>> wrote:<br>
Hi Alina,<br>
<br>
Some comments below; I think some operations cannot be marked as MustModRef:<br>
<br>
<br>
@@ -440,9 +479,17 @@ ModRefInfo AAResults::getModRefInfo(cons<br>
  if (isStrongerThanMonotonic(CX->g<wbr>etSuccessOrdering()))<br>
    return ModRefInfo::ModRef;<br>
<br>
-  // If the cmpxchg address does not alias the location, it does not access it.<br>
-  if (Loc.Ptr && !alias(MemoryLocation::get(CX)<wbr>, Loc))<br>
-    return ModRefInfo::NoModRef;<br>
+  if (Loc.Ptr) {<br>
+    AliasResult AR = alias(MemoryLocation::get(CX), Loc);<br>
+    // If the cmpxchg address does not alias the location, it does not access<br>
+    // it.<br>
+    if (AR == NoAlias)<br>
+      return ModRefInfo::NoModRef;<br>
+<br>
+    // If the cmpxchg address aliases the pointer as must alias, set Must.<br>
+    if (AR == MustAlias)<br>
+      return ModRefInfo::MustModRef;<br>
+  }<br>
<br>
According to the manual (<a href="http://llvm.org/docs/LangRef.html#id205" rel="noreferrer" target="_blank">http://llvm.org/docs/LangRef.<wbr>html#id205</a>), cmpxchg may or may not write to the location, depending on whether the comparison succeeds. For weak operations, the write may not occur even if the comparison succeeds.<br>
<br>
<br>
@@ -453,9 +500,17 @@ ModRefInfo AAResults::getModRefInfo(cons<br>
  if (isStrongerThanMonotonic(RMW-><wbr>getOrdering()))<br>
    return ModRefInfo::ModRef;<br>
<br>
-  // If the atomicrmw address does not alias the location, it does not access it.<br>
-  if (Loc.Ptr && !alias(MemoryLocation::get(RMW<wbr>), Loc))<br>
-    return ModRefInfo::NoModRef;<br>
+  if (Loc.Ptr) {<br>
+    AliasResult AR = alias(MemoryLocation::get(RMW)<wbr>, Loc);<br>
+    // If the atomicrmw address does not alias the location, it does not access<br>
+    // it.<br>
+    if (AR == NoAlias)<br>
+      return ModRefInfo::NoModRef;<br>
+<br>
+    // If the atomicrmw address aliases the pointer as must alias, set Must.<br>
+    if (AR == MustAlias)<br>
+      return ModRefInfo::MustModRef;<br>
+  }<br>
<br>
<br>
According to the manual (<a href="http://llvm.org/docs/LangRef.html#id210" rel="noreferrer" target="_blank">http://llvm.org/docs/LangRef.<wbr>html#id210</a>) not all 'atomicrmw' operations read the pointer. The instruction always writes, but may not read (depending on the underlying operation).<br>
<br>
Nuno <br>
</div></div></blockquote></div><br></div></div>