mirror of git://gcc.gnu.org/git/gcc.git
gimplify: Fix up side-effect handling in 2nd __builtin_c[lt]zg argument [PR122188]
The patch from yesterday made me think about side-effects in the second argument of __builtin_c[lt]zg. When we change __builtin_c[lt]zg (x, y) when y is not INTEGER_CST into x ? __builtin_c[lt]zg (x) : y with evaluating x only once, we omit the side-effects in y unless x is not 0. That looks undesirable, we should evaluate side-effects in y unconditionally. 2025-10-09 Jakub Jelinek <jakub@redhat.com> PR c/122188 * c-gimplify.cc (c_gimplify_expr): Also gimplify the second operand before the COND_EXPR and use in COND_EXPR result of gimplification. * gcc.dg/torture/pr122188.c: New test.
This commit is contained in:
parent
0558c6028e
commit
579de8f529
|
@ -1040,6 +1040,10 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
|
|||
if (gimplify_expr (&a, pre_p, post_p, is_gimple_val, fb_rvalue)
|
||||
== GS_ERROR)
|
||||
return GS_ERROR;
|
||||
tree b = CALL_EXPR_ARG (*expr_p, 1);
|
||||
if (gimplify_expr (&b, 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,
|
||||
|
@ -1047,7 +1051,7 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
|
|||
build2_loc (EXPR_LOCATION (*expr_p),
|
||||
NE_EXPR, boolean_type_node, a,
|
||||
build_zero_cst (TREE_TYPE (a))),
|
||||
c, CALL_EXPR_ARG (*expr_p, 1));
|
||||
c, b);
|
||||
return GS_OK;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* PR c/122188 */
|
||||
/* { dg-do run } */
|
||||
|
||||
int
|
||||
foo (unsigned x, int y)
|
||||
{
|
||||
unsigned a = x;
|
||||
int b = y;
|
||||
int ret = __builtin_ctzg (x++, y++);
|
||||
if (x != a + 1 || y != b + 1)
|
||||
__builtin_abort ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
bar (unsigned x, int y)
|
||||
{
|
||||
unsigned a = x;
|
||||
int b = y;
|
||||
int ret = __builtin_clzg (x++, y++);
|
||||
if (x != a + 1 || y != b + 1)
|
||||
__builtin_abort ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (foo (0, 42) != 42 || foo (1, 5) != 0 || foo (4, 17) != 2)
|
||||
__builtin_abort ();
|
||||
if (bar (0, 42) != 42 || bar (~0U, 5) != 0 || bar (~0U >> 4, 17) != 4)
|
||||
__builtin_abort ();
|
||||
}
|
Loading…
Reference in New Issue