On 7/17/2026 12:20 AM, Naveen wrote:
CDCE already recognizes an exact two-value length range {0, N}, guards the
zero-length path and replaces the length on the nonzero path with N and folds
the call again. The accepted PR102202 fold handles N == 1 through arbitrary
pointer destinations but the guarded {0, N} path still needs the same
scalar-store conversion for supported N greater than one.
Keep normal builtin folding behavior unchanged: ordinary constant-size memsets
are still left to the existing ADDR_EXPR/object-specific machinery. Expose the
memset fold with an opt-in flag for multi-byte arbitrary-pointer stores and
let CDCE use that flag only after it has shrink-wrapped the zero-length path
and pinned the guarded length to N.
The multi-byte fold keeps the existing object-size deferral and bounds checks.
It limits the store to MOVE_MAX, requires an exact integer/bitwise mode, checks
unaligned-store support and replicates the fill byte into the selected scalar
type.
gcc/ChangeLog:
PR tree-optimization/102202
* gimple-fold.cc (gimple_fold_builtin_memset): Make non-static and
add fold_arbitrary_n parameter. Generalize the arbitrary-pointer
fold to supported constant lengths when requested.
(gimple_fold_builtin): Pass false to gimple_fold_builtin_memset.
* gimple-fold.h (gimple_fold_builtin_memset): Declare.
* tree-call-cdce.cc (shrink_wrap_len_call): Request the multi-byte
arbitrary-pointer memset fold after pinning the guarded length.
gcc/testsuite/ChangeLog:
PR tree-optimization/102202
* gcc.dg/pr102202-fold-zero-n.c: New test.
Signed-off-by: Naveen <[email protected]>
@@ -1481,12 +1484,18 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi,
tree c, tree len)
{
- /* Keep the original call until object-size analysis has inspected it.
*/
+ /* Keep the arbitrary-pointer fold until object-size analysis has
+ inspected the original call. Preserve the old early ADDR_EXPR fold
+ for multi-byte memsets. */
if (!(cfun->curr_properties & PROP_objsz))
- return false;
+ {
+ if (length == 1)
+ return false;
+ goto normal_memset;
+ }
So it seems like cdce is always run after PROP_objsz is set, at least
from a cursory scan of passes.def. So it would seem this code is
dead. I feel like I must be missing something.
I don't see anything particularly concerning. Not a fan of the goto,
but I can see why you used it. The alternative would be to take
everything from teh goto and beyond and factor that into its own routine
and call it at the appropriate places.
I'm inclined to ACK, but would like to understand if we really need that
fragment with the PROP_objsize check anymore.
Jeff