diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-12-13 22:10:44 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-12-13 22:10:44 +0000 |
commit | 51426017f8fe0f18295ca467feba3fbb5aad3fa8 (patch) | |
tree | 2f686f2d4657aa570473986e7d0924794093c67b /gcc/expr.c | |
parent | 0cec14923830569b8727d461bcf64adaf965de83 (diff) | |
parent | c926fd82bbd336b317266d43b9fa67a83397b06b (diff) | |
download | gcc-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.c | 52 |
1 files changed, 41 insertions, 11 deletions
@@ -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, |