For a few math IFNs we never declared the conditional variants. This is needed
to handle trapping math correctly. SVE already implements all of these using
the expected optabs.
This just adds the COND and COND_LEN optabs for SQRT, CEIL, FLOOR, ROUND and
RINT.
Note that we don't seem to have any documentation for the math IFNs as they look
like they're all on the optabs/original builtins. As such I only documented the
optabs as that's consistent.
Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.
Ok for master?
Thanks,
Tamar
gcc/ChangeLog:
PR tree-optimization/122103
* doc/md.texi: Document them
* internal-fn.cc (FOR_EACH_COND_FN_PAIR, internal_fn_else_index): Add
SQRT, CEIL, FLOOR, ROUND and RINT.
* internal-fn.def (IFN_COND_SQRT, IFN_COND_CEIL, IFN_COND_FLOOR,
IFN_COND_ROUND, IFN_COND_RINT, IFN_COND_LEN_SQRT, IFN_COND_LEN_CEIL,
IFN_COND_LEN_FLOOR, IFN_COND_LEN_ROUND, IFN_COND_LEN_RINT): New.
* optabs.def (cond_rint_optab, cond_sqrt_optab, cond_round_optab,
cond_ceil_optab, cond_floor_optab, cond_len_rint_optab,
cond_len_sqrt_optab, cond_len_round_optab, cond_len_ceil_optab,
cond_len_floor_optab): New.
---
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index
6ca039b70f9647eed81ac57a96669ff8bf80ad38..58d8fb28c15d3ad279baf795670950c23ef3d60e
100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -7362,8 +7362,18 @@ operand 0, otherwise (operand 2 + operand 3) is moved.
@cindex @code{cond_neg@var{mode}} instruction pattern
@cindex @code{cond_one_cmpl@var{mode}} instruction pattern
+@cindex @code{cond_sqrt@var{mode}} instruction pattern
+@cindex @code{cond_ceil@var{mode}} instruction pattern
+@cindex @code{cond_floor@var{mode}} instruction pattern
+@cindex @code{cond_round@var{mode}} instruction pattern
+@cindex @code{cond_rint@var{mode}} instruction pattern
@item @samp{cond_neg@var{mode}}
@itemx @samp{cond_one_cmpl@var{mode}}
+@itemx @samp{cond_sqrt@var{mode}}
+@itemx @samp{cond_ceil@var{mode}}
+@itemx @samp{cond_floor@var{mode}}
+@itemx @samp{cond_round@var{mode}}
+@itemx @samp{cond_rint@var{mode}}
When operand 1 is true, perform an operation on operands 2 and
store the result in operand 0, otherwise store operand 3 in operand 0.
The operation works elementwise if the operands are vectors.
@@ -7487,8 +7497,18 @@ for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++)
@cindex @code{cond_len_neg@var{mode}} instruction pattern
@cindex @code{cond_len_one_cmpl@var{mode}} instruction pattern
+@cindex @code{cond_len_sqrt@var{mode}} instruction pattern
+@cindex @code{cond_len_ceil@var{mode}} instruction pattern
+@cindex @code{cond_len_floor@var{mode}} instruction pattern
+@cindex @code{cond_len_round@var{mode}} instruction pattern
+@cindex @code{cond_len_rint@var{mode}} instruction pattern
@item @samp{cond_len_neg@var{mode}}
@itemx @samp{cond_len_one_cmpl@var{mode}}
+@itemx @samp{cond_len_sqrt@var{mode}}
+@itemx @samp{cond_len_ceil@var{mode}}
+@itemx @samp{cond_len_floor@var{mode}}
+@itemx @samp{cond_len_round@var{mode}}
+@itemx @samp{cond_len_rint@var{mode}}
When operand 1 is true and element index < operand 4 + operand 5, perform an
operation on operands 1 and
store the result in operand 0, otherwise store operand 2 in operand 0.
The operation only works for the operands are vectors.
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index
d94ad1227460f60cd916c949e7c78f5836830d67..f52e1c99ea53eaad17f5b670fafee2dcbe6d2112
100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -4829,7 +4829,12 @@ get_conditional_len_internal_fn (tree_code code)
T (FMA) \
T (FMS) \
T (FNMA) \
- T (FNMS)
+ T (FNMS) \
+ T (SQRT) \
+ T (ROUND) \
+ T (FLOOR) \
+ T (RINT) \
+ T (CEIL)
/* Return a function that only performs internal function FN when a
certain condition is met and that uses a given fallback value otherwise.
@@ -5129,8 +5134,18 @@ internal_fn_else_index (internal_fn fn)
{
case IFN_COND_NEG:
case IFN_COND_NOT:
+ case IFN_COND_SQRT:
+ case IFN_COND_CEIL:
+ case IFN_COND_FLOOR:
+ case IFN_COND_ROUND:
+ case IFN_COND_RINT:
case IFN_COND_LEN_NEG:
case IFN_COND_LEN_NOT:
+ case IFN_COND_LEN_SQRT:
+ case IFN_COND_LEN_CEIL:
+ case IFN_COND_LEN_FLOOR:
+ case IFN_COND_LEN_ROUND:
+ case IFN_COND_LEN_RINT:
return 2;
case IFN_LEN_LOAD:
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index
9227ab06a9b68f080b654be3ccfff3b8b9ffb287..656385cf2cfce106ef9a2aa88c71d67ccc5516cd
100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -286,6 +286,11 @@ DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_MUL, ECF_CONST, first,
ssmul, usmul, binary)
DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_TRUNC, ECF_CONST, first, sstrunc, ustrunc,
unary_convert)
+DEF_INTERNAL_COND_FN (SQRT, ECF_CONST, sqrt, unary)
+DEF_INTERNAL_COND_FN (CEIL, ECF_CONST, ceil, unary)
+DEF_INTERNAL_COND_FN (FLOOR, ECF_CONST, floor, unary)
+DEF_INTERNAL_COND_FN (ROUND, ECF_CONST, round, unary)
+DEF_INTERNAL_COND_FN (RINT, ECF_CONST, rint, unary)
DEF_INTERNAL_COND_FN (ADD, ECF_CONST, add, binary)
DEF_INTERNAL_COND_FN (SUB, ECF_CONST, sub, binary)
DEF_INTERNAL_COND_FN (MUL, ECF_CONST, smul, binary)
diff --git a/gcc/optabs.def b/gcc/optabs.def
index
7ed4327ec94a09e7e44f4593d52c27c0497ed79c..5881a028545539fd40245bcb291a16b80ed65e79
100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -244,6 +244,7 @@ OPTAB_D (addcc_optab, "add$acc")
OPTAB_D (negcc_optab, "neg$acc")
OPTAB_D (notcc_optab, "not$acc")
OPTAB_D (movcc_optab, "mov$acc")
+OPTAB_D (cond_sqrt_optab, "cond_sqrt$F$a")
OPTAB_D (cond_add_optab, "cond_add$a")
OPTAB_D (cond_sub_optab, "cond_sub$a")
OPTAB_D (cond_smul_optab, "cond_mul$a")
@@ -272,6 +273,7 @@ OPTAB_D (cond_neg_optab, "cond_neg$a")
OPTAB_D (cond_vec_cbranch_any_optab, "cond_vec_cbranch_any$a")
OPTAB_D (cond_vec_cbranch_all_optab, "cond_vec_cbranch_all$a")
OPTAB_D (cond_one_cmpl_optab, "cond_one_cmpl$a")
+OPTAB_D (cond_len_sqrt_optab, "cond_len_sqrt$F$a")
OPTAB_D (cond_len_add_optab, "cond_len_add$a")
OPTAB_D (cond_len_sub_optab, "cond_len_sub$a")
OPTAB_D (cond_len_smul_optab, "cond_len_mul$a")
@@ -339,6 +341,14 @@ OPTAB_D (floor_optab, "floor$a2")
OPTAB_D (ceil_optab, "ceil$a2")
OPTAB_D (btrunc_optab, "btrunc$a2")
OPTAB_D (nearbyint_optab, "nearbyint$a2")
+OPTAB_D (cond_rint_optab, "cond_rint$a")
+OPTAB_D (cond_round_optab, "cond_round$a")
+OPTAB_D (cond_floor_optab, "cond_floor$a")
+OPTAB_D (cond_ceil_optab, "cond_ceil$a")
+OPTAB_D (cond_len_rint_optab, "cond_len_rint$a")
+OPTAB_D (cond_len_round_optab, "cond_len_round$a")
+OPTAB_D (cond_len_floor_optab, "cond_len_floor$a")
+OPTAB_D (cond_len_ceil_optab, "cond_len_ceil$F$a")
OPTAB_D (acos_optab, "acos$a2")
OPTAB_D (acosh_optab, "acosh$a2")
--
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 6ca039b70f9647eed81ac57a96669ff8bf80ad38..58d8fb28c15d3ad279baf795670950c23ef3d60e 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -7362,8 +7362,18 @@ operand 0, otherwise (operand 2 + operand 3) is moved.
@cindex @code{cond_neg@var{mode}} instruction pattern
@cindex @code{cond_one_cmpl@var{mode}} instruction pattern
+@cindex @code{cond_sqrt@var{mode}} instruction pattern
+@cindex @code{cond_ceil@var{mode}} instruction pattern
+@cindex @code{cond_floor@var{mode}} instruction pattern
+@cindex @code{cond_round@var{mode}} instruction pattern
+@cindex @code{cond_rint@var{mode}} instruction pattern
@item @samp{cond_neg@var{mode}}
@itemx @samp{cond_one_cmpl@var{mode}}
+@itemx @samp{cond_sqrt@var{mode}}
+@itemx @samp{cond_ceil@var{mode}}
+@itemx @samp{cond_floor@var{mode}}
+@itemx @samp{cond_round@var{mode}}
+@itemx @samp{cond_rint@var{mode}}
When operand 1 is true, perform an operation on operands 2 and
store the result in operand 0, otherwise store operand 3 in operand 0.
The operation works elementwise if the operands are vectors.
@@ -7487,8 +7497,18 @@ for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++)
@cindex @code{cond_len_neg@var{mode}} instruction pattern
@cindex @code{cond_len_one_cmpl@var{mode}} instruction pattern
+@cindex @code{cond_len_sqrt@var{mode}} instruction pattern
+@cindex @code{cond_len_ceil@var{mode}} instruction pattern
+@cindex @code{cond_len_floor@var{mode}} instruction pattern
+@cindex @code{cond_len_round@var{mode}} instruction pattern
+@cindex @code{cond_len_rint@var{mode}} instruction pattern
@item @samp{cond_len_neg@var{mode}}
@itemx @samp{cond_len_one_cmpl@var{mode}}
+@itemx @samp{cond_len_sqrt@var{mode}}
+@itemx @samp{cond_len_ceil@var{mode}}
+@itemx @samp{cond_len_floor@var{mode}}
+@itemx @samp{cond_len_round@var{mode}}
+@itemx @samp{cond_len_rint@var{mode}}
When operand 1 is true and element index < operand 4 + operand 5, perform an operation on operands 1 and
store the result in operand 0, otherwise store operand 2 in operand 0.
The operation only works for the operands are vectors.
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index d94ad1227460f60cd916c949e7c78f5836830d67..f52e1c99ea53eaad17f5b670fafee2dcbe6d2112 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -4829,7 +4829,12 @@ get_conditional_len_internal_fn (tree_code code)
T (FMA) \
T (FMS) \
T (FNMA) \
- T (FNMS)
+ T (FNMS) \
+ T (SQRT) \
+ T (ROUND) \
+ T (FLOOR) \
+ T (RINT) \
+ T (CEIL)
/* Return a function that only performs internal function FN when a
certain condition is met and that uses a given fallback value otherwise.
@@ -5129,8 +5134,18 @@ internal_fn_else_index (internal_fn fn)
{
case IFN_COND_NEG:
case IFN_COND_NOT:
+ case IFN_COND_SQRT:
+ case IFN_COND_CEIL:
+ case IFN_COND_FLOOR:
+ case IFN_COND_ROUND:
+ case IFN_COND_RINT:
case IFN_COND_LEN_NEG:
case IFN_COND_LEN_NOT:
+ case IFN_COND_LEN_SQRT:
+ case IFN_COND_LEN_CEIL:
+ case IFN_COND_LEN_FLOOR:
+ case IFN_COND_LEN_ROUND:
+ case IFN_COND_LEN_RINT:
return 2;
case IFN_LEN_LOAD:
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 9227ab06a9b68f080b654be3ccfff3b8b9ffb287..656385cf2cfce106ef9a2aa88c71d67ccc5516cd 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -286,6 +286,11 @@ DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_MUL, ECF_CONST, first, ssmul, usmul, binary)
DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_TRUNC, ECF_CONST, first, sstrunc, ustrunc, unary_convert)
+DEF_INTERNAL_COND_FN (SQRT, ECF_CONST, sqrt, unary)
+DEF_INTERNAL_COND_FN (CEIL, ECF_CONST, ceil, unary)
+DEF_INTERNAL_COND_FN (FLOOR, ECF_CONST, floor, unary)
+DEF_INTERNAL_COND_FN (ROUND, ECF_CONST, round, unary)
+DEF_INTERNAL_COND_FN (RINT, ECF_CONST, rint, unary)
DEF_INTERNAL_COND_FN (ADD, ECF_CONST, add, binary)
DEF_INTERNAL_COND_FN (SUB, ECF_CONST, sub, binary)
DEF_INTERNAL_COND_FN (MUL, ECF_CONST, smul, binary)
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 7ed4327ec94a09e7e44f4593d52c27c0497ed79c..5881a028545539fd40245bcb291a16b80ed65e79 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -244,6 +244,7 @@ OPTAB_D (addcc_optab, "add$acc")
OPTAB_D (negcc_optab, "neg$acc")
OPTAB_D (notcc_optab, "not$acc")
OPTAB_D (movcc_optab, "mov$acc")
+OPTAB_D (cond_sqrt_optab, "cond_sqrt$F$a")
OPTAB_D (cond_add_optab, "cond_add$a")
OPTAB_D (cond_sub_optab, "cond_sub$a")
OPTAB_D (cond_smul_optab, "cond_mul$a")
@@ -272,6 +273,7 @@ OPTAB_D (cond_neg_optab, "cond_neg$a")
OPTAB_D (cond_vec_cbranch_any_optab, "cond_vec_cbranch_any$a")
OPTAB_D (cond_vec_cbranch_all_optab, "cond_vec_cbranch_all$a")
OPTAB_D (cond_one_cmpl_optab, "cond_one_cmpl$a")
+OPTAB_D (cond_len_sqrt_optab, "cond_len_sqrt$F$a")
OPTAB_D (cond_len_add_optab, "cond_len_add$a")
OPTAB_D (cond_len_sub_optab, "cond_len_sub$a")
OPTAB_D (cond_len_smul_optab, "cond_len_mul$a")
@@ -339,6 +341,14 @@ OPTAB_D (floor_optab, "floor$a2")
OPTAB_D (ceil_optab, "ceil$a2")
OPTAB_D (btrunc_optab, "btrunc$a2")
OPTAB_D (nearbyint_optab, "nearbyint$a2")
+OPTAB_D (cond_rint_optab, "cond_rint$a")
+OPTAB_D (cond_round_optab, "cond_round$a")
+OPTAB_D (cond_floor_optab, "cond_floor$a")
+OPTAB_D (cond_ceil_optab, "cond_ceil$a")
+OPTAB_D (cond_len_rint_optab, "cond_len_rint$a")
+OPTAB_D (cond_len_round_optab, "cond_len_round$a")
+OPTAB_D (cond_len_floor_optab, "cond_len_floor$a")
+OPTAB_D (cond_len_ceil_optab, "cond_len_ceil$F$a")
OPTAB_D (acos_optab, "acos$a2")
OPTAB_D (acosh_optab, "acosh$a2")