summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2019-09-03 14:37:41 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2019-09-03 14:37:41 +0000
commit934392185369af22fee845e4edd92c420b8c248b (patch)
treee13e59cecc7a4efdcf0a55187dcac5ea3900e569 /gcc/expr.c
parentc6c2d1bc9bc3eb3606af6a198e74170bd906e199 (diff)
re PR middle-end/91603 (Unaligned access in expand_assignment)
2019-09-03 Bernd Edlinger <bernd.edlinger@hotmail.de> PR middle-end/91603 PR middle-end/91612 PR middle-end/91613 * expr.c (expand_expr_real_1): Handle unaligned decl_rtl and SSA_NAME referring to CONSTANT_P correctly. testsuite: 2019-09-03 Bernd Edlinger <bernd.edlinger@hotmail.de> PR middle-end/91603 * testsuite/gcc.target/arm/pr91603.c: New test. From-SVN: r275342
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 3c3f15a0f77..0c96551ec2c 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10062,6 +10062,42 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
{
if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0)))
mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
+ }
+ else if (MEM_P (decl_rtl))
+ temp = decl_rtl;
+
+ if (temp != 0)
+ {
+ if (MEM_P (temp)
+ && modifier != EXPAND_WRITE
+ && modifier != EXPAND_MEMORY
+ && modifier != EXPAND_INITIALIZER
+ && modifier != EXPAND_CONST_ADDRESS
+ && modifier != EXPAND_SUM
+ && !inner_reference_p
+ && mode != BLKmode
+ && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
+ {
+ enum insn_code icode;
+
+ if ((icode = optab_handler (movmisalign_optab, mode))
+ != CODE_FOR_nothing)
+ {
+ class expand_operand ops[2];
+
+ /* We've already validated the memory, and we're creating a
+ new pseudo destination. The predicates really can't fail,
+ nor can the generator. */
+ create_output_operand (&ops[0], NULL_RTX, mode);
+ create_fixed_operand (&ops[1], temp);
+ expand_insn (icode, 2, ops);
+ temp = ops[0].value;
+ }
+ else if (targetm.slow_unaligned_access (mode, MEM_ALIGN (temp)))
+ temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
+ 0, unsignedp, NULL_RTX,
+ mode, mode, false, NULL);
+ }
return temp;
}
@@ -10974,9 +11010,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
op0 = copy_rtx (op0);
/* Don't set memory attributes if the base expression is
- SSA_NAME that got expanded as a MEM. In that case, we should
- just honor its original memory attributes. */
- if (TREE_CODE (tem) != SSA_NAME || !MEM_P (orig_op0))
+ SSA_NAME that got expanded as a MEM or a CONSTANT. In that case,
+ we should just honor its original memory attributes. */
+ if (!(TREE_CODE (tem) == SSA_NAME
+ && (MEM_P (orig_op0) || CONSTANT_P (orig_op0))))
set_mem_attributes (op0, exp, 0);
if (REG_P (XEXP (op0, 0)))