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).