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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/expr.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr83608.C | 28 |
4 files changed, 51 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98073e8..a0c9bf8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2018-01-01 Jakub Jelinek <jakub@redhat.com> + 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 @@ -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 59c9543..8b5c062 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-01-01 Jakub Jelinek <jakub@redhat.com> + 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 0000000..555e587 --- /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 <typename> class B; +template <> struct B<float> +{ + float foo () { return __real__ b; } + _Complex double b; +}; + +void bar (int); + +template <class T> +void +baz () +{ + B<T> h; + T *a = (T *) &h; + a[0] = a[1] = 6; + h.foo () ? void () : bar (7); +} + +int +main () +{ + baz<float> (); +} |