[RFC] mask out mult expr ctz bits from nonzero bits
Alexandre Oliva
oliva@adacore.com
Wed Jan 27 12:47:20 GMT 2021
While looking into the possibility of introducing setmemM patterns on
RISC-V to undo the transformation from loops of word writes into
memset, I was disappointed to find out that get_nonzero_bits would
take into account the range of the length passed to memset, but not
the trivially-available observation that this length was a multiple of
the word size. This knowledge, if passed on to setmemM, could enable
setmemM to output more efficient code.
In the end, I did not introduce a setmemM pattern, nor the machinery
to pass the ctz of the length on to it along with other useful
information, but I figured this small improvement to nonzero_bits
could still improve code generation elsewhere.
https://gcc.gnu.org/pipermail/gcc-patches/2021-January/564341.html
Regstrapped on x86_64-linux-gnu. No analysis of codegen impact yet.
Does this seem worth pursuing, presumably for stage1?
for gcc/ChangeLog
* tree-ssanames.c (get_nonzero_bits): Zero out low bits of
integral types, when a MULT_EXPR INTEGER_CST operand ensures
the result will be a multiple of a power of two.
---
gcc/tree-ssanames.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 51a26d2fce1c2..c4b5bf2a4999a 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -546,10 +546,29 @@ get_nonzero_bits (const_tree name)
}
range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+ wide_int ret;
if (!ri)
- return wi::shwi (-1, precision);
+ ret = wi::shwi (-1, precision);
+ else
+ ret = ri->get_nonzero_bits ();
+
+ /* If NAME is defined as a multiple of a constant C, we know the ctz(C) low
+ bits are zero. ??? Should we handle LSHIFT_EXPR too? Non-constants,
+ e.g. the minimum shift count, and ctz from both MULT_EXPR operands? That
+ could make for deep recursion. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (name))
+ && SSA_NAME_DEF_STMT (name)
+ && is_gimple_assign (SSA_NAME_DEF_STMT (name))
+ && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (name)) == MULT_EXPR
+ && TREE_CODE (gimple_assign_rhs2 (SSA_NAME_DEF_STMT (name))) == INTEGER_CST)
+ {
+ unsigned HOST_WIDE_INT bits
+ = tree_ctz (gimple_assign_rhs2 (SSA_NAME_DEF_STMT (name)));
+ wide_int mask = wi::shwi (-1, precision) << bits;
+ ret &= mask;
+ }
- return ri->get_nonzero_bits ();
+ return ret;
}
/* Return TRUE is OP, an SSA_NAME has a range of values [0..1], false
--
Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/
Free Software Activist GNU Toolchain Engineer
Vim, Vi, Voltei pro Emacs -- GNUlius Caesar
More information about the Gcc-patches
mailing list