Hi! The following testcase ICEs, because store_expr is not prepared to handle VCE-like assignments (while store_field can handle that). We already had same mode check for the store_expr when size covers the whole complex to_rtx, this patch adds a similar check when storing just one half of it (first or second). Richard Sandiford recently added gcc_checking_assert (COMPLEX_MODE_P (to_mode)); so the patch also removes a now dead && COMPLEX_MODE_P (GET_MODE (to_rtx)) check, and uses the to_mode temporary to simplify the code.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/8.2? 2018-06-15 Jakub Jelinek <ja...@redhat.com> PR middle-end/85878 * expr.c (expand_assignment): Remove now redundant COMPLEX_MODE_P check from first store_expr, use to_mode instead of GET_MODE (to_rtx). Only call store_expr for halves if the mode is the same. * gfortran.fortran-torture/compile/pr85878.f90: New test. --- gcc/expr.c.jj 2018-06-13 10:05:30.000000000 +0200 +++ gcc/expr.c 2018-06-15 16:29:34.904387548 +0200 @@ -5150,12 +5150,12 @@ expand_assignment (tree to, tree from, b gcc_checking_assert (COMPLEX_MODE_P (to_mode)); poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode); unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode); - if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE (to_rtx) - && COMPLEX_MODE_P (GET_MODE (to_rtx)) + if (TYPE_MODE (TREE_TYPE (from)) == to_mode && known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize)) result = store_expr (from, to_rtx, false, nontemporal, reversep); - else if (known_eq (bitsize, inner_bitsize) + else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode) + && known_eq (bitsize, inner_bitsize) && (known_eq (bitpos, 0) || known_eq (bitpos, inner_bitsize))) result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)), --- gcc/testsuite/gfortran.fortran-torture/compile/pr85878.f90.jj 2018-06-15 16:50:53.825639713 +0200 +++ gcc/testsuite/gfortran.fortran-torture/compile/pr85878.f90 2018-06-15 16:49:20.483548544 +0200 @@ -0,0 +1,8 @@ +! PR middle-end/85878 + +program pr85878 + real :: a + complex :: c = (2.0, 3.0) + print *, c + print *, transfer (a, c) +end Jakub