Commit cab35794 by Richard Guenther Committed by Richard Biener

re PR middle-end/50716 (Segmentation fault caused by misaligned vector access)

2011-10-18  Richard Guenther  <rguenther@suse.de>

	PR middle-end/50716
	* expr.c (get_object_or_type_alignment): New function.
	(expand_assignment): Use it.
	(expand_expr_real_1): Likewise.

From-SVN: r180125
parent d17687f6
2011-10-18 Richard Guenther <rguenther@suse.de>
PR middle-end/50716
* expr.c (get_object_or_type_alignment): New function.
(expand_assignment): Use it.
(expand_expr_real_1): Likewise.
2011-10-18 Dodji Seketeli <dodji@redhat.com> 2011-10-18 Dodji Seketeli <dodji@redhat.com>
PR bootstrap/50760 PR bootstrap/50760
...@@ -4544,6 +4544,27 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart, ...@@ -4544,6 +4544,27 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
} }
} }
/* Return the alignment of the object EXP, also considering its type
when we do not know of explicit misalignment.
??? Note that, in the general case, the type of an expression is not kept
consistent with misalignment information by the front-end, for
example when taking the address of a member of a packed structure.
However, in most of the cases, expressions have the alignment of
their type, so we optimistically fall back to the alignment of the
type when we cannot compute a misalignment. */
static unsigned int
get_object_or_type_alignment (tree exp)
{
unsigned HOST_WIDE_INT misalign;
unsigned int align = get_object_alignment_1 (exp, &misalign);
if (misalign != 0)
align = (misalign & -misalign);
else
align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align);
return align;
}
/* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL /* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL
is true, try generating a nontemporal store. */ is true, try generating a nontemporal store. */
...@@ -4553,7 +4574,7 @@ expand_assignment (tree to, tree from, bool nontemporal) ...@@ -4553,7 +4574,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
rtx to_rtx = 0; rtx to_rtx = 0;
rtx result; rtx result;
enum machine_mode mode; enum machine_mode mode;
int align; unsigned int align;
enum insn_code icode; enum insn_code icode;
/* Don't crash if the lhs of the assignment was erroneous. */ /* Don't crash if the lhs of the assignment was erroneous. */
...@@ -4571,8 +4592,8 @@ expand_assignment (tree to, tree from, bool nontemporal) ...@@ -4571,8 +4592,8 @@ expand_assignment (tree to, tree from, bool nontemporal)
if ((TREE_CODE (to) == MEM_REF if ((TREE_CODE (to) == MEM_REF
|| TREE_CODE (to) == TARGET_MEM_REF) || TREE_CODE (to) == TARGET_MEM_REF)
&& mode != BLKmode && mode != BLKmode
&& ((align = MAX (TYPE_ALIGN (TREE_TYPE (to)), get_object_alignment (to))) && ((align = get_object_or_type_alignment (to))
< (signed) GET_MODE_ALIGNMENT (mode)) < GET_MODE_ALIGNMENT (mode))
&& ((icode = optab_handler (movmisalign_optab, mode)) && ((icode = optab_handler (movmisalign_optab, mode))
!= CODE_FOR_nothing)) != CODE_FOR_nothing))
{ {
...@@ -9241,7 +9262,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9241,7 +9262,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp)); addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
struct mem_address addr; struct mem_address addr;
enum insn_code icode; enum insn_code icode;
int align; unsigned int align;
get_address_description (exp, &addr); get_address_description (exp, &addr);
op0 = addr_for_mem_ref (&addr, as, true); op0 = addr_for_mem_ref (&addr, as, true);
...@@ -9249,9 +9270,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9249,9 +9270,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
temp = gen_rtx_MEM (mode, op0); temp = gen_rtx_MEM (mode, op0);
set_mem_attributes (temp, exp, 0); set_mem_attributes (temp, exp, 0);
set_mem_addr_space (temp, as); set_mem_addr_space (temp, as);
align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), get_object_alignment (exp)); align = get_object_or_type_alignment (exp);
if (mode != BLKmode if (mode != BLKmode
&& (unsigned) align < GET_MODE_ALIGNMENT (mode) && align < GET_MODE_ALIGNMENT (mode)
/* If the target does not have special handling for unaligned /* If the target does not have special handling for unaligned
loads of mode then it can use regular moves for them. */ loads of mode then it can use regular moves for them. */
&& ((icode = optab_handler (movmisalign_optab, mode)) && ((icode = optab_handler (movmisalign_optab, mode))
...@@ -9278,7 +9299,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9278,7 +9299,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
tree base = TREE_OPERAND (exp, 0); tree base = TREE_OPERAND (exp, 0);
gimple def_stmt; gimple def_stmt;
enum insn_code icode; enum insn_code icode;
int align; unsigned align;
/* Handle expansion of non-aliased memory with non-BLKmode. That /* Handle expansion of non-aliased memory with non-BLKmode. That
might end up in a register. */ might end up in a register. */
if (TREE_CODE (base) == ADDR_EXPR) if (TREE_CODE (base) == ADDR_EXPR)
...@@ -9329,7 +9350,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9329,7 +9350,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
gimple_assign_rhs1 (def_stmt), mask); gimple_assign_rhs1 (def_stmt), mask);
TREE_OPERAND (exp, 0) = base; TREE_OPERAND (exp, 0) = base;
} }
align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), get_object_alignment (exp)); align = get_object_or_type_alignment (exp);
op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM); op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address_addr_space (address_mode, op0, as); op0 = memory_address_addr_space (address_mode, op0, as);
if (!integer_zerop (TREE_OPERAND (exp, 1))) if (!integer_zerop (TREE_OPERAND (exp, 1)))
...@@ -9345,7 +9366,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9345,7 +9366,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (TREE_THIS_VOLATILE (exp)) if (TREE_THIS_VOLATILE (exp))
MEM_VOLATILE_P (temp) = 1; MEM_VOLATILE_P (temp) = 1;
if (mode != BLKmode if (mode != BLKmode
&& (unsigned) align < GET_MODE_ALIGNMENT (mode) && align < GET_MODE_ALIGNMENT (mode)
/* If the target does not have special handling for unaligned /* If the target does not have special handling for unaligned
loads of mode then it can use regular moves for them. */ loads of mode then it can use regular moves for them. */
&& ((icode = optab_handler (movmisalign_optab, mode)) && ((icode = optab_handler (movmisalign_optab, mode))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment