I am currently testing the following patch to fix PR63175 - a regression
in expanding realign-load expressions the vectorizer generates.
get_object_alignment_2 gets MEM[&MEM[ptr + 4] & -16] here and while
it extracts an alignment of 128 from the & -16 recursing on the
address &MEM[ptr + 4] gets it a misalign offset of 32 which it fails
to re-apply the masking to.

Bootstrap and regtest running on x86_64-unknown-linux-gnu, I'm also
trying a ppc64-linux bootstrap & regtest (the only target that
exercises that vectorizer path I think), but it'll take me some
while there because I have no baseline.

(still the bug is quite obvious)

Richard.

2015-02-26  Richard Biener  <rguent...@suse.de>

        PR middle-end/63175
        * builtins.c (get_object_alignment_2): Make sure to re-apply
        the ANDed mask after recursing to its operand gets us a new
        misalignment bit position.

Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c      (revision 220959)
--- gcc/builtins.c      (working copy)
*************** get_object_alignment_2 (tree exp, unsign
*** 359,371 ****
        tree addr = TREE_OPERAND (exp, 0);
        unsigned ptr_align;
        unsigned HOST_WIDE_INT ptr_bitpos;
  
        if (TREE_CODE (addr) == BIT_AND_EXPR
          && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
        {
!         align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
!                   & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
!         align *= BITS_PER_UNIT;
          addr = TREE_OPERAND (addr, 0);
        }
  
--- 359,373 ----
        tree addr = TREE_OPERAND (exp, 0);
        unsigned ptr_align;
        unsigned HOST_WIDE_INT ptr_bitpos;
+       unsigned HOST_WIDE_INT ptr_bitmask = ~0;
  
+       /* If the address is explicitely aligned, handle that.  */
        if (TREE_CODE (addr) == BIT_AND_EXPR
          && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
        {
!         ptr_bitmask = TREE_INT_CST_LOW (TREE_OPERAND (addr, 1));
!         ptr_bitmask *= BITS_PER_UNIT;
!         align = ptr_bitmask & -ptr_bitmask;
          addr = TREE_OPERAND (addr, 0);
        }
  
*************** get_object_alignment_2 (tree exp, unsign
*** 373,378 ****
--- 375,383 ----
        = get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos);
        align = MAX (ptr_align, align);
  
+       /* Re-apply explicit alignment to the bitpos.  */
+       ptr_bitpos &= ptr_bitmask;
+ 
        /* The alignment of the pointer operand in a TARGET_MEM_REF
         has to take the variable offset parts into account.  */
        if (TREE_CODE (exp) == TARGET_MEM_REF)

Reply via email to