From 0f3f0e4e97a0d564f87cbd8a7dfdaf9be3665fe3 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 1 Jan 2018 00:52:01 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/expr.c | 17 +++++++++++++++-- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/opt/pr83608.C | 28 ++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr83608.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98073e8f942..a0c9bf86bb5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2018-01-01 Jakub Jelinek + 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. + PR middle-end/83609 * expr.c (expand_assignment): Fix up a typo in simplify_gen_subreg last argument when extracting from CONCAT. If either from_real or diff --git a/gcc/expr.c b/gcc/expr.c index 0a735762e51..bae853c00cc 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 59c9543de5f..8b5c062e1f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-01-01 Jakub Jelinek + PR middle-end/83608 + * g++.dg/opt/pr83608.C: New test. + PR middle-end/83609 * gcc.dg/pr83609.c: New test. * g++.dg/opt/pr83609.C: New test. diff --git a/gcc/testsuite/g++.dg/opt/pr83608.C b/gcc/testsuite/g++.dg/opt/pr83608.C new file mode 100644 index 00000000000..555e5877e75 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr83608.C @@ -0,0 +1,28 @@ +// PR middle-end/83608 +// { dg-do compile } +// { dg-options "-O2" } + +template class B; +template <> struct B +{ + float foo () { return __real__ b; } + _Complex double b; +}; + +void bar (int); + +template +void +baz () +{ + B h; + T *a = (T *) &h; + a[0] = a[1] = 6; + h.foo () ? void () : bar (7); +} + +int +main () +{ + baz (); +} -- 2.30.2