public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/101145] niter analysis fails for until-wrap condition Date: Wed, 01 Dec 2021 19:59:52 +0000 [thread overview] Message-ID: <bug-101145-4-XNrzxKczyJ@http.gcc.gnu.org/bugzilla/> (raw) In-Reply-To: <bug-101145-4@http.gcc.gnu.org/bugzilla/> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101145 --- Comment #11 from CVS Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>: https://gcc.gnu.org/g:de3e5aae6c4b540e808c822c1e878b0a3304d09c commit r12-5699-gde3e5aae6c4b540e808c822c1e878b0a3304d09c Author: Roger Sayle <roger@nextmovesoftware.com> Date: Wed Dec 1 19:58:40 2021 +0000 Final value replacement improvements for until-wrap loops. This middle-end patch is inspired by the Richard Beiner's until-wrap loop example in PR tree-optimization/101145. unsigned foo(unsigned val, unsigned start) { unsigned cnt = 0; for (unsigned i = start; i > val; ++i) cnt++; return cnt; } For this loop, the tree optimizers currently generate: unsigned int foo (unsigned int val, unsigned int start) { unsigned int cnt; unsigned int _1; unsigned int _5; <bb 2> [local count: 118111600]: if (start_3(D) > val_4(D)) goto <bb 3>; [89.00%] else goto <bb 4>; [11.00%] <bb 3> [local count: 105119324]: _1 = start_3(D) + 1; _5 = -start_3(D); cnt_2 = _1 > val_4(D) ? _5 : 1; <bb 4> [local count: 118111600]: # cnt_11 = PHI <cnt_2(3), 0(2)> return cnt_11; } or perhaps slightly easier to read: if (start > val) { cnt = (start+1) > val ? -start : 1; } else cnt = 0; In this snippet, if we know start > val, then (start+1) > val unless start+1 overflows, i.e. (start+1) == 0 and start == ~0. We can use this (loop header) context to simplify the ternary expression to "(start != -1) ? -start : 1", which with a little help from match.pd can be folded to -start. Hence the optimal final value replacement should be: cnt = (start > val) ? -start : 0; Or as now generated by this patch: unsigned int foo (unsigned int val, unsigned int start) { unsigned int cnt; <bb 2> [local count: 118111600]: if (start_3(D) > val_4(D)) goto <bb 3>; [89.00%] else goto <bb 4>; [11.00%] <bb 3> [local count: 105119324]: cnt_2 = -start_3(D); <bb 4> [local count: 118111600]: # cnt_11 = PHI <cnt_2(3), 0(2)> return cnt_11; } We can also improve until-wrap loops that don't have a (suitable) loop header, as determined by simplify_using_initial_conditions. unsigned bar(unsigned val, unsigned start) { unsigned cnt = 0; unsigned i = start; do { cnt++; i++; } while (i > val); return cnt; } which is currently optimized to: unsigned int foo (unsigned int val, unsigned int start) { unsigned int cnt; unsigned int _9; unsigned int _10; <bb 2> [local count: 118111600]: _9 = start_4(D) + 1; _10 = -start_4(D); cnt_3 = val_7(D) < _9 ? _10 : 1; return cnt_3; } Here we have "val < (start+1) ? -start : 1", which again with the help of match.pd can be slightly simplified to "val <= start ? -start : 1" when dealing with unsigned types, because at the complicating value where start == ~0, we fortunately have -start == 1, hence it doesn't matter whether the second or third operand of the ternary operator is returned. To summarize, this patch (in addition to tweaking may_be_zero in number_of_iterations_until_wrap) adds three new constant folding transforms to match.pd. X != C1 ? -X : C2 simplifies to -X when -C1 == C2. which is the generalized form of the simplification above. X != C1 ? ~X : C2 simplifies to ~X when ~C1 == C2. which is the BIT_NOT_EXPR analog of the NEGATE_EXPR case. and the "until-wrap final value replacement without context": (X + 1) > Y ? -X : 1 simplifies to X >= Y ? -X : 1 when X is unsigned, as when X + 1 overflows, X is -1, so -X == 1. 2021-12-01 Roger Sayle <roger@nextmovesoftware.com> Richard Biener <rguenther@suse.de> gcc/ChangeLog * tree-ssa-loop-niter.c (number_of_iterations_until_wrap): Check if simplify_using_initial_conditions allows us to simplify the expression for may_be_zero. * match.pd (X != C ? -X : -C -> -X): New transform. (X != C ? ~X : ~C -> ~X): Likewise. ((X+1) > Y ? -X : 1 -> X >= Y ? -X : 1): Likewise. gcc/testsuite/ChangeLog * gcc.dg/fold-condneg-1.c: New test case. * gcc.dg/fold-condneg-2.c: New test case. * gcc.dg/fold-condnot-1.c: New test case. * gcc.dg/pr101145-1.c: New test case. * gcc.dg/pr101145-2.c: New test case.
prev parent reply other threads:[~2021-12-01 19:59 UTC|newest] Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-06-21 8:59 [Bug tree-optimization/101145] New: " rguenth at gcc dot gnu.org 2021-06-21 9:02 ` [Bug tree-optimization/101145] " rguenth at gcc dot gnu.org 2021-06-24 15:39 ` amker at gcc dot gnu.org 2021-06-25 1:28 ` guojiufu at gcc dot gnu.org 2021-06-25 1:34 ` amker at gcc dot gnu.org 2021-06-25 10:13 ` guojiufu at gcc dot gnu.org 2021-06-25 12:24 ` guojiufu at gcc dot gnu.org 2021-06-26 2:53 ` amker at gcc dot gnu.org 2021-07-01 3:42 ` guojiufu at gcc dot gnu.org 2021-08-25 8:39 ` cvs-commit at gcc dot gnu.org 2021-08-31 13:27 ` cvs-commit at gcc dot gnu.org 2021-09-17 10:01 ` marxin at gcc dot gnu.org 2021-12-01 19:59 ` cvs-commit at gcc dot gnu.org [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-101145-4-XNrzxKczyJ@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).