https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104140

Roger Sayle <roger at nextmovesoftware dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2022-01-20
           Assignee|unassigned at gcc dot gnu.org      |roger at 
nextmovesoftware dot com

--- Comment #1 from Roger Sayle <roger at nextmovesoftware dot com> ---
Mine (perhaps?).  To quote the review from my HIGHPART_MULT_EXPR patch:
>+  if (optype != TREE_TYPE (mop2)
>
> I think mop1 and mop2 have to be compatible types (the tree-cfg.c
> GIMPLE verification only tests for same precision it seems but tree.def
> says they are of type T1).  That said, I think optype != TREE_TYPE (mop2)
> is superfluous and too conservative at it.

It turns out that restoring this clause from the original patch submission
resolves this ICE on a cross-compiler to riscv-unknown-linux-gnu.

diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 1b6a57b..89a26dd 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -4600,7 +4600,8 @@ convert_mult_to_highpart (gassign *stmt,
gimple_stmt_itera
   bool unsignedp = TYPE_UNSIGNED (optype);
   unsigned int prec = TYPE_PRECISION (optype);

-  if (unsignedp != TYPE_UNSIGNED (mtype)
+  if (optype != TREE_TYPE (mop2)
+      || unsignedp != TYPE_UNSIGNED (mtype)
       || TYPE_PRECISION (mtype) != 2 * prec)
     return false;

It's odd that I'm unable to reproduce a similar failure on x86_64.
Perhaps the above paranoid fix isn't the correct solution at all, as
before/with it, I'm seeing:

void g ()
{
  int x.0_2;
  unsigned int v.1_4;
  long long int _6;
  long long int _7;
  unsigned int _8;

  <bb 2> [local count: 1073741824]:
  x.0_2 = x;
  v.1_4 = v;
  _6 = x.0_2 w* v.1_4;
  _7 = _6 >> 32;
  _8 = (unsigned int) _7;
  u = _8;
  return;

}

Note the differing operand types to the widening multiplication.  Perhaps the
upstream widening multiplication perception is the true source of the problem,
and just not being caught by verify_gimple like MULT_HIGHPART_EXPR is.

More generally, "defensive programming", i.e. the use of seemingly superfluous
tests that confirm assumed invariants isn't always a bad thing (in software
as complex as GCC).

Reply via email to