On Wed, 8 Oct 2025, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase ICEs during gimplification.
> The problem is that save_expr sometimes doesn't create a SAVE_EXPR but
> returns the original complex tree (COND_EXPR) and the code then uses that
> tree in 2 different spots without unsharing.  As this is done during
> gimplification it wasn't unshared when whole body is unshared and because
> gimplification is destructive, the first time we gimplify it we destruct it
> and second time we try to gimplify it we ICE on it.
> Now, we could replace one a use with unshare_expr (a), but because this
> is a gimplification hook, I think easier than trying to create a save_expr
> is just gimplify the argument, then we know it is is_gimple_val and so
> something without side-effects and can safely use it twice.  That argument
> would be the first thing to gimplify after return GS_OK anyway, so it
> doesn't change argument sequencing etc.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and
> later backports?

LGTM.

Richard.

> 2025-10-08  Jakub Jelinek  <[email protected]>
> 
>       PR c/122188
>       * c-gimplify.cc (c_gimplify_expr): Gimplify CALL_EXPR_ARG (*expr_p, 0)
>       instead of calling save_expr on it.
> 
>       * c-c++-common/pr122188.c: New test.
> 
> --- gcc/c-family/c-gimplify.cc.jj     2025-08-15 17:41:34.401721395 +0200
> +++ gcc/c-family/c-gimplify.cc        2025-10-07 18:24:14.611565348 +0200
> @@ -1036,7 +1036,10 @@ c_gimplify_expr (tree *expr_p, gimple_se
>           && call_expr_nargs (*expr_p) == 2
>           && TREE_CODE (CALL_EXPR_ARG (*expr_p, 1)) != INTEGER_CST)
>         {
> -         tree a = save_expr (CALL_EXPR_ARG (*expr_p, 0));
> +         tree a = CALL_EXPR_ARG (*expr_p, 0);
> +         if (gimplify_expr (&a, pre_p, post_p, is_gimple_val, fb_rvalue)
> +             == GS_ERROR)
> +           return GS_ERROR;
>           tree c = build_call_expr_loc (EXPR_LOCATION (*expr_p),
>                                         fndecl, 1, a);
>           *expr_p = build3_loc (EXPR_LOCATION (*expr_p), COND_EXPR,
> --- gcc/testsuite/c-c++-common/pr122188.c.jj  2025-10-07 18:27:53.928516188 
> +0200
> +++ gcc/testsuite/c-c++-common/pr122188.c     2025-10-07 18:27:37.355746617 
> +0200
> @@ -0,0 +1,15 @@
> +/* PR c/122188 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +int
> +foo (const unsigned x, int y)
> +{
> +  return __builtin_ctzg (x ? x : 4081577U, y);
> +}
> +
> +int
> +bar (const unsigned x, int y)
> +{
> +  return __builtin_clzg (x ? x : 4081577U, y);
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to