aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-12-13 22:10:44 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-12-13 22:10:44 +0000
commit51426017f8fe0f18295ca467feba3fbb5aad3fa8 (patch)
tree2f686f2d4657aa570473986e7d0924794093c67b /gcc/expr.c
parent0cec14923830569b8727d461bcf64adaf965de83 (diff)
parentc926fd82bbd336b317266d43b9fa67a83397b06b (diff)
downloadgcc-51426017f8fe0f18295ca467feba3fbb5aad3fa8.zip
gcc-51426017f8fe0f18295ca467feba3fbb5aad3fa8.tar.gz
gcc-51426017f8fe0f18295ca467feba3fbb5aad3fa8.tar.bz2
Merge from trunk revision 279830.
From-SVN: r279387
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 476c686..20aa939 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -250,6 +250,31 @@ convert_move (rtx to, rtx from, int unsignedp)
if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
{
+ if (GET_MODE_UNIT_PRECISION (to_mode)
+ > GET_MODE_UNIT_PRECISION (from_mode))
+ {
+ optab op = unsignedp ? zext_optab : sext_optab;
+ insn_code icode = convert_optab_handler (op, to_mode, from_mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ emit_unop_insn (icode, to, from,
+ unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
+ return;
+ }
+ }
+
+ if (GET_MODE_UNIT_PRECISION (to_mode)
+ < GET_MODE_UNIT_PRECISION (from_mode))
+ {
+ insn_code icode = convert_optab_handler (trunc_optab,
+ to_mode, from_mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ emit_unop_insn (icode, to, from, TRUNCATE);
+ return;
+ }
+ }
+
gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
GET_MODE_BITSIZE (to_mode)));
@@ -3571,11 +3596,13 @@ emit_move_complex (machine_mode mode, rtx x, rtx y)
rtx_insn *ret;
/* For memory to memory moves, optimal behavior can be had with the
- existing block move logic. */
+ existing block move logic. But use normal expansion if optimizing
+ for size. */
if (MEM_P (x) && MEM_P (y))
{
emit_block_move (x, y, gen_int_mode (GET_MODE_SIZE (mode), Pmode),
- BLOCK_OP_NO_LIBCALL);
+ (optimize_insn_for_speed_p()
+ ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
return get_last_insn ();
}
@@ -5258,13 +5285,16 @@ expand_assignment (tree to, tree from, bool nontemporal)
}
else
{
+ machine_mode from_mode
+ = GET_MODE (result) == VOIDmode
+ ? TYPE_MODE (TREE_TYPE (from))
+ : GET_MODE (result);
rtx from_rtx;
if (MEM_P (result))
from_rtx = change_address (result, to_mode, NULL_RTX);
else
from_rtx
- = simplify_gen_subreg (to_mode, result,
- TYPE_MODE (TREE_TYPE (from)), 0);
+ = simplify_gen_subreg (to_mode, result, from_mode, 0);
if (from_rtx)
{
emit_move_insn (XEXP (to_rtx, 0),
@@ -5276,12 +5306,9 @@ expand_assignment (tree to, tree from, bool nontemporal)
{
to_mode = GET_MODE_INNER (to_mode);
rtx from_real
- = simplify_gen_subreg (to_mode, result,
- TYPE_MODE (TREE_TYPE (from)),
- 0);
+ = simplify_gen_subreg (to_mode, result, from_mode, 0);
rtx from_imag
- = simplify_gen_subreg (to_mode, result,
- TYPE_MODE (TREE_TYPE (from)),
+ = simplify_gen_subreg (to_mode, result, from_mode,
GET_MODE_SIZE (to_mode));
if (!from_real || !from_imag)
goto concat_store_slow;
@@ -6809,6 +6836,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
&& n_elts.is_constant (&const_n_elts))
{
machine_mode emode = eltmode;
+ bool vector_typed_elts_p = false;
if (CONSTRUCTOR_NELTS (exp)
&& (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
@@ -6819,13 +6847,14 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
* TYPE_VECTOR_SUBPARTS (etype),
n_elts));
emode = TYPE_MODE (etype);
+ vector_typed_elts_p = true;
}
icode = convert_optab_handler (vec_init_optab, mode, emode);
if (icode != CODE_FOR_nothing)
{
unsigned int n = const_n_elts;
- if (emode != eltmode)
+ if (vector_typed_elts_p)
{
n = CONSTRUCTOR_NELTS (exp);
vec_vec_init_p = true;
@@ -12552,7 +12581,8 @@ build_personality_function (const char *lang)
name = ACONCAT (("__", lang, "_personality", unwind_and_version, NULL));
- type = build_function_type_list (integer_type_node, integer_type_node,
+ type = build_function_type_list (unsigned_type_node,
+ integer_type_node, integer_type_node,
long_long_unsigned_type_node,
ptr_type_node, ptr_type_node, NULL_TREE);
decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,