[PATCH] D37419: Teach scalar evolution to handle inttoptr/ptrtoint
Hal Finkel via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 3 23:57:28 PDT 2017
On 09/04/2017 01:40 AM, Daniel Berlin wrote:
>
>
> On Sun, Sep 3, 2017 at 10:03 PM, Hal Finkel <hfinkel at anl.gov
> <mailto:hfinkel at anl.gov>> wrote:
>
>
> On 09/03/2017 11:35 PM, Daniel Berlin wrote:
>>
>>
>> On Sun, Sep 3, 2017 at 7:52 PM, Daniel Berlin
>> <dberlin at dberlin.org <mailto:dberlin at dberlin.org>> wrote:
>>
>>
>>
>> On Sun, Sep 3, 2017 at 7:17 PM, Daniel Berlin
>> <dberlin at dberlin.org <mailto:dberlin at dberlin.org>> wrote:
>>
>>
>> Sanjoy's description of the current behavior is
>> accurate.
>>
>>
>> I see two ways of looking at this:
>>
>> 1. This is a bug.
>> 2. To allow this kind of inter-object addressing you
>> need to use inttoptr/ptrtoint.
>>
>>
>> I'm fine with #2, i just feel like our rules are a little
>> hodgepodge:)
>>
>> I don't believe that it is possible for the current
>> behavior to manifest as a problem for C/C++ (and this
>> is likely the same for most higher-level languages).
>>
>>
>> I don't believe it is either - we've already stated we
>> assume aliasing does not imply pointer equality and
>> non-aliasing does not imply pointer inequality.
>> If we did, this behaviour could.
>>
>>
>> Which means the weirdest discontinuity that occurs to me off
>> the top of my head is that we are treating malloc's like
>> lifetime beginning operations in a bunch of cases (GVN does
>> this) , but if you call free on the pointer from the gep in
>> sanjoy's example, there is no way to know it could have ended
>> the lifetime of both p0 and p1 without a separate analysis.
>>
>> It means things like this in memorydependenceanalysis:
>>
>> if (const CallInst *CI = isFreeCall(Inst, &TLI)) {
>> // calls to free() deallocate the entire structure
>> Loc = MemoryLocation(CI->getArgOperand(0));
>> return MRI_Mod;
>> }
>> will say this free does not touch p1, even though it could
>> have destroyed it and ended the lifetime.
>>
>> Do we have anything that takes advantage and does something
>> silly? I don't think we have anything that advanced ATM.
>>
>>
>> Actually, this is, IMHO, worse than i initially thought.
>>
>> So imagine we free %gep from sanjoy's example.
>>
>> Right now, the above code (and elsewhere) will say that free does
>> not MOD %p1. Even if the pointer is value equal to %p1
>>
>> We already say malloc operates by returning new memory regardless
>> of what pointer value it returns. Here, free is taking a pointer
>> and we are saying it only modifies the memory that pointer can
>> alias.
>>
>> I can think of a few possibilities
>>
>> 1. Free operates by pointer value and not "abstract memory
>> location", in which case, the above code is wrong, as free will
>> modify things that are value equal, even if they do not alias.
>
> I don't believe we can have this model. We model free, I believe
> fairly, as writing to the memory being freed.
>
>
> I'm going to leave whether that's correct for another day, but if you
> want to be pedantic, all C11 says is:
> "The free function causes the space pointed to by ptr to be
> deallocated, that is, made
> available for further allocation. "
>
> (I have no urge here to go down the rabbit hole of whether you can
> free pointers you couldn't load and store due to TBAA or whatever)
>
> Thus, we need to following aliasing rules regarding what it can
> affect.
>
>
> Okay.
>
> Otherwise, we'd need to model free as potentially modifying
> anything (because we'd have no infrastructure to deal with
> figuring out what it might affect).
>
> Correct.
>
>> In this model, except through value numbering or range analysis,
>> you can't really ever tell what free has done, it may mod/ref
>> anything (and we have some bugs to fix).
>>
>> Also now malloc returns abstract memory objects, but free doesn't
>> really destroy them
>>
>> 2. An attempt by free to destroy p1 is considered UB, and
>> sanjoy's code, with a free at the end cannot validly destroy p1.
>
> This is what we have, as far as I can tell. It is true that you
> can't have an additional call to free(%p1) at the end, but that's
> irrelevant, as UB would have already occurred.
>
>
> So, i instrumented llvm to add runtime asserts about the noaliasing
> pointers before free (IE it adds an assert that, for each pointer that
> is noaliased with the pointer passed to free, free is not destroying
> that pointer), and it fails really quickly.
Are these live pointers? (i.e., could this be caused because malloc is
recycling memory blocks?)
>
> Hence, i'm going to go with "i still have trouble believing we are
> generating currently correct code that accounts for this model".
> Though i admit nothing currently takes advantage of free that i can find.
> But at least i feel like i understand what we are trying to model :)
Sounds good. ;)
We should be a bit careful, however. Or, at least I should ;) -- I'd
like to get back to doing heap-to-stack conversion at some point.
-Hal
>
>
>
>
>> I would have trouble believing we are generating currently
>> correct code in this model from any of our frontends, but willing
>> to be convinced (IE i would believe if i added asserts to free
>> calls that they are not value equal to anything llvm considers
>> the argument to noalias, it would fail)
>>
>> 3. Free is not mapped into our memory model, but malloc is.
>
> I'm not sure what this means.
>
>
> It means unlike malloc, which we've taken from c's memory model and
> said things about what it does in llvm's, we have decided not to do
> anything with free
> (IE attempts to rely on saying anything about llvm memory objects
> based on free is nonsense)
>
>
>>
>> Thoughts? Other possibilities?
>
> Referring to this:
>
> define void @f(i64 %arg, i64 %arg1) {
> bb:
> %p0 = tail call noalias i8* @malloc(i64 %arg) #3
> %p1 = tail call noalias i8* @malloc(i64 %arg) #3
> %offset = tail call i64 @subtract(i8* %p1, i8* %p0)
> %gep = getelementptr i8, i8* %p0, i64 %offset ;; not inbounds
> ret void
> }
>
> declare noalias i8* @malloc(i64)
> declare i64 @subtract(i8*, i8*)
>
> In our model, as I understand it, free of %gep: As %gep is based
> on %p0, and free must be called with a pointer to the beginning of
> the allocation, %offset must be 0. If offset is not 0, the
> behavior is undefined.
>
>
>
> Then, as i said, i think we've got a lot of cases we aren't generating
> correct code (though again, nothing is trying to take a lot of
> advantage of free).
>
>
--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170904/5254c6da/attachment.html>
More information about the llvm-commits
mailing list