aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2020-09-02 14:26:15 +0800
committerKito Cheng <kito.cheng@sifive.com>2020-10-14 11:47:33 +0800
commit78fbe731a8822e819c4ca0e6d6f777c7a2f36bad (patch)
treeb579eab21ff3ed2c539751a409949bbacca72bec /gcc/expr.c
parent72b38338228b3e90879828c0bb059603f683d98b (diff)
downloadgcc-78fbe731a8822e819c4ca0e6d6f777c7a2f36bad.zip
gcc-78fbe731a8822e819c4ca0e6d6f777c7a2f36bad.tar.gz
gcc-78fbe731a8822e819c4ca0e6d6f777c7a2f36bad.tar.bz2
PR target/96759 - Handle global variable assignment from misaligned structure/PARALLEL return values.
In g:70cdb21e579191fe9f0f1d45e328908e59c0179e, DECL/global variable has handled misaligned stores, but it didn't handle PARALLEL values, and I refer the other part of this function, I found the PARALLEL need handled by emit_group_* functions, so I add a check, and using emit_group_store if storing a PARALLEL value, also checked this change didn't break the testcase(gcc.target/arm/unaligned-argument-3.c) added by the orginal changes. For riscv64 target, struct S {int a; double b;} will pack into a parallel value to return and it has TImode when misaligned access is supported, however TImode required 16-byte align, but it only 8-byte align, so it go to the misaligned stores handling, then it will try to generate move instruction from a PARALLEL value. Tested on following target without introduced new reguression: - riscv32/riscv64 elf - x86_64-linux - arm-eabi v2 changes: - Use maybe_emit_group_store instead of emit_group_store. - Remove push_temp_slots/pop_temp_slots, emit_group_store only require stack temp slot when dst is CONCAT or PARALLEL, however maybe_emit_group_store will always use REG for dst if needed. gcc/ChangeLog: PR target/96759 * expr.c (expand_assignment): Handle misaligned stores with PARALLEL value. gcc/testsuite/ChangeLog: PR target/96759 * g++.target/riscv/pr96759.C: New. * gcc.target/riscv/pr96759.c: New.
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 1c79518..9d951e8 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5168,6 +5168,8 @@ expand_assignment (tree to, tree from, bool nontemporal)
rtx reg, mem;
reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ /* Handle PARALLEL. */
+ reg = maybe_emit_group_store (reg, TREE_TYPE (from));
reg = force_not_mem (reg);
mem = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))