From patchwork Wed Sep 2 08:05:25 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 142680 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 ADAFD4BA23EB for ; Wed, 2 Sep 2026 08:06:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ADAFD4BA23EB Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=rsY092PI; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=lqgsA82w; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=SyPxpvAR; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=74sEG8Uq X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by sourceware.org (Postfix) with ESMTPS id 5302B4BA2E24 for ; Wed, 2 Sep 2026 08:05:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5302B4BA2E24 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5302B4BA2E24 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=195.135.223.130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788336334; cv=none; b=YTJs3zr6KPEkrTp/VUBokql3lraQOTrHhDW+OWPGpdv0LUxy4UaMao6LWM87LqxN97HjQjaaPVjujnCi7mfHh+6Pv60gdmu/TpwLNYux9IMpj9Mvgxw2g9M26+1Np6RZoTvoUXqcFGRUqo2qSMI0c+Mqt2qU95SVg9iqenFYgKI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788336334; c=relaxed/simple; bh=bZkyddi0g3PWbdKgfdCY6V46FCvSrLZRNiA/MyfiMEc=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature:Date: From:To:Subject:Message-ID:MIME-Version; b=vSa7BSgHx37l59Z93yh+N8VaVrm0qKJbwOQYVFoJNTPXU5o+1lb4L6DsvQPlwMUviVIXiiTO+xc0+NKMR5sob0mDStTev3co6peAeoEpbBOBmTzIHz/HKXQl+RyCeeIwtRexxUq5z/NmPRQkM8Bt2xjujIpvepehIVSpager3fg= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=rsY092PI; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=lqgsA82w; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=SyPxpvAR; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=74sEG8Uq DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5302B4BA2E24 Received: from murzim.nue2.suse.org (unknown [10.168.4.243]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 211F621EF5; Wed, 2 Sep 2026 08:05:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1788336329; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=/sHS2nkJm7+3rwcV3fG5hcJAG1gJOu93FmBnjuKmq+Q=; b=rsY092PIt3IzGZnLw57iR7pvlH7mjM0GV7o7q2iWWEo+UVNWnJddMCK6OSXlCFtxQt7GB8 rAzwKobQnoN5VlZQRvIpaNOOxXOSlFUl247AvL5WtqukfuZsHTZyyjgfKP7pdc50yk/syp 4wDzGvn4lwRoAnv0yVBq3oMydRrGBis= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1788336329; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=/sHS2nkJm7+3rwcV3fG5hcJAG1gJOu93FmBnjuKmq+Q=; b=lqgsA82w0NQEeFb3xBHXz5nFxJZGG2wbO1YWyfrrlS0s8EDfnkdBh34gxb/lX8DUP7ktUf t+PY04l9aw7/gIAQ== Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1788336325; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=/sHS2nkJm7+3rwcV3fG5hcJAG1gJOu93FmBnjuKmq+Q=; b=SyPxpvARReOwohtocd5lRnoq+WJIsdDGVef/1boZjK/GlgHwKCRlpEETeRAaGohEEs3XJf 1vy9JMQv5YtI0+hSvcIcu5huo8x4g6s5qJzcFb69Rq3fJCfkb08zf1qO+X+1a75gDi+YJA oIsdaGcwM2lKpDssfOUhYFpO8oIr5EM= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1788336325; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=/sHS2nkJm7+3rwcV3fG5hcJAG1gJOu93FmBnjuKmq+Q=; b=74sEG8UqN4ryosA/AJ1qYdt8GLKT8Cu7CTYmcwhTSo5NkpyA4spDF551wMBu7YI/l4KJpc 2oWacIlL1Y1a+1Dw== Date: Wed, 2 Sep 2026 10:05:25 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org cc: mjambor@suse.cz Subject: [PATCH] ipa: do not match bit-field predicate conditions against byte offsets Message-ID: MIME-Version: 1.0 X-Spam-Level: X-Spam-Score: -4.30 X-Spamd-Result: default: False [-4.30 / 50.00]; BAYES_HAM(-3.00)[100.00%]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_SHORT(-0.20)[-0.998]; MIME_GOOD(-0.10)[text/plain]; TO_MATCH_ENVRCPT_ALL(0.00)[]; ARC_NA(0.00)[]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; RCPT_COUNT_TWO(0.00)[2]; FROM_HAS_DN(0.00)[]; MISSING_XM_UA(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; TO_DN_NONE(0.00)[]; RCVD_COUNT_ZERO(0.00)[0]; DBL_BLOCKED_OPENRESOLVER(0.00)[murzim.nue2.suse.org:helo, fhfr.qr:mid, ipa-fnsummary.cc:url] X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, 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 Conditions of IPA predicates record the position of an aggregate load as a bit offset (ipa_load_from_parm_agg derives it from get_ref_base_and_extent_hwi and add_condition stores it verbatim), while the aggregate values of jump functions are indexed by byte offsets (ipa_argagg_value::unit_offset). evaluate_conditions_for_known_args bridged the two by simply dividing by BITS_PER_UNIT, which for a bit-field silently drops its sub-byte position and matches the constant recorded for the containing byte. The subsequent compatibility check only compares TYPE_SIZE, which is the mode size and therefore equal for a narrow bit-field type and a char, so the whole byte is then reinterpreted as the field with a VIEW_CONVERT_EXPR. In the testcase a 3-bit signed bit-field holding 1 sits at bits 2..4 of a byte whose value is 4; the byte is reinterpreted as -4, the guard ((int) p.f3.f7) >= 0 folds to false, the guarded call edge gets a false predicate and edge_set_predicate turns it into __builtin_unreachable. Everything dominated by the guard is then removed, main loses its return statement and falls through into _start. Since ipa_argagg_value_list cannot represent a sub-byte position, skip the lookup altogether when the condition is not byte aligned. Boostrap and regtest running on x86_64-unknown-linux-gnu. OK if that succeeds? Thanks, Richard. PR ipa/126153 * ipa-fnsummary.cc (evaluate_conditions_for_known_args): Do not look up an aggregate value for a condition whose offset is not byte aligned. * gcc.dg/torture/pr126153.c: New test. Assisted-By: Claude Opus 5 --- gcc/ipa-fnsummary.cc | 6 ++- gcc/testsuite/gcc.dg/torture/pr126153.c | 52 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr126153.c diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc index a6ccdb1852a..5ce4fb8bdc5 100644 --- a/gcc/ipa-fnsummary.cc +++ b/gcc/ipa-fnsummary.cc @@ -417,7 +417,11 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, if (tree sval = avals->safe_sval_at (c->operand_num)) val = ipa_find_agg_cst_from_init (sval, c->offset, c->by_ref); - if (!val) + /* ipa_argagg_value_list is indexed by byte offsets, so a condition + which does not start at a byte boundary (a bit-field) cannot be + looked up in it; the containing byte would be reinterpreted as + the whole field below. */ + if (!val && (c->offset % BITS_PER_UNIT) == 0) { ipa_argagg_value_list avs (avals); val = avs.get_value (c->operand_num, c->offset / BITS_PER_UNIT, diff --git a/gcc/testsuite/gcc.dg/torture/pr126153.c b/gcc/testsuite/gcc.dg/torture/pr126153.c new file mode 100644 index 00000000000..af37f47eef5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr126153.c @@ -0,0 +1,52 @@ +/* { dg-do run { target le } } */ +/* { dg-require-effective-target int32plus } */ +/* { dg-options "-O2" } */ + +/* Conditions of IPA predicates record the position of an aggregate load as + a bit offset, while the aggregate values of jump functions are indexed by + byte offsets. Truncating the former used to match the constant recorded + for the byte containing the bit-field, which was then reinterpreted with + a VIEW_CONVERT_EXPR as if it were the whole field. Here that turned the + value 1 of f7 into -4, the guard below into a false predicate and the + call to shifter() into __builtin_unreachable. */ + +struct S0 { unsigned f5 : 2; signed f7 : 3; unsigned f6 : 3; }; +struct S1 { int a; struct S0 f3; char pad; short s; }; + +int g; + +__attribute__((noipa)) void ext (int x) { g += x; } + +__attribute__((noinline, noclone)) static long +shifter (long l, int r) +{ + if (l < 0 || r < 0 || r >= 32 || l > (0x7fffffffffffffffL >> r)) + return l; + return l << r; +} + +static void +callee (struct S1 p, int n) +{ + ext (n); + if ((int) p.f3.f7 >= 0) + ext ((int) shifter (0x350631DD6B880108LL, (int) p.f3.f7)); + ext (n); +} + +/* A second caller, so that callee is not inlined before IPA. */ +void other (struct S1 q, int n) { callee (q, n); } + +int +main (void) +{ + struct S1 l; + l.a = 5; + l.pad = 7; + l.s = 9; + *(char *) &l.f3 = 4; /* f5 = 0, f7 = 1, f6 = 0 */ + callee (l, 3); + if (g != 3 + 3 + (int) (0x350631DD6B880108LL << 1)) + __builtin_abort (); + return 0; +}