[LLVMdev] Strange pointer aliasing behaviour

NAKAMURA Takumi geek4civic at gmail.com
Fri Jun 18 08:07:19 PDT 2010


FYI,
the case below can be folded with -scev-aa -licm,
to hoist this->_length on former loop.

class LittleList2X {
public:
       int     _length;
       double  _data[8];

       LittleList2X( int length )
       {
               _length = length;
	       int i = 0;
#if 1
               for( ; i<_length && i <= 0x1FFFFFFE; i++ )
                       _data[i] = 0;
#endif
               for( ; i<_length; i++ )
                       _data[i] = 0;
       }
};

Rationale: the pass ScalarEvolution discovers range of &_data[i] must be finite.
(impossible when i >= 0x1FFFFFFF on p:32 target)

...Takumi



2010/6/17 Pierre C <lists at peufeu.com>:
>
> I'm hitting a strange pointer aliasing "bug". Here is a test case :
>
> /* SOURCE CODE */
>
> #define little_list_size 8
>
> class LittleList1 {
> public:
>        int     _length;
>        double  _data[ little_list_size ];
>
>        LittleList1( int length )
>        {
>                _length = length;
>                for( int i=0; i<length; i++ )
>                        _data[i] = 0;
>        }
> };
>
> class LittleList2 {
> public:
>        int     _length;
>        double  _data[ little_list_size ];
>
>        LittleList2( int length )
>        {
>                _length = length;
>                for( int i=0; i<_length; i++ )
>                        _data[i] = 0;
>        }
> };
>
> int func1()
> {
>        LittleList1 l(4);
>        return l._length;
> }
>
> int func2()
> {
>        LittleList2 l(4);
>        return l._length;
> }
>
> /* END SOURCE CODE */
>
> The only difference between the 2 classes is in the constructor, in the
> line :
>        for( int i=0; i<_length; i++ )
>
> One has "length" which is a function parameter, the other has "_length"
> which is the class member which was initialized in the same constructor.
>
> Now let's compile and optimize :
>
> llvm-g++ -emit-llvm -Winline -O3 -Iinclude  -c test2.cpp -o test2.bc
> opt -S -O3 -print-alias-sets -count-aa test2.bc
>
> Result :
>
> %struct.LittleList1 = type { i32, [8 x double] }
>
> ********
> Here, func1() is perfectly optimized :
> ********
>
> define i32 @_Z5func1v() nounwind readnone {
> entry:
>   ret i32 4
> }
>
>
> ********
> func2() should give the exact same result as func1, however ...
>
> Alias Set Tracker: 1 alias sets for 2 pointer values.
>   AliasSet[0x0x8ca140,2] may alias, Mod/Ref   Pointers: (i32* %0, 4),
> (double* %scevgep.i, 8)
>
> A spurious alias comes up between the 2 fields of the struct (which should
> in theory not happen).
> So, it reloads _length at each iteration, thus no optimization takes place
> and the code below is generated :
>
> ********
>
> define i32 @_Z5func2v() nounwind readnone {
> entry:
>   %l = alloca %struct.LittleList1, align 8        ; <%struct.LittleList1*>
> [#uses=2]
>   %0 = getelementptr inbounds %struct.LittleList1* %l, i64 0, i32 0 ;
> <i32*> [#uses=2]
>   store i32 4, i32* %0, align 8
>   br label %bb.i
>
> bb.i:                                             ; preds = %bb.i, %entry
>   %indvar.i = phi i64 [ %tmp, %bb.i ], [ 0, %entry ] ; <i64> [#uses=2]
>   %tmp = add i64 %indvar.i, 1                     ; <i64> [#uses=2]
>   %tmp2.i = trunc i64 %tmp to i32                 ; <i32> [#uses=1]
>   %scevgep.i = getelementptr %struct.LittleList1* %l, i64 0, i32 1, i64
> %indvar.i ; <double*> [#uses=1]
>   store double 0.000000e+00, double* %scevgep.i, align 8
>   %1 = load i32* %0, align 8                      ; <i32> [#uses=2]
>   %2 = icmp sgt i32 %1, %tmp2.i                   ; <i1> [#uses=1]
>   br i1 %2, label %bb.i, label %_ZN11LittleList2C1Ei.exit
>
> _ZN11LittleList2C1Ei.exit:                        ; preds = %bb.i
>   ret i32 %1
>
> ********
>
> g++ correctly resolves this alias and both functions are compiled to
> "return 4".
> llvm-gcc (and opt) detect a spurious alias on func2() (all alias passes
> seem to do the same here) which prevents optimizations, and in other cases
> more complex than this simple test, it also prevents loop unrolling and
> many other optimizations.
>
> Can I do something to fix this ?
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>




More information about the llvm-dev mailing list