[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] Widening-Mul: Refine build_and_insert_cast when rhs is cast
Jeff Law
law@gcc.gnu.org
Sat Nov 8 06:29:05 GMT 2025
https://gcc.gnu.org/g:82646dac16eb0341574965209aa5543ca6732ef1
commit 82646dac16eb0341574965209aa5543ca6732ef1
Author: Pan Li <pan2.li@intel.com>
Date: Mon Sep 8 22:25:03 2025 +0800
Widening-Mul: Refine build_and_insert_cast when rhs is cast
The widening-mul will insert a cast for the widen-mul, the
function build_and_insert_cast is design to take care of it.
In some case the optimized gimple has some unnecessary cast,
for example as below code.
#define SAT_U_MUL_FMT_5(NT, WT) \
NT __attribute__((noinline)) \
sat_u_mul_##NT##_from_##WT##_fmt_5 (NT a, NT b) \
{ \
WT x = (WT)a * (WT)b; \
NT hi = x >> (sizeof(NT) * 8); \
NT lo = (NT)x; \
return lo | -!!hi; \
}
SAT_U_MUL_FMT_5(uint64_t, uint128_t)
There will be a additional cast to uint128_t after optimized,
this patch would like to refine this by checking the def of
the rhs cast, if it comes from a cast with less or equal
precision, the rhs of the def will be leveraged.
Before this patch:
29 │ _1 = (__int128 unsigned) a_8(D);
30 │ _2 = (__int128 unsigned) b_9(D);
31 │ _35 = (unsigned long) _1;
32 │ _34 = (unsigned long) _2;
33 │ x_10 = _35 w* _34;
After this patch:
27 │ _35 = (unsigned long) a_8(D);
28 │ _34 = (unsigned long) b_9(D);
29 │ x_10 = _35 w* _34;
gcc/ChangeLog:
* tree-ssa-math-opts.cc (build_and_insert_cast): Refine
the cast insert by check the rhs of val.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/sat/widen-mul-0.c: New test.
* gcc.target/riscv/sat/widen-mul-1.c: New test.
* gcc.target/riscv/sat/widen-mul-2.c: New test.
* gcc.target/riscv/sat/widen-mul-3.c: New test.
* gcc.target/riscv/sat/widen-mul.h: New test.
Signed-off-by: Pan Li <pan2.li@intel.com>
(cherry picked from commit d0526e8ef0d92e93b956acb731e212a39106ef0a)
Diff:
---
gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c | 8 ++++++++
gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c | 8 ++++++++
gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c | 8 ++++++++
gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c | 8 ++++++++
gcc/testsuite/gcc.target/riscv/sat/widen-mul.h | 15 +++++++++++++++
gcc/tree-ssa-math-opts.cc | 22 +++++++++++++++++++++-
6 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c
new file mode 100644
index 000000000000..1074fa9d5f41
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "widen-mul.h"
+
+SAT_U_MUL_FMT_5(uint8_t, uint128_t)
+
+/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c
new file mode 100644
index 000000000000..5f8f0dd733ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "widen-mul.h"
+
+SAT_U_MUL_FMT_5(uint16_t, uint128_t)
+
+/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c
new file mode 100644
index 000000000000..4c54cc07b535
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "widen-mul.h"
+
+SAT_U_MUL_FMT_5(uint32_t, uint128_t)
+
+/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c
new file mode 100644
index 000000000000..d3dd97104b70
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "widen-mul.h"
+
+SAT_U_MUL_FMT_5(uint64_t, uint128_t)
+
+/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul.h b/gcc/testsuite/gcc.target/riscv/sat/widen-mul.h
new file mode 100644
index 000000000000..a0a44084e58a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul.h
@@ -0,0 +1,15 @@
+#include <stdint.h>
+
+#if __riscv_xlen == 64
+typedef unsigned __int128 uint128_t;
+#endif
+
+#define SAT_U_MUL_FMT_5(NT, WT) \
+NT __attribute__((noinline)) \
+sat_u_mul_##NT##_from_##WT##_fmt_5 (NT a, NT b) \
+{ \
+ WT x = (WT)a * (WT)b; \
+ NT hi = x >> (sizeof(NT) * 8); \
+ NT lo = (NT)x; \
+ return lo | -!!hi; \
+}
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index c3b2ac28e46e..539fd4e965ed 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -1632,7 +1632,27 @@ build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
tree type, tree val)
{
tree result = make_ssa_name (type);
- gassign *stmt = gimple_build_assign (result, NOP_EXPR, val);
+ tree rhs = val;
+
+ if (TREE_CODE (val) == SSA_NAME)
+ {
+ gimple *def = SSA_NAME_DEF_STMT (val);
+
+ if (is_gimple_assign (def)
+ && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
+ {
+ tree cast_rhs = gimple_assign_rhs1 (def);
+ unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (cast_rhs));
+ unsigned type_prec = TYPE_PRECISION (type);
+ unsigned val_prec = TYPE_PRECISION (TREE_TYPE (val));
+
+ if (type_prec >= rhs_prec && val_prec >= rhs_prec)
+ rhs = cast_rhs;
+ }
+ }
+
+ gassign *stmt = gimple_build_assign (result, NOP_EXPR, rhs);
+
gimple_set_location (stmt, loc);
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
return result;
More information about the Gcc-cvs
mailing list