This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Some aliasing questions


On April 8, 2016 8:10:16 PM GMT+02:00, Bill Schmidt <wschmidt@linux.vnet.ibm.com> wrote:
>Hi,
>
>I ran into a couple of aliasing issues with a project I'm working on,
>and have some questions.
>
>The first is an issue with TOC-relative addresses on PowerPC.  These
>are
>symbolic addresses that are to be loaded from a fixed slot in the table
>of contents, as addressed by the TOC pointer (r2).  In the RTL phases
>prior to register allocation, these are described in an UNSPEC that
>looks like this for an example store:
>
>(set (mem/c:DI (unspec:DI [
>       (symbol_ref:DI ("*.LANCHOR0") [flags 0x182])
>       (reg:DI 2 2)
>      ] UNSPEC_TOCREL) [1 svul+0 S8 A128])
>     (reg:DI 178))
>
>The UNSPEC helps keep track of the r2 reference until this is split
>into
>two or more insns depending on the memory model.
>
>I discovered that alias.c:memrefs_conflict_p is unable to make
>must-alias decisions about these, because it doesn't see into the
>UNSPEC
>to find the symbol_ref.  Thus it returns -1 (no information) when
>comparing the above with:
>
>(set (reg/f:DI 177)
>     (unspec:DI [
>        (symbol_ref:DI ("*.LANCHOR0") [flags 0x182])
>        (reg:DI 2 2)
>      ] UNSPEC_TOCREL))
>(set (reg:V2DI 159)
>     (mem:V2DI (and:DI (reg/f:DI 177)
>            (const_int -16 [0xfffffffffffffff0])) [4 *_11+0 S16 A128]))
>
>But clearly the two addresses overlap.
>
>I added the following hack, and the code then returns 1 (must-alias),
>without regressing anything in the test suite.
>
>Index: gcc/alias.c                                                     
>        
>===================================================================
>--- gcc/alias.c (revision 234726)                                      
>        
>+++ gcc/alias.c (working copy)                                         
>        
>@@ -2213,6 +2213,12 @@ memrefs_conflict_p (int xsize, rtx x, int ysize,
>r
>}                                                                      
>
>}                                                                      
>   
>                                                                       
>+  /* Some targets may hide a base address in an UNSPEC.  Peel that
>away.  */   
>+  if (GET_CODE (x) == UNSPEC)                                         
>        
>+    return memrefs_conflict_p (xsize, XVECEXP (x, 0, 0), ysize, y, c);
>        
>+  if (GET_CODE (y) == UNSPEC)                                         
>        
>+    return memrefs_conflict_p (xsize, x, ysize, XVECEXP (y, 0, 0), c);
>        
>+                                                                      
>        
>if (CONSTANT_P (x))                                                    
>     
>{                                                                      
>   
>if (CONST_INT_P (x) && CONST_INT_P (y))                                
> 
>
>Now, this is probably not right for a real fix, since it assumes that
>any UNSPEC is ok for this, and that the base address will be found
>recursively in the first position.  I don't know whether any other
>targets have similar issues.  So:
>
>(1) What is the best way to handle this?  Would it be better to have
>some sort of target hook?
>
>(2) Are there other places in the aliasing infrastructure where this
>UNSPEC use could be getting us into trouble?

UNSPECs are bad for any middle-end analysis.  My suggestion is to try to avoid these.

>Another issue I see involves disjoint alias sets.  If you look closely
>at the rtx's above, they have been marked as disjoint, belonging to
>alias sets 1 and 4, respectively:
>
>[1 svul+0 S8 A128]
>[4 *_11+0 S16 A128]
>
>The gimple involved is:
>
>  svul[0] = 0;
>  svul[1] = 1;
>  svul.1_9 = (sizetype) &svul;
>  _10 = svul.1_9 & 18446744073709551600;  // i.e., -16 or 0xfff...f0
>  _11 = (__vector unsigned long *) _10;
>  vul.2_12 = *_11;
>
>where svul is file-scope:
>
>  static unsigned long long svul[2] __attribute__ ((aligned (16)));

The issue is unsigned long long vs. Unsigned long.  They do not alias according to TBAA rules.  Most x86 builtins carefully use may_alias vector types to side-step this issue.

Richard.

>Here I am exposing the semantics of the vec_ld built-in, which aligns
>the address to a 16-byte boundary by masking the low-order four bits.
>But bitwise AND only works in an integer type, so some casting there
>may
>be responsible for losing track of the fact that *_11 aliases svul.
>However, it seems odd to imply that *_11 definitely does not alias
>svul.
>So:
>
>(3) Am I doing something wrong to expose the address masking this way?
>
>(4) Are the alias sets bogus, or am I misinterpreting this?  If they
>are
>wrong, please point me to where they are computed and I can debug
>further.
>
>Thanks for any help!  I haven't dug deeply into the aliasing analysis
>before.
>
>Bill



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]