https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84101
--- Comment #23 from Richard Biener <rguenth at gcc dot gnu.org> --- Fallout is: FAIL: gcc.dg/pr85195.c (internal compiler error) where we handle V1TI = {_2} with _2 = (__int128) int_1; this way and end up calling convert_move from SImode to V1TImode (instead of TImode). Looks like a pre-existing bug to me, not quickly sure where to fix. FAIL: c-c++-common/torture/builtin-convertvector-1.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (internal compiler error) Similar issue, we end up in expand_fix to TImode from V4SFmode. The generic tree code expanders in expand_expr_real_2 simply pass down target (here to expand_fix). Not sure what constraints we have on target for expand_expr, the docs just say "The value may be stored in TARGET if TARGET is nonzero. TARGET is just a suggestion; callers must assume that the rtx returned may not be the same as TARGET." and further down "Note that TARGET may have neither TMODE nor MODE. In that case, it probably will not be used." So it looks to me these high-level expanders need to be more careful in what they pass to functions like expand_fix or convert_move. FAIL: gfortran.dg/allocatable_function_8.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (internal compiler error) FAIL: gfortran.fortran-torture/execute/entry_4.f90, -O1 (internal compiler error) Same issue for expand_float. That's all issues in the testsuite but with those it may look a little too risky for GCC 9. At least it would solve the DImode pair issue which might happen quite often in practice :/ The following guards the above three cases: @@ -8543,7 +8560,9 @@ expand_expr_real_2 (sepops ops, rtx targ op0 = gen_rtx_fmt_e (TYPE_UNSIGNED (TREE_TYPE (treeop0)) ? ZERO_EXTEND : SIGN_EXTEND, mode, op0); - else if (target == 0) + else if (target == 0 + || (VECTOR_MODE_P (GET_MODE (target)) + != VECTOR_MODE_P (GET_MODE (op0)))) op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0))); @@ -9019,14 +9038,20 @@ expand_expr_real_2 (sepops ops, rtx targ case FIX_TRUNC_EXPR: op0 = expand_normal (treeop0); - if (target == 0 || modifier == EXPAND_STACK_PARM) + if (target == 0 || modifier == EXPAND_STACK_PARM + || (target + && (VECTOR_MODE_P (GET_MODE (target)) + != VECTOR_MODE_P (GET_MODE (op0))))) target = gen_reg_rtx (mode); expand_fix (target, op0, unsignedp); return target; case FLOAT_EXPR: op0 = expand_normal (treeop0); - if (target == 0 || modifier == EXPAND_STACK_PARM) + if (target == 0 || modifier == EXPAND_STACK_PARM + || (target + && (VECTOR_MODE_P (GET_MODE (target)) + != VECTOR_MODE_P (GET_MODE (op0))))) target = gen_reg_rtx (mode); /* expand_float can't figure out what to do if FROM has VOIDmode. So give it the correct mode. With -O, cse will optimize this. */ but then the testcases run into other similar issues all through RTL expansion :/