Unfortunately this patch doesn't work because the memory dependency is Anti in this case.
Why TBAA cannot handle anti- & output- dependencies? I check GCC bug database, and found pr38503 & pr38964. I don't fully understand it, but seems to me is related in handling C++ new operator. But this example is pretty clear and has nothing to do with C++ and new statement. Isn't it too conservative to disable TBAA for anti- & output- dependency here? Bingfeng -----Original Message----- From: Richard Biener [mailto:rguent...@suse.de] Sent: 31 January 2014 15:24 To: Bingfeng Mei; gcc@gcc.gnu.org Subject: Re: No TBAA before ptr_derefs_may_alias_p? On 1/31/14 4:02 PM, Bingfeng Mei wrote: > Hi, > I got this simple example to vectorize. Somehow, GCC (4.8) generates loop > version because > it cannot determine alias between acc[i] write and x[i].real read. It is > pretty obvious to me that they are not aliased based on TBAA information. > > typedef struct > { > short real; > short imag; > } complex16_t; > > void > libvector_AccSquareNorm_ref (unsigned long long *acc, > const complex16_t *x, unsigned len) > { > for (unsigned i = 0; i < len; i++) > { > acc[i] += > ((unsigned long long)((int)x[i].real * x[i].real)) + > ((unsigned long long)((int)x[i].imag * x[i].imag)); > } > } > > Tracing into how the alias information is calculated, I found it hits the > following code > by calling ptr_derefs_may_alias_p and return true. ptr_derefs_may_alias_p > doesn't contain > TBAA disambiguation code. Should we add check before that? > > /* If we had an evolution in a MEM_REF BASE_OBJECT we do not know > the size of the base-object. So we cannot do any offset/overlap > based analysis but have to rely on points-to information only. */ > if (TREE_CODE (addr_a) == MEM_REF > && DR_UNCONSTRAINED_BASE (a)) > { > if (TREE_CODE (addr_b) == MEM_REF > && DR_UNCONSTRAINED_BASE (b)) > return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0), > TREE_OPERAND (addr_b, 0)); > else > return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0), > build_fold_addr_expr (addr_b)); > } > else if (TREE_CODE (addr_b) == MEM_REF > && DR_UNCONSTRAINED_BASE (b)) > return ptr_derefs_may_alias_p (build_fold_addr_expr (addr_a), > TREE_OPERAND (addr_b, 0)); > > /* Otherwise DR_BASE_OBJECT is an access that covers the whole object > that is being subsetted in the loop nest. */ > if (DR_IS_WRITE (a) && DR_IS_WRITE (b)) > return refs_output_dependent_p (addr_a, addr_b); > else if (DR_IS_READ (a) && DR_IS_WRITE (b)) > return refs_anti_dependent_p (addr_a, addr_b); > return refs_may_alias_p (addr_a, addr_b); > > This issue can be reproduced on trunk x86-64 gcc. True, you can add a if (flag_strict_aliasing && DR_IS_WRITE (a) && DR_IS_READ (b) && !alias_sets_conflict_p (get_alias_set (DR_REF (a)), get_alias_set (DR_REF (b))) return false; before the ptr_derefs_may_alias_p calls. TBAA is only valid for true dependences. Richard. > Cheers, > Bingfeng Mei >