From 78fbe731a8822e819c4ca0e6d6f777c7a2f36bad Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Wed, 2 Sep 2020 14:26:15 +0800 Subject: 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. --- gcc/expr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/expr.c') 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)) -- cgit v1.1 From b960a9c83a93b58a84a7a370002990810675ac5d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 22 Oct 2020 09:29:47 +0200 Subject: middle-end/97521 - fix VECTOR_CST expansion This fixes expansion of VECTOR_BOOLEAN_TYPE_P VECTOR_CSTs which when using an integer mode are not always "mask-mode" but may be using an integer mode when there's no supported vector mode. The patch makes sure to only go the mask-mode expansion if the elements do not line up to cover the full integer mode (when they do and the mode was an actual mask-mode there's no actual difference in both expansions). 2020-10-22 Richard Biener PR middle-end/97521 * expr.c (expand_expr_real_1): Be more careful when expanding a VECTOR_BOOLEAN_TYPE_P VECTOR_CSTs. * gcc.target/i386/pr97521.c: New testcase. --- gcc/expr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 9d951e8..d87bda7 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10356,7 +10356,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, scalar_int_mode int_mode; if (is_int_mode (mode, &int_mode)) { - if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp))) + if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)) + && maybe_ne (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (exp))) + * TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp)), + GET_MODE_PRECISION (int_mode))) return const_scalar_mask_from_tree (int_mode, exp); else { -- cgit v1.1 From 7cda498920dbf244e9e06fdb2fc710a118a8c033 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 23 Oct 2020 08:21:39 +0200 Subject: Revert "middle-end/97521 - fix VECTOR_CST expansion" 2020-10-23 Richard Biener PR middle-end/97521 * expr.c (expand_expr_real_1): Revert last change. * gcc.target/i386/pr97521.c: Remove. This reverts commit b960a9c83a93b58a84a7a370002990810675ac5d. --- gcc/expr.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index d87bda7..9d951e8 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10356,10 +10356,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, scalar_int_mode int_mode; if (is_int_mode (mode, &int_mode)) { - if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)) - && maybe_ne (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (exp))) - * TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp)), - GET_MODE_PRECISION (int_mode))) + if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp))) return const_scalar_mask_from_tree (int_mode, exp); else { -- cgit v1.1 From 605c2a393d3a2db86454a70fd7c9467db434060c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 23 Oct 2020 08:40:15 +0200 Subject: middle-end/97521 - always use single-bit bools in mask vector types This makes us always use a single-bit boolean type component type for integer mode mask VECTOR_BOOLEAN_TYPE_P to match the RTL and target representation. This aovids the need for magic translation and the inconsistencies from the translation requirement now that we expose temporaries of those types on the GIMPLE level. 2020-10-23 Richard Biener PR middle-end/97521 * expr.c (const_scalar_mask_from_tree): Remove. (expand_expr_real_1): Always VIEW_CONVERT integer mode vector constants to an integer type. * tree.c (build_truth_vector_type_for_mode): Use a single-bit boolean component type for non-vector-mode mask_mode. * gcc.target/i386/pr97521.c: New testcase. --- gcc/expr.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 9d951e8..ae16f07 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -96,7 +96,6 @@ static void emit_single_push_insn (machine_mode, rtx, tree); static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx, profile_probability); static rtx const_vector_from_tree (tree); -static rtx const_scalar_mask_from_tree (scalar_int_mode, tree); static tree tree_expr_size (const_tree); static HOST_WIDE_INT int_expr_size (tree); static void convert_mode_scalar (rtx, rtx, int); @@ -10356,16 +10355,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, scalar_int_mode int_mode; if (is_int_mode (mode, &int_mode)) { - if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp))) - return const_scalar_mask_from_tree (int_mode, exp); - else - { - tree type_for_mode - = lang_hooks.types.type_for_mode (int_mode, 1); - if (type_for_mode) - tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, - type_for_mode, exp); - } + tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1); + if (type_for_mode) + tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, + type_for_mode, exp); } if (!tmp) { @@ -12739,30 +12732,6 @@ const_vector_mask_from_tree (tree exp) return builder.build (); } -/* EXP is a VECTOR_CST in which each element is either all-zeros or all-ones. - Return a constant scalar rtx of mode MODE in which bit X is set if element - X of EXP is nonzero. */ -static rtx -const_scalar_mask_from_tree (scalar_int_mode mode, tree exp) -{ - wide_int res = wi::zero (GET_MODE_PRECISION (mode)); - tree elt; - - /* The result has a fixed number of bits so the input must too. */ - unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant (); - for (unsigned int i = 0; i < nunits; ++i) - { - elt = VECTOR_CST_ELT (exp, i); - gcc_assert (TREE_CODE (elt) == INTEGER_CST); - if (integer_all_onesp (elt)) - res = wi::set_bit (res, i); - else - gcc_assert (integer_zerop (elt)); - } - - return immed_wide_int_const (res, mode); -} - /* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */ static rtx const_vector_from_tree (tree exp) -- cgit v1.1