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

Reply via email to