From: Soumya AR <[email protected]> Add optab definitions for both legacy __sync and __atomic min/max operations.
The legacy sync optabs are not expected to be implemented by backends. They're included to minimize branching in expand_atomic_fetch_op_no_fallback in gcc/optabs.cc, since this function attempts to emit atomic operations by trying multiple optabs, including the legacy optabs. Rather than adding special clauses for the case where these optabs for the legacy builtins do not exist, we define optabs for all operations. The existing mechanisms should check whether these optabs are implemented or not. This means that although unlikely, if backends do implement these optabs, they should work correctly. Signed-off-by: Soumya AR <[email protected]> gcc/ChangeLog: * optabs.def (OPTAB_NC): Optab definitions for legacy sync min/max. (OPTAB_D): Optab definitions for atomic min/max. * optabs.cc (get_atomic_op_for_code): Fill in optab table for atomic min/max. --- gcc/optabs.cc | 36 ++++++++++++++++++++++++++++++++++++ gcc/optabs.def | 24 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 5c9450f6145..cacb15bb946 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -7584,6 +7584,42 @@ get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code) op->no_result = sync_nand_optab; op->reverse_code = UNKNOWN; break; + case SMIN: + op->mem_fetch_before = atomic_fetch_smin_optab; + op->mem_fetch_after = atomic_smin_fetch_optab; + op->mem_no_result = atomic_smin_optab; + op->fetch_before = sync_old_smin_optab; + op->fetch_after = sync_new_smin_optab; + op->no_result = sync_smin_optab; + op->reverse_code = UNKNOWN; + break; + case SMAX: + op->mem_fetch_before = atomic_fetch_smax_optab; + op->mem_fetch_after = atomic_smax_fetch_optab; + op->mem_no_result = atomic_smax_optab; + op->fetch_before = sync_old_smax_optab; + op->fetch_after = sync_new_smax_optab; + op->no_result = sync_smax_optab; + op->reverse_code = UNKNOWN; + break; + case UMIN: + op->mem_fetch_before = atomic_fetch_umin_optab; + op->mem_fetch_after = atomic_umin_fetch_optab; + op->mem_no_result = atomic_umin_optab; + op->fetch_before = sync_old_umin_optab; + op->fetch_after = sync_new_umin_optab; + op->no_result = sync_umin_optab; + op->reverse_code = UNKNOWN; + break; + case UMAX: + op->mem_fetch_before = atomic_fetch_umax_optab; + op->mem_fetch_after = atomic_umax_fetch_optab; + op->mem_no_result = atomic_umax_optab; + op->fetch_before = sync_old_umax_optab; + op->fetch_after = sync_new_umax_optab; + op->no_result = sync_umax_optab; + op->reverse_code = UNKNOWN; + break; default: gcc_unreachable (); } diff --git a/gcc/optabs.def b/gcc/optabs.def index 87a8b85da15..6b054b1f6b2 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -211,12 +211,20 @@ OPTAB_NC(sync_old_ior_optab, "sync_old_ior$I$a", UNKNOWN) OPTAB_NC(sync_old_and_optab, "sync_old_and$I$a", UNKNOWN) OPTAB_NC(sync_old_xor_optab, "sync_old_xor$I$a", UNKNOWN) OPTAB_NC(sync_old_nand_optab, "sync_old_nand$I$a", UNKNOWN) +OPTAB_NC(sync_old_smin_optab, "sync_old_smin$I$a", UNKNOWN) +OPTAB_NC(sync_old_smax_optab, "sync_old_smax$I$a", UNKNOWN) +OPTAB_NC(sync_old_umin_optab, "sync_old_umin$I$a", UNKNOWN) +OPTAB_NC(sync_old_umax_optab, "sync_old_umax$I$a", UNKNOWN) OPTAB_NC(sync_new_add_optab, "sync_new_add$I$a", UNKNOWN) OPTAB_NC(sync_new_sub_optab, "sync_new_sub$I$a", UNKNOWN) OPTAB_NC(sync_new_ior_optab, "sync_new_ior$I$a", UNKNOWN) OPTAB_NC(sync_new_and_optab, "sync_new_and$I$a", UNKNOWN) OPTAB_NC(sync_new_xor_optab, "sync_new_xor$I$a", UNKNOWN) OPTAB_NC(sync_new_nand_optab, "sync_new_nand$I$a", UNKNOWN) +OPTAB_NC(sync_new_smin_optab, "sync_new_smin$I$a", UNKNOWN) +OPTAB_NC(sync_new_smax_optab, "sync_new_smax$I$a", UNKNOWN) +OPTAB_NC(sync_new_umin_optab, "sync_new_umin$I$a", UNKNOWN) +OPTAB_NC(sync_new_umax_optab, "sync_new_umax$I$a", UNKNOWN) OPTAB_NC(sync_compare_and_swap_optab, "sync_compare_and_swap$I$a", UNKNOWN) OPTAB_NC(sync_lock_test_and_set_optab, "sync_lock_test_and_set$I$a", UNKNOWN) @@ -501,6 +509,10 @@ OPTAB_D (sync_and_optab, "sync_and$I$a") OPTAB_D (sync_ior_optab, "sync_ior$I$a") OPTAB_D (sync_lock_release_optab, "sync_lock_release$I$a") OPTAB_D (sync_nand_optab, "sync_nand$I$a") +OPTAB_D (sync_smin_optab, "sync_smin$I$a") +OPTAB_D (sync_smax_optab, "sync_smax$I$a") +OPTAB_D (sync_umin_optab, "sync_umin$I$a") +OPTAB_D (sync_umax_optab, "sync_umax$I$a") OPTAB_D (sync_sub_optab, "sync_sub$I$a") OPTAB_D (sync_xor_optab, "sync_xor$I$a") @@ -519,6 +531,18 @@ OPTAB_D (atomic_fetch_nand_optab, "atomic_fetch_nand$I$a") OPTAB_D (atomic_fetch_or_optab, "atomic_fetch_or$I$a") OPTAB_D (atomic_fetch_sub_optab, "atomic_fetch_sub$I$a") OPTAB_D (atomic_fetch_xor_optab, "atomic_fetch_xor$I$a") +OPTAB_D (atomic_fetch_smax_optab, "atomic_fetch_smax$I$a") +OPTAB_D (atomic_fetch_smin_optab, "atomic_fetch_smin$I$a") +OPTAB_D (atomic_smax_fetch_optab, "atomic_smax_fetch$I$a") +OPTAB_D (atomic_smin_fetch_optab, "atomic_smin_fetch$I$a") +OPTAB_D (atomic_smax_optab, "atomic_smax$I$a") +OPTAB_D (atomic_smin_optab, "atomic_smin$I$a") +OPTAB_D (atomic_fetch_umax_optab, "atomic_fetch_umax$I$a") +OPTAB_D (atomic_fetch_umin_optab, "atomic_fetch_umin$I$a") +OPTAB_D (atomic_umax_fetch_optab, "atomic_umax_fetch$I$a") +OPTAB_D (atomic_umin_fetch_optab, "atomic_umin_fetch$I$a") +OPTAB_D (atomic_umax_optab, "atomic_umax$I$a") +OPTAB_D (atomic_umin_optab, "atomic_umin$I$a") OPTAB_D (atomic_load_optab, "atomic_load$I$a") OPTAB_D (atomic_nand_fetch_optab, "atomic_nand_fetch$I$a") OPTAB_D (atomic_nand_optab, "atomic_nand$I$a") -- 2.44.0
