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 :/

Reply via email to