On Mon, 2 Feb 2026, Jakub Jelinek wrote:
> Hi!
>
> As the following testcase shows, I've missed a check that element type
> of lhs type of ovf1/ovf2 (.ADD_OVERFLOW/.SUB_OVERFLOW) matches type (there
> are some casts accepted on the way for the case of values in [0-1] range),
> so the following testcase got also matched as .SUBC and we get an ICE on
> type mismatch in there. The other .{ADD,SUB}_OVERFLOW cases already check
> even the result type, both
> if (gimple_call_internal_p (ovf, code == PLUS_EXPR
> ? IFN_ADD_OVERFLOW
> : IFN_SUB_OVERFLOW))
> ...
> ovf_lhs = gimple_call_lhs (ovf);
> tree ovf_lhs_type = TREE_TYPE (TREE_TYPE (ovf_lhs));
> ovf_arg1 = gimple_call_arg (ovf, 0);
> ovf_arg2 = gimple_call_arg (ovf, 1);
> /* In that case we need to punt if the types don't
> mismatch. */
> if (!types_compatible_p (type, ovf_lhs_type)
> || !types_compatible_p (type, TREE_TYPE
> (ovf_arg1))
> || !types_compatible_p (type,
> TREE_TYPE (ovf_arg2)))
> ovf_lhs = NULL_TREE;
> and
> gimple *ovf3
> = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im3), 0));
> if (gimple_call_internal_p (ovf3, ifn))
> {
> lhs = gimple_call_lhs (ovf3);
> arg1 = gimple_call_arg (ovf3, 0);
> arg2 = gimple_call_arg (ovf3, 1);
> if (types_compatible_p (type, TREE_TYPE (TREE_TYPE (lhs)))
> && types_compatible_p (type, TREE_TYPE (arg1))
> && types_compatible_p (type, TREE_TYPE (arg2)))
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Richard.
> 2026-02-02 Jakub Jelinek <[email protected]>
>
> PR tree-optimization/121104
> * tree-ssa-math-opts.cc (match_uaddc_usubc): Punt if
> lhs of ovf1 or ovf2 doesn't have element type compatible with type.
>
> * gcc.dg/pr121104.c: New test.
>
> --- gcc/tree-ssa-math-opts.cc.jj 2026-01-27 10:18:31.525823281 +0100
> +++ gcc/tree-ssa-math-opts.cc 2026-01-31 14:00:13.600764201 +0100
> @@ -5411,7 +5411,11 @@ match_uaddc_usubc (gimple_stmt_iterator
> TYPE_MODE (type)) == CODE_FOR_nothing
> || (rhs[2]
> && optab_handler (code == PLUS_EXPR ? uaddc5_optab : usubc5_optab,
> - TYPE_MODE (type)) == CODE_FOR_nothing))
> + TYPE_MODE (type)) == CODE_FOR_nothing)
> + || !types_compatible_p (type,
> + TREE_TYPE (TREE_TYPE (gimple_call_lhs (ovf1))))
> + || !types_compatible_p (type,
> + TREE_TYPE (TREE_TYPE (gimple_call_lhs (ovf2)))))
> return false;
> tree arg1, arg2, arg3 = NULL_TREE;
> gimple *re1 = NULL, *re2 = NULL;
> --- gcc/testsuite/gcc.dg/pr121104.c.jj 2026-01-31 14:07:39.051271803
> +0100
> +++ gcc/testsuite/gcc.dg/pr121104.c 2026-01-31 14:07:27.947458961 +0100
> @@ -0,0 +1,23 @@
> +/* PR tree-optimization/121104 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +static unsigned long
> +foo (unsigned long x, unsigned long y,
> + unsigned long z, unsigned long *w)
> +{
> + int r;
> + unsigned long a = __builtin_sub_overflow (x, y, &r);
> + unsigned long b = __builtin_sub_overflow (r, z, &r);
> + *w = a + b;
> + return r;
> +}
> +
> +unsigned long
> +bar (unsigned long *p, unsigned long *q)
> +{
> + unsigned long c;
> + p[0] = foo (p[0], q[0], 0, &c);
> + p[1] = foo (p[1], q[1], c, &c);
> + return c;
> +}
>
> Jakub
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)