diff options
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index fe8de9b..91c5d857 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1587,29 +1587,31 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, else if (TREE_CODE (t) == MEM_REF) { tree op0 = TREE_OPERAND (t, 0); - unsigned HOST_WIDE_INT aoff = BITS_PER_UNIT; - if (host_integerp (TREE_OPERAND (t, 1), 1)) + if (TREE_CODE (op0) == ADDR_EXPR + && (DECL_P (TREE_OPERAND (op0, 0)) + || CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)))) { - unsigned HOST_WIDE_INT ioff = TREE_INT_CST_LOW (TREE_OPERAND (t, 1)); - aoff = (ioff & -ioff) * BITS_PER_UNIT; - } - if (TREE_CODE (op0) == ADDR_EXPR && DECL_P (TREE_OPERAND (op0, 0))) - align = MAX (align, DECL_ALIGN (TREE_OPERAND (op0, 0))); - else if (TREE_CODE (op0) == ADDR_EXPR - && CONSTANT_CLASS_P (TREE_OPERAND (op0, 0))) - { - align = TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (op0, 0))); + if (DECL_P (TREE_OPERAND (op0, 0))) + align = DECL_ALIGN (TREE_OPERAND (op0, 0)); + else if (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0))) + { + align = TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (op0, 0))); #ifdef CONSTANT_ALIGNMENT - align = CONSTANT_ALIGNMENT (TREE_OPERAND (op0, 0), align); + align = CONSTANT_ALIGNMENT (TREE_OPERAND (op0, 0), align); #endif + } + if (TREE_INT_CST_LOW (TREE_OPERAND (t, 1)) != 0) + { + unsigned HOST_WIDE_INT ioff + = TREE_INT_CST_LOW (TREE_OPERAND (t, 1)); + unsigned HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT; + align = MIN (aoff, align); + } } else /* ??? This isn't fully correct, we can't set the alignment from the type in all cases. */ align = MAX (align, TYPE_ALIGN (type)); - - if (!integer_zerop (TREE_OPERAND (t, 1)) && aoff < align) - align = aoff; } else if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF) |