diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-01-01 00:52:01 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-01-01 00:52:01 +0100 |
commit | 0f3f0e4e97a0d564f87cbd8a7dfdaf9be3665fe3 (patch) | |
tree | dbf0da98cfbbbcc90510cf65785816fef4763aaf /gcc/expr.c | |
parent | c1329fc84c8f7ee892070cb4aa514c4dbab70625 (diff) | |
download | gcc-0f3f0e4e97a0d564f87cbd8a7dfdaf9be3665fe3.zip gcc-0f3f0e4e97a0d564f87cbd8a7dfdaf9be3665fe3.tar.gz gcc-0f3f0e4e97a0d564f87cbd8a7dfdaf9be3665fe3.tar.bz2 |
re PR rtl-optimization/83608 (ICE in convert_move, at expr.c:229 in GIMPLE store merging pass)
PR middle-end/83608
* expr.c (store_expr_with_bounds): Use simplify_gen_subreg instead of
convert_modes if target mode has the right side, but different mode
class.
* g++.dg/opt/pr83608.C: New test.
From-SVN: r256053
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -5638,8 +5638,21 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p, if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode && TREE_CODE (exp) != ERROR_MARK && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp))) - temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)), - temp, TYPE_UNSIGNED (TREE_TYPE (exp))); + { + if (GET_MODE_CLASS (GET_MODE (target)) + != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp))) + && GET_MODE_BITSIZE (GET_MODE (target)) + == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))) + { + rtx t = simplify_gen_subreg (GET_MODE (target), temp, + TYPE_MODE (TREE_TYPE (exp)), 0); + if (t) + temp = t; + } + if (GET_MODE (temp) == VOIDmode) + temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)), + temp, TYPE_UNSIGNED (TREE_TYPE (exp))); + } /* If value was not generated in the target, store it there. Convert the value to TARGET's type first if necessary and emit the |