[PATCH] expand: Fix up IFN_ATOMIC_{BIT*,*CMP_0} expansion [PR105951]
Jakub Jelinek
jakub@redhat.com
Wed Jun 15 09:16:25 GMT 2022
On Wed, Jun 15, 2022 at 10:26:39AM +0200, Richard Biener wrote:
> Ah, that might be a nice way to simplify the fallback indeed.
>
> > > The back-and-forth is a big ugly IMHO and it would suggest we can
> > > always match to the IFN since we can fall back to the builtin
> > > call as expansion...?
> >
> > We can, but if the optab isn't implemented, it won't improve the code in any
> > way. So it would be wasted work.
>
> Indeed. So I guess OK with the suggested extra argument to the IFN.
Here is what I'll retest then:
2022-06-15 Jakub Jelinek <jakub@redhat.com>
PR middle-end/105951
* tree-ssa-ccp.cc (optimize_atomic_bit_test_and,
optimize_atomic_op_fetch_cmp_0): Remember gimple_call_fn (call)
as last argument to the internal functions.
* builtins.cc (expand_ifn_atomic_bit_test_and): Adjust for the
extra call argument to ifns. If expand_atomic_fetch_op fails for the
lhs == NULL_TREE case, fall through into the optab code with
gen_reg_rtx (mode) as target. If second expand_atomic_fetch_op
fails, construct a CALL_EXPR and expand that.
(expand_ifn_atomic_op_fetch_cmp_0): Adjust for the extra call argument
to ifns. If expand_atomic_fetch_op fails, construct a CALL_EXPR and
expand that.
* gcc.target/i386/pr105951-1.c: New test.
* gcc.target/i386/pr105951-2.c: New test.
--- gcc/tree-ssa-ccp.cc.jj 2022-05-23 10:59:06.200591718 +0200
+++ gcc/tree-ssa-ccp.cc 2022-06-15 10:51:43.956039519 +0200
@@ -3789,11 +3789,12 @@ optimize_atomic_bit_test_and (gimple_stm
tree new_lhs = make_ssa_name (TREE_TYPE (lhs));
tree flag = build_int_cst (TREE_TYPE (lhs), use_bool);
if (has_model_arg)
- g = gimple_build_call_internal (fn, 4, gimple_call_arg (call, 0),
- bit, flag, gimple_call_arg (call, 2));
+ g = gimple_build_call_internal (fn, 5, gimple_call_arg (call, 0),
+ bit, flag, gimple_call_arg (call, 2),
+ gimple_call_fn (call));
else
- g = gimple_build_call_internal (fn, 3, gimple_call_arg (call, 0),
- bit, flag);
+ g = gimple_build_call_internal (fn, 4, gimple_call_arg (call, 0),
+ bit, flag, gimple_call_fn (call));
gimple_call_set_lhs (g, new_lhs);
gimple_set_location (g, gimple_location (call));
gimple_move_vops (g, call);
@@ -4003,14 +4004,16 @@ optimize_atomic_op_fetch_cmp_0 (gimple_s
gimple *g;
tree flag = build_int_cst (TREE_TYPE (lhs), encoded);
if (has_model_arg)
- g = gimple_build_call_internal (fn, 4, flag,
+ g = gimple_build_call_internal (fn, 5, flag,
gimple_call_arg (call, 0),
gimple_call_arg (call, 1),
- gimple_call_arg (call, 2));
+ gimple_call_arg (call, 2),
+ gimple_call_fn (call));
else
- g = gimple_build_call_internal (fn, 3, flag,
+ g = gimple_build_call_internal (fn, 4, flag,
gimple_call_arg (call, 0),
- gimple_call_arg (call, 1));
+ gimple_call_arg (call, 1),
+ gimple_call_fn (call));
gimple_call_set_lhs (g, new_lhs);
gimple_set_location (g, gimple_location (call));
gimple_move_vops (g, call);
--- gcc/builtins.cc.jj 2022-06-15 10:43:34.442073272 +0200
+++ gcc/builtins.cc 2022-06-15 11:12:20.865321490 +0200
@@ -6224,7 +6224,7 @@ expand_ifn_atomic_bit_test_and (gcall *c
gcc_assert (flag_inline_atomics);
- if (gimple_call_num_args (call) == 4)
+ if (gimple_call_num_args (call) == 5)
model = get_memmodel (gimple_call_arg (call, 3));
rtx mem = get_builtin_sync_mem (ptr, mode);
@@ -6250,15 +6250,19 @@ expand_ifn_atomic_bit_test_and (gcall *c
if (lhs == NULL_TREE)
{
- val = expand_simple_binop (mode, ASHIFT, const1_rtx,
- val, NULL_RTX, true, OPTAB_DIRECT);
+ rtx val2 = expand_simple_binop (mode, ASHIFT, const1_rtx,
+ val, NULL_RTX, true, OPTAB_DIRECT);
if (code == AND)
- val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
- expand_atomic_fetch_op (const0_rtx, mem, val, code, model, false);
- return;
+ val2 = expand_simple_unop (mode, NOT, val2, NULL_RTX, true);
+ if (expand_atomic_fetch_op (const0_rtx, mem, val2, code, model, false))
+ return;
}
- rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ rtx target;
+ if (lhs)
+ target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ else
+ target = gen_reg_rtx (mode);
enum insn_code icode = direct_optab_handler (optab, mode);
gcc_assert (icode != CODE_FOR_nothing);
create_output_operand (&ops[0], target, mode);
@@ -6277,6 +6281,22 @@ expand_ifn_atomic_bit_test_and (gcall *c
val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
rtx result = expand_atomic_fetch_op (gen_reg_rtx (mode), mem, val,
code, model, false);
+ if (!result)
+ {
+ bool is_atomic = gimple_call_num_args (call) == 5;
+ tree tcall = gimple_call_arg (call, 3 + is_atomic);
+ tree fndecl = gimple_call_addr_fndecl (tcall);
+ tree type = TREE_TYPE (TREE_TYPE (fndecl));
+ tree exp = build_call_nary (type, tcall, 2 + is_atomic, ptr,
+ make_tree (type, val),
+ is_atomic
+ ? gimple_call_arg (call, 3)
+ : integer_zero_node);
+ result = expand_builtin (exp, gen_reg_rtx (mode), NULL_RTX,
+ mode, !lhs);
+ }
+ if (!lhs)
+ return;
if (integer_onep (flag))
{
result = expand_simple_binop (mode, ASHIFTRT, result, bitval,
@@ -6308,7 +6328,7 @@ expand_ifn_atomic_op_fetch_cmp_0 (gcall
gcc_assert (flag_inline_atomics);
- if (gimple_call_num_args (call) == 4)
+ if (gimple_call_num_args (call) == 5)
model = get_memmodel (gimple_call_arg (call, 3));
rtx mem = get_builtin_sync_mem (ptr, mode);
@@ -6369,6 +6389,21 @@ expand_ifn_atomic_op_fetch_cmp_0 (gcall
rtx result = expand_atomic_fetch_op (gen_reg_rtx (mode), mem, op,
code, model, true);
+ if (!result)
+ {
+ bool is_atomic = gimple_call_num_args (call) == 5;
+ tree tcall = gimple_call_arg (call, 3 + is_atomic);
+ tree fndecl = gimple_call_addr_fndecl (tcall);
+ tree type = TREE_TYPE (TREE_TYPE (fndecl));
+ tree exp = build_call_nary (type, tcall,
+ 2 + is_atomic, ptr, arg,
+ is_atomic
+ ? gimple_call_arg (call, 3)
+ : integer_zero_node);
+ result = expand_builtin (exp, gen_reg_rtx (mode), NULL_RTX,
+ mode, !lhs);
+ }
+
if (lhs)
{
result = emit_store_flag_force (target, comp, result, const0_rtx, mode,
--- gcc/testsuite/gcc.target/i386/pr105951-1.c.jj 2022-06-15 10:46:58.953970222 +0200
+++ gcc/testsuite/gcc.target/i386/pr105951-1.c 2022-06-15 10:46:58.953970222 +0200
@@ -0,0 +1,5 @@
+/* PR middle-end/105951 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -march=i386" } */
+
+#include "pr98737-2.c"
--- gcc/testsuite/gcc.target/i386/pr105951-2.c.jj 2022-06-15 10:46:58.953970222 +0200
+++ gcc/testsuite/gcc.target/i386/pr105951-2.c 2022-06-15 10:46:58.953970222 +0200
@@ -0,0 +1,5 @@
+/* PR middle-end/105951 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -march=i386" } */
+
+#include "pr98737-4.c"
Jakub
More information about the Gcc-patches
mailing list