diff options
author | Juzhe-Zhong <juzhe.zhong@rivai.ai> | 2023-08-22 09:58:34 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2023-08-24 18:46:03 +0800 |
commit | 2a0de833be3cb451cedf75ccae3d07f9825d7dc6 (patch) | |
tree | b5fa075383e4fe9dea1855b31b47234f06e718ab /gcc/internal-fn.cc | |
parent | a1558e9ad856938f165f838733955b331ebbec09 (diff) | |
download | gcc-2a0de833be3cb451cedf75ccae3d07f9825d7dc6.zip gcc-2a0de833be3cb451cedf75ccae3d07f9825d7dc6.tar.gz gcc-2a0de833be3cb451cedf75ccae3d07f9825d7dc6.tar.bz2 |
gimple_fold: Support COND_LEN_FNMA/COND_LEN_FMS/COND_LEN_FNMS gimple fold
Hi, Richard and Richi.
Currently, GCC support COND_LEN_FMA for floating-point **NO** -ffast-math.
It's supported in tree-ssa-math-opts.cc. However, GCC failed to support COND_LEN_FNMA/COND_LEN_FMS/COND_LEN_FNMS.
Consider this following case:
__attribute__ ((noipa)) void ternop_##TYPE (TYPE *__restrict dst, \
TYPE *__restrict a, \
TYPE *__restrict b, int n) \
{ \
for (int i = 0; i < n; i++) \
dst[i] -= a[i] * b[i]; \
}
TEST_TYPE (float) \
TEST_ALL ()
Gimple IR for RVV:
...
_39 = -vect__8.14_26;
vect__10.16_21 = .COND_LEN_FMA ({ -1, ... }, vect__6.11_30, _39, vect__4.8_34, vect__4.8_34, _46, 0);
...
This is because this following piece of codes in tree-ssa-math-opts.cc:
if (len)
fma_stmt
= gimple_build_call_internal (IFN_COND_LEN_FMA, 7, cond, mulop1, op2,
addop, else_value, len, bias);
else if (cond)
fma_stmt = gimple_build_call_internal (IFN_COND_FMA, 5, cond, mulop1,
op2, addop, else_value);
else
fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop);
gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt));
gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
use_stmt));
gsi_replace (&gsi, fma_stmt, true);
/* Follow all SSA edges so that we generate FMS, FNMA and FNMS
regardless of where the negation occurs. */
gimple *orig_stmt = gsi_stmt (gsi);
if (fold_stmt (&gsi, follow_all_ssa_edges))
{
if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
gcc_unreachable ();
update_stmt (gsi_stmt (gsi));
}
'fold_stmt' failed to fold NEGATE_EXPR + COND_LEN_FMA ====> COND_LEN_FNMA.
This patch support STMT fold into:
vect__10.16_21 = .COND_LEN_FNMA ({ -1, ... }, vect__8.14_26, vect__6.11_30, vect__4.8_34, { 0.0, ... }, _46, 0);
Note that COND_LEN_FNMA has 7 arguments and COND_LEN_ADD has 6 arguments.
Extend maximum num ops:
- static const unsigned int MAX_NUM_OPS = 5;
+ static const unsigned int MAX_NUM_OPS = 7;
Bootstrap and Regtest on X86 passed.
Tested on aarch64 Qemu.
Fully tested COND_LEN_FNMA/COND_LEN_FMS/COND_LEN_FNMS on RISC-V backend.
gcc/ChangeLog:
* genmatch.cc (decision_tree::gen): Support
COND_LEN_FNMA/COND_LEN_FMS/COND_LEN_FNMS gimple fold.
* gimple-match-exports.cc (gimple_simplify): Ditto.
(gimple_resimplify6): New function.
(gimple_resimplify7): New function.
(gimple_match_op::resimplify): Support
COND_LEN_FNMA/COND_LEN_FMS/COND_LEN_FNMS gimple fold.
(convert_conditional_op): Ditto.
(build_call_internal): Ditto.
(try_conditional_simplification): Ditto.
(gimple_extract): Ditto.
* gimple-match.h (gimple_match_cond::gimple_match_cond): Ditto.
* internal-fn.cc (CASE): Ditto.
Diffstat (limited to 'gcc/internal-fn.cc')
-rw-r--r-- | gcc/internal-fn.cc | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 8baf4d4..4138cc3 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -4448,8 +4448,11 @@ get_unconditional_internal_fn (internal_fn ifn) { switch (ifn) { -#define CASE(NAME) case IFN_COND_##NAME: return IFN_##NAME; - FOR_EACH_COND_FN_PAIR(CASE) +#define CASE(NAME) \ + case IFN_COND_##NAME: \ + case IFN_COND_LEN_##NAME: \ + return IFN_##NAME; +FOR_EACH_COND_FN_PAIR (CASE) #undef CASE default: return IFN_LAST; |