]> git.ipfire.org Git - thirdparty/gcc.git/commit
builtins: Force SAVE_EXPR for __builtin_{add,sub,mul}_overflow [PR108789]
authorJakub Jelinek <jakub@redhat.com>
Tue, 4 Jun 2024 10:28:01 +0000 (12:28 +0200)
committerJakub Jelinek <jakub@redhat.com>
Thu, 20 Jun 2024 13:07:42 +0000 (15:07 +0200)
commit2922060a7fe04397df1ca69dd1f4de1edf8d2282
tree82dbf22f27c731aefcc5b3fe937c6e27cc34affe
parent82bb4ee090342f2b787661420f701f2e0bf6624a
builtins: Force SAVE_EXPR for __builtin_{add,sub,mul}_overflow [PR108789]

The following testcase is miscompiled, because we use save_expr
on the .{ADD,SUB,MUL}_OVERFLOW call we are creating, but if the first
two operands are not INTEGER_CSTs (in that case we just fold it right away)
but are TREE_READONLY/!TREE_SIDE_EFFECTS, save_expr doesn't actually
create a SAVE_EXPR at all and so we lower it to
*arg2 = REALPART_EXPR (.ADD_OVERFLOW (arg0, arg1)), \
IMAGPART_EXPR (.ADD_OVERFLOW (arg0, arg1))
which evaluates the ifn twice and just hope it will be CSEd back.
As *arg2 aliases *arg0, that is not the case.
The builtins are really never const/pure as they store into what
the third arguments points to, so after handling the INTEGER_CST+INTEGER_CST
case, I think we should just always use SAVE_EXPR.  Just building SAVE_EXPR
by hand and setting TREE_SIDE_EFFECTS on it doesn't work, because
c_fully_fold optimizes it away again, so the following patch marks the
ifn calls as TREE_SIDE_EFFECTS (but doesn't do it for the
__builtin_{add,sub,mul}_overflow_p case which were designed for use
especially in constant expressions and don't really evaluate the
realpart side, so we don't really need a SAVE_EXPR in that case).

2024-06-04  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/108789
* builtins.c (fold_builtin_arith_overflow): For ovf_only,
don't call save_expr and don't build REALPART_EXPR, otherwise
set TREE_SIDE_EFFECTS on call before calling save_expr.

* gcc.c-torture/execute/pr108789.c: New test.

(cherry picked from commit b8e28381cb5c0cddfe5201faf799d8b27f5d7d6c)
gcc/builtins.c
gcc/testsuite/gcc.c-torture/execute/pr108789.c [new file with mode: 0644]