<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Sep 3, 2017 at 6:16 PM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Sun, Sep 3, 2017 at 4:53 PM, Daniel Berlin <<a href="mailto:dberlin@dberlin.org">dberlin@dberlin.org</a>> wrote:<br>
>> > I also don't understand "  // It's tempting to handle inttoptr and<br>
>> > ptrtoint<br>
>> > as no-ops, however this can<br>
>> >   // lead to pointer expressions which cannot safely be expanded to<br>
>> > GEPs,<br>
>> >   // because ScalarEvolution doesn't respect the GEP aliasing rules when<br>
>> >   // simplifying integer expressions."<br>
>> ><br>
>> > 1. What are "the gep aliasing rules", exactly?<br>
>> > <a href="https://llvm.org/docs/LangRef.html#pointeraliasing" rel="noreferrer" target="_blank">https://llvm.org/docs/LangRef.<wbr>html#pointeraliasing</a> does not mention<br>
>> > special<br>
>> > rules for gep :)<br>
>><br>
>> I think the rule it is talking about is that reads and writes on a GEP<br>
>> are allowed to only read from and write to the allocation that is<br>
>> passed in as the first parameter to the GEP<br>
><br>
> When we had the discussion about "inrange" and "inbounds", (and elsewhere,<br>
> like field accesses) it was raised repeatedly that it's just fine to gep<br>
> outside what would be the normal "range" of a pointer, because you can't<br>
> ever really tell what it is.<br>
> IE a gep of a given pointer can access anything it wants.<br>
><br>
> In fact, it seemed generally accepted that you can happily GEP from a<br>
> pointer to anywhere you want unless there's an inrange or inbounds on it.<br>
<br>
</span>I think there are two issues here.<br>
<br>
Non-inbounds GEPs to outside the base allocation is allowed by<br>
themselves, and produce a bitwise value. </blockquote><div><br></div><div>Sure</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Inbounds GEPs to outside the<br>
base allocation produces poison.<br>
<br>
So this is allowed:<br>
<br>
  %p0 = malloc(16);<br>
  %p1 = malloc(16);<br>
  %gep = gep i8* %p0, i64 18<br>
  %cmp = icmp eq %gep, %p1<br>
  br i1 %cmp, ...<br>
<br>
but it would not be allowed if the GEP was inbounds (we'd be branching<br>
on poison).<br>
<br></blockquote><div><br></div><div>Sure</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
*However* (this is the "and issue reads/writes" bit in my previous<br>
email) for reading / writing through the result of a GEP the GEP must<br>
*also* follow the pointer aliasing rules.  Of course the GEP must not<br>
have produced poison either, that's necessary but not sufficient for<br>
safe memory operations.<br>
<span class=""><br>
> So i'm not sure what you mean by "the allocation", since none of these<br>
> allocations are  defined in terms of llvm memory semantics (IE they aren't<br>
> alloca's, they are malloc/frees).<br>
> If that's not the case, we are not being consistent (IE we're losing<br>
> optimizations we shouldn't, and we have correctness issues we don't think we<br>
> do).<br>
<br>
</span>[snip]<br>
<span class=""><br>
> This set of rules, without anything more, implies we have both correcntess<br>
> and optimization issues :)<br>
<br>
</span>The semantic in "pointer aliasing rules" is already implemented --<br>
BasicAA returns NoAlias for %p1 and %gep even though @subtract could<br>
have returned an offset that will guarantee that at runtime %p1 ==<br>
%gep:</blockquote><div>This is definitely news to me.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
```<br>
target datalayout = "e-m:e-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
target triple = "x86_64-unknown-linux-gnu"<br>
<br>
define void @f(i64 %arg, i64 %arg1) {<br>
bb:<br>
  %p0 = tail call noalias i8* @malloc(i64 %arg) #3<br>
  %p1 = tail call noalias i8* @malloc(i64 %arg) #3<br>
  %offset = tail call i64 @subtract(i8* %p1, i8* %p0)<br>
  %gep = getelementptr i8, i8* %p0, i64 %offset  ;; not inbounds<br>
  ret void<br>
}<br>
<br>
declare noalias i8* @malloc(i64)<br>
declare i64 @subtract(i8*, i8*)<br>
```<br>
<br>
I believe this follows from the GetUnderlyingObject and<br>
isIdentifiedObject related logic in  BasicAAResult::aliasCheck.<br>
<br>
And I'm not aware of any transforms in LLVM today that contradict the<br>
pointer aliasing rules.<br></blockquote><div><br></div><div>I assume you meant "do the wrong thing here". Which i still believe is definitely wrong, FWIW, but i'm too lazy to go searching through bugzilla some more today, so i'm going to let it go.</div><div><br></div><div><br></div></div></div></div>