diff options
author | Bernd Edlinger <bernd.edlinger@hotmail.de> | 2019-09-03 14:37:41 +0000 |
---|---|---|
committer | Bernd Edlinger <edlinger@gcc.gnu.org> | 2019-09-03 14:37:41 +0000 |
commit | 934392185369af22fee845e4edd92c420b8c248b (patch) | |
tree | e13e59cecc7a4efdcf0a55187dcac5ea3900e569 /gcc/expr.c | |
parent | c6c2d1bc9bc3eb3606af6a198e74170bd906e199 (diff) | |
download | gcc-934392185369af22fee845e4edd92c420b8c248b.zip gcc-934392185369af22fee845e4edd92c420b8c248b.tar.gz gcc-934392185369af22fee845e4edd92c420b8c248b.tar.bz2 |
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.c | 43 |
1 files changed, 40 insertions, 3 deletions
@@ -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))) |