From patchwork Tue Jul 7 06:39:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naveen SiddeGowda X-Patchwork-Id: 138633 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 421B44BA2E1E for ; Tue, 7 Jul 2026 06:40:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 421B44BA2E1E Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=FatKcfvb X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by sourceware.org (Postfix) with ESMTPS id 4481A4BA5435 for ; Tue, 7 Jul 2026 06:39:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4481A4BA5435 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=oss.qualcomm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=qualcomm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4481A4BA5435 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783406360; cv=none; b=G22mO6no3hkR1Fis2c84EHV5PyH3eA6EZnPS4pgdrLOlaoERs/McFrnrx2ktaL9v6KgUu9dyMXmleOAAm811dTXNQFS9HWkSW3up/FGqcpIyh3a+rhBEY/A7PG8MESfEmH/4B4y/sQbLS1ABFobYBWkw4CwcCM1660b7lrk+Il0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783406360; c=relaxed/simple; bh=LOAvN8Q8CDpbQj03LInrO3QiPKfE8sTerPXtX20VaaI=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=RsusdsNWJ8oviR0mpX7IlC9LHu6f9RdZAcDOFYYa/s7EwCykZSRZmH0kTD50zpd0zjqYVmGHj1vpNE2T66wfEClAQbRnV7sTu6nx621hpU66xMx4erIiYhIIBgMh14djINqwmIUsVWDsMcKnC/vtmiTfrIxbsQwby7wPtmhQVJk= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=FatKcfvb DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4481A4BA5435 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66748oma2649207; Tue, 7 Jul 2026 06:39:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=MQUTJPbJMtL eExcK6W86vpVaVM2wwPzcefK6nF5zXMs=; b=FatKcfvbWzuQqHtqe8tZGE5mhlZ Rs3tucG5rjLZsEukr7S05lVW+q6EEkeGASByHahkbUwl7rsKGsmnx+B6DnwUT7CC aTOsPigKsP+sjEyh4xe/25vKJZyDIzyf5vYNBn5/K+D8O5X68bcPx+yNulZPoY7i HHaXfvFMRlRsiKn9UGzXURiP+D7VanQN9U4+eSlBtca88IGFGQAYAPjHqdTbnScm GFBbAqWi9DXAaNNIvErYN8K2qRxcyfXMoGOQuKTp1PcXf+XC4rVqVOe9edco+dMn Jp2u+ZMZposu4faTgBDV4exKxp9G9vt8OWCsK29/Xq8KKVqP6O0c0R65mMw== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4f8fdw2wgw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 06:39:18 +0000 (GMT) Received: from pps.filterd (NALASPPMTA05.qualcomm.com [127.0.0.1]) by NALASPPMTA05.qualcomm.com (8.18.1.7/8.18.1.7) with ESMTP id 6676dI9x008838; Tue, 7 Jul 2026 06:39:18 GMT Received: from pps.reinject (localhost [127.0.0.1]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTPS id 4f86ebujj7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 06:39:18 +0000 (GMT) Received: from NALASPPMTA05.qualcomm.com (NALASPPMTA05.qualcomm.com [127.0.0.1]) by pps.reinject (8.18.1.12/8.18.1.12) with ESMTP id 6676WqaL027374; Tue, 7 Jul 2026 06:39:18 GMT Received: from hu-devc-lv-u22-c.qualcomm.com (hu-navehs-lv.qualcomm.com [10.47.205.87]) by NALASPPMTA05.qualcomm.com (PPS) with ESMTPS id 6676dHU4008833 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 06:39:17 +0000 (GMT) Received: by hu-devc-lv-u22-c.qualcomm.com (Postfix, from userid 4831948) id CBFCD5EF; Mon, 6 Jul 2026 23:39:17 -0700 (PDT) From: Naveen To: gcc-patches@gcc.gnu.org Cc: andrew.pinski@oss.qualcomm.com, richard.guenther@gmail.com Subject: [PATCH v2] tree-optimization: Extend CDCE memset shrink-wrapping to {0, N} ranges [PR102202] Date: Mon, 6 Jul 2026 23:39:17 -0700 Message-Id: <20260707063917.3162084-1-naveen.siddegowda@oss.qualcomm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDA2MiBTYWx0ZWRfX5+LxW0/ab/9O ILgPt6Sw6IdsnD7HOVpUKevsWZbvtKj+v8xhPSyO6VVhaFcs9O1XaiL550pmeRTF1NKe5aXlp67 XbofQfFiWClEeSUlRSz5dbjvRDZC3js= X-Proofpoint-ORIG-GUID: gBVyVucLfgq0rjF2mFYQUE7eAOGFMw6U X-Authority-Analysis: v=2.4 cv=EtziaycA c=1 sm=1 tr=0 ts=6a4c9f16 cx=c_pps a=ouPCqIW2jiPt+lZRy3xVPw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=cM7gfQdQb2HNzDNHjT4A:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDA2MiBTYWx0ZWRfX4sXyshGguOHU Y/4qdBYXhz6S8Z1UE4P7cYIAQ/OmDZMAnDhEglPPzInO3hmhjzvJEWRukcWD6YRWPPbdsi8E0ME TBeT8f3Emy+331ilVdYpbdPybKXU+0xkKAA/H1FFKNtXpJgFiXsQjZjupLHSp/WYXUhaWLhsimC EEMCk4Mo8zYxlPdxUaQAqeAnPvGj1iDy4aRtdDWGgOjh89t2eazSwheiE3Dj3uGczA4UGS3EJzt n3ABWDBwt31AnbEz0P79lcyfvkjlKc00N2Wt0tI2Gx2uCZWHxcazR+owJZbGsndC9RA12eOrOCk HYqFDk3JqmWTvmemyzHp5opwoRh5/RnCb145wnqRVHSkdfuz179AEORyM6nlIrDx/JqeI08pjbE zBg/GtiEpDXn/tHbE5PqUIBnbb571YkoLE8CBH8zFEHfmr/YvoKHwvdNyT5M2UwXRaz5kfgh8jc 4UJIhcvMy9uahS7ljKQ== X-Proofpoint-GUID: gBVyVucLfgq0rjF2mFYQUE7eAOGFMw6U X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-07_01,2026-07-06_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 clxscore=1015 adultscore=0 phishscore=0 spamscore=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607070062 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, PROLO_LEO1, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org The patch extends the CDCE shrink-wrapping support added for PR102202. The existing transform handles memset calls whose length is known to be in [0, 1]. It bypasses the call for length zero and specializes the nonzero path to a constant length of one. Extend this to exact two-value length ranges {0, N}, where N is a nonzero integer constant. The zero-length path is still bypassed and the nonzero path is specialized to the constant N. In particular, the transform does not accept an ordinary interval [0, N] since such an interval can contain values other than zero and N. The range query now returns the nonzero member of either a [0, 1] range or an exact {0, N} range. The existing [0, 1] behavior is preserved. gcc/ChangeLog: PR tree-optimization/102202 * tree-call-cdce.cc: Include "value-query.h" and "value-range.h". (len_has_boolean_range_p): Remove. (get_len_nonzero_value): New function. Return the nonzero member of LEN's value range when it is a boolean range [0, 1] or an exact two-value set {0, N}. (can_shrink_wrap_len_p): Replace len_has_boolean_range_p call with get_len_nonzero_value. Add NONZERO_LEN output parameter and set it to the returned nonzero value on success. (shrink_wrap_len_call): Use it to pin the length argument on the guarded call path instead of build_one_cst. (shrink_wrap_conditional_dead_built_in_calls): Declare local nonzero_len and pass it to can_shrink_wrap_len_p and forward it to shrink_wrap_len_call. (pass_call_cdce::execute): Pass nullptr as NONZERO_LEN to can_shrink_wrap_len_p. gcc/testsuite/ChangeLog: PR tree-optimization/102202 * gcc.dg/pr102202-3.c: New test. * gcc.dg/pr102202-4.c: New test. Signed-off-by: Naveen --- gcc/testsuite/gcc.dg/pr102202-3.c | 21 ++++++++++ gcc/testsuite/gcc.dg/pr102202-4.c | 16 ++++++++ gcc/tree-call-cdce.cc | 65 +++++++++++++++++++++---------- 3 files changed, 82 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr102202-3.c create mode 100644 gcc/testsuite/gcc.dg/pr102202-4.c diff --git a/gcc/testsuite/gcc.dg/pr102202-3.c b/gcc/testsuite/gcc.dg/pr102202-3.c new file mode 100644 index 00000000000..1904e309fee --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102202-3.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/102202 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cdce-details" } */ + +/* An exact two-value range {0, 2}. Use a PHI so that Ranger retains + the two singleton values at the call. */ + +void +g1 (unsigned int x, int c, char *d) +{ + __SIZE_TYPE__ len; + + if (x) + len = 2; + else + len = 0; + + __builtin_memset (d, c, len); +} + +/* { dg-final { scan-tree-dump-times "function call is shrink-wrapped into error conditions" 1 "cdce" } } */ diff --git a/gcc/testsuite/gcc.dg/pr102202-4.c b/gcc/testsuite/gcc.dg/pr102202-4.c new file mode 100644 index 00000000000..908256b5b2d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102202-4.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/102202 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cdce-details" } */ + +/* The interval [0, 2] is not the exact two-value set {0, 2}. */ + +void +g1 (__SIZE_TYPE__ len, int c, char *d) +{ + if (len > 2) + __builtin_unreachable (); + + __builtin_memset (d, c, len); +} + +/* { dg-final { scan-tree-dump-not "function call is shrink-wrapped into error conditions" "cdce" } } */ diff --git a/gcc/tree-call-cdce.cc b/gcc/tree-call-cdce.cc index 144f485909c..289504fc927 100644 --- a/gcc/tree-call-cdce.cc +++ b/gcc/tree-call-cdce.cc @@ -39,6 +39,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-eh.h" #include "tree-ssanames.h" #include "gimple-fold.h" +#include "value-query.h" +#include "value-range.h" /* This pass serves two closely-related purposes: @@ -1257,23 +1259,40 @@ use_internal_fn (gcall *call) is_arg_conds ? new_call : NULL); } -/* Return true if LEN is an SSA_NAME known to have a boolean range, i.e. its - value is provably in [0, 1]. */ +/* Return the nonzero member of LEN's range if LEN is an SSA name with range + [0, 1] or the exact two-value set {0, N}. Return NULL_TREE otherwise. */ -static bool -len_has_boolean_range_p (tree len, gimple *stmt) +static tree +get_len_nonzero_value (tree len, gimple *stmt) { if (TREE_CODE (len) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (len))) - return false; - return ssa_name_has_boolean_range (len, stmt); + return NULL_TREE; + + if (ssa_name_has_boolean_range (len, stmt)) + return build_one_cst (TREE_TYPE (len)); + + int_range<2> range (TREE_TYPE (len)); + if (!get_range_query (cfun)->range_of_expr (range, len, stmt) + || range.num_pairs () != 2) + return NULL_TREE; + + if (!wi::eq_p (range.lower_bound (0), 0) + || !wi::eq_p (range.upper_bound (0), 0)) + return NULL_TREE; + + if (!wi::eq_p (range.lower_bound (1), range.upper_bound (1))) + return NULL_TREE; + + return wide_int_to_tree (TREE_TYPE (len), range.lower_bound (1)); } /* Return true if CALL is a supported length-taking builtin whose length - argument is an SSA name known to have a boolean range. On success, - set LEN_ARG to the argument index of the length. */ + argument is an SSA name known to have a suitable range. On success, + set LEN_ARG to the argument index of the length and, if NONZERO_LEN is + nonnull, set it to the nonzero member of the range. */ static bool -can_shrink_wrap_len_p (gcall *call, unsigned *len_arg) +can_shrink_wrap_len_p (gcall *call, unsigned *len_arg, tree *nonzero_len) { if (!gimple_call_builtin_p (call, BUILT_IN_MEMSET) || !gimple_vdef (call)) @@ -1284,10 +1303,13 @@ can_shrink_wrap_len_p (gcall *call, unsigned *len_arg) return false; tree len = gimple_call_arg (call, memset_len_arg); - if (!len_has_boolean_range_p (len, call)) + tree value = get_len_nonzero_value (len, call); + if (!value) return false; *len_arg = memset_len_arg; + if (nonzero_len) + *nonzero_len = value; return true; } @@ -1305,13 +1327,14 @@ gen_zero_len_conditions (tree len, vec &conds, unsigned *nconds) *nconds = 1; } -/* Shrink-wrap CALL whose LEN_ARG argument is known to be in [0, 1]. - ZERO_LEN_RESULT is the value of the call result when its length is zero. - On the guarded path the length is one, so pin it to a constant for - subsequent folding. */ +/* Shrink-wrap CALL whose LEN_ARG argument is known to be in [0, 1] or + {0, N}. ZERO_LEN_RESULT is the value of the call result when its length + is zero. On the guarded path the length is NONZERO_LEN, so pin it to that + constant for subsequent folding. */ static void -shrink_wrap_len_call (gcall *call, unsigned len_arg, tree zero_len_result) +shrink_wrap_len_call (gcall *call, unsigned len_arg, tree zero_len_result, + tree nonzero_len) { tree lhs = gimple_call_lhs (call); @@ -1341,8 +1364,8 @@ shrink_wrap_len_call (gcall *call, unsigned len_arg, tree zero_len_result) shrink_wrap_one_built_in_call_with_conds (call, conds, nconds); - /* On the guarded path the length is one. */ - gimple_call_set_arg (call, len_arg, build_one_cst (TREE_TYPE (len))); + /* On the guarded path the length is NONZERO_LEN. */ + gimple_call_set_arg (call, len_arg, nonzero_len); update_stmt (call); gimple_stmt_iterator gsi = gsi_for_stmt (call); fold_stmt (&gsi); @@ -1363,8 +1386,10 @@ shrink_wrap_conditional_dead_built_in_calls (const vec &calls) unsigned len_arg; /* memset returns its destination pointer on the zero-length path. */ - if (can_shrink_wrap_len_p (bi_call, &len_arg)) - shrink_wrap_len_call (bi_call, len_arg, gimple_call_arg (bi_call, 0)); + tree nonzero_len; + if (can_shrink_wrap_len_p (bi_call, &len_arg, &nonzero_len)) + shrink_wrap_len_call (bi_call, len_arg, gimple_call_arg (bi_call, 0), + nonzero_len); else if (gimple_call_lhs (bi_call)) use_internal_fn (bi_call); else @@ -1427,7 +1452,7 @@ pass_call_cdce::execute (function *fun) unsigned len_arg; if (stmt && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL) - && (can_shrink_wrap_len_p (stmt, &len_arg) + && (can_shrink_wrap_len_p (stmt, &len_arg, nullptr) || (gimple_call_lhs (stmt) ? can_use_internal_fn (stmt) : can_test_argument_range (stmt)))