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)