[LLVMdev] BasicAliasAnalysis: constant does not alias with noalias parameter

Hans Wennborg hans at hanshq.net
Thu Nov 12 23:36:46 PST 2009


Attaching patch with unnecessary trailing ; removed from test case.

Thank you both for helping to straighten this out, and sorry about the 
confusion.


Hans


Nick Lewycky wrote:
> Hans Wennborg wrote:
>> After discussing with Nick Lewycky in the IRC channel, here comes a 
>> less aggressive patch.
>>
>> We were worried that a constant pointer could alias with a GlobalValue.
>> Also, if one pointer could be a GlobalValue and the other a 
>> GlobalAlias with the GlobalValue as aliasee.
>> However, I was not able to produce a test where this happens wihout 
>> the getUnderlyingObject() returning the same value.
>>
>> It would be nice if someone could produce such a test case, or dismiss 
>> the possibility of this happening.
> 
> My bad, it seems that while I wasn't looking, someone taught 
> getUnderlyingObject to look through GlobalAliases and return what they 
> point to!
> 
> However the previous patch was wrong given code like:
> 
>   @gv = global i32 0
>   define void @test() {
>     store i16 1, i16* inttoptr(i64 add(i64 ptrtoint(i32* @gv to i64), 
> i64 1) to i16*) ; ; Not dead
>     store i32 2, i32* @gv
>     ret void
>   }
> 
>> Anyway, saying that a Constant does not alias with a non-const 
>> isIdentifiedObject object seems safe.
> 
> Yup!
> 
> Please remove the tailing ; on the lines where they aren't needed in 
> your tests. Besides that, your patch looks great! Thanks!
> 
> Nick
> 
>> / Hans
>>
>>
>> Hans Wennborg wrote:
>>> Dan Gohman wrote:
>>>> On Nov 4, 2009, at 6:43 AM, Hans Wennborg wrote:
>>>>
>>>>> Here is another change I'd like to suggest to the BasicAliasAnalysis.
>>>>>
>>>>> LLVM fails to remove the dead store in the following code:
>>>>>
>>>>> %t = type { i32 }
>>>>>
>>>>> define void @f(%t* noalias nocapture %stuff ) {
>>>>>    %p = getelementptr inbounds %t* %stuff, i32 0, i32 0
>>>>>
>>>>>    store i32 1, i32* %p; <-- This store is dead
>>>>>
>>>>>    %x = load i32* inttoptr (i32 12345 to i32*)
>>>>>    store i32 %x, i32* %p
>>>>>    ret void
>>>>> }
>>>>>
>>>>>
>>>>> when run through
>>>>> ./llvm-as -o - test2.ll | ./opt -O3 -o - | ./llvm-dis -o -
>>>>>
>>>>>
>>>>> The problem is that the alias analysis is unsure about whether %p 
>>>>> and 12345 may alias. But since %p is derived from %stuff, which has 
>>>>> the noalias attribute, and 12345 is a constant and therefore cannot 
>>>>> be derived from %stuff, they cannot alias.
>>>>
>>>> This sounds right. And actually, it's not limited to noalias;
>>>> isIdentifiedObject objects don't alias inttoptr-casted integer
>>>> literals either. I have a few comments on the patch below.
>>>>
>>>>> I'm attaching a patch which implements this. Please comment on 
>>>>> whether this is sane, and if my code is the right way of doing it.
>>>>>
>>>>>
>>>>> / Hans
>>>>> Index: lib/Analysis/BasicAliasAnalysis.cpp
>>>>> ===================================================================
>>>>> --- lib/Analysis/BasicAliasAnalysis.cpp    (revision 86023)
>>>>> +++ lib/Analysis/BasicAliasAnalysis.cpp    (working copy)
>>>>> @@ -643,6 +643,23 @@
>>>>>   if (!isa<PointerType>(V1->getType()) || 
>>>>> !isa<PointerType>(V2->getType()))
>>>>>     return NoAlias;  // Scalars cannot alias each other
>>>>>
>>>>> +  // Constant ptr cannot alias with a noalias attribute
>>>>> +  if (isa<Constant>(V1) && isa<PointerType>(V2->getType())) {
>>>>> +    while (const GEPOperator *g = dyn_cast<GEPOperator>(V2))
>>>>> +      V2 = g->getOperand(0);
>>>>> +
>>>>> +    if (const Argument *A = dyn_cast<Argument>(V2))
>>>>> +      if (A->hasNoAliasAttr())
>>>>> +        return NoAlias;
>>>>> +  } else if (isa<Constant>(V2) && isa<PointerType>(V1->getType())) {
>>>>> +    while (const GEPOperator *g = dyn_cast<GEPOperator>(V1))
>>>>> +      V1 = g->getOperand(0);
>>>>> +
>>>>> +    if (const Argument *A = dyn_cast<Argument>(V1))
>>>>> +      if (A->hasNoAliasAttr())
>>>>> +        return NoAlias;
>>>>> +  }
>>>>
>>>> The GEP logic here is effectively doing (a subset of) what
>>>> getUnderlyingObject does. It would be better to move these checks
>>>> below the getUnderlyingObject calls just below so that they can
>>>> use the results from those calls instead.
>>>>
>>>> And instead of checking for a no-alias argument, this code could
>>>> use isIdentifiedObject instead, following my comment above.
>>>
>>> Thank you for the input, this certainly made things nicer. I have 
>>> attached a patch that does this together with a test case.
>>>
>>> / Hans
>>>
>>>>
>>>> Dan
>>>>
>>>>>   // Figure out what objects these things are pointing to if we can.
>>>>>   const Value *O1 = V1->getUnderlyingObject();
>>>>>   const Value *O2 = V2->getUnderlyingObject();
>>>>> _______________________________________________
>>>>> LLVM Developers mailing list
>>>>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: BasicAliasAnalysis3.patch
Type: text/x-patch
Size: 1993 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20091113/c5e63f56/attachment.bin>


More information about the llvm-dev mailing list