public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "marxin at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/94779] Bad optimization of simple switch Date: Thu, 17 Dec 2020 13:36:26 +0000 [thread overview] Message-ID: <bug-94779-4-2K0MIWJsqj@http.gcc.gnu.org/bugzilla/> (raw) In-Reply-To: <bug-94779-4@http.gcc.gnu.org/bugzilla/> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94779 --- Comment #14 from Martin Liška <marxin at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #12) > So, for start I think we should do: > 1) query->range_of_expr (m_index_range, m_index_expr, swtch) > where query is address of gimple_ranger passed down from the caller > to figure out range of the index expression; case labels without > CASE_HIGH for > which m_index_range.contains_p (CASE_LOW (case)) is false can be ignored > for the optimization (well, handled the way it is better for the > optimization) > For CASE_HIGH labels, similarly query if the range overlaps the index > range. > Note, I don't remember exactly in which way the types of the index > expression > and of the case labels can differ, I believe all case labels have to have > the > same type, so probably for the computation of the range if it has > different > type from the case label ones, it needs to call something that would > emulate > the effect of conversion to that type (or vice versa?) > CCing Andrew for the range stuff Ok, I've just taken look at what EVRP pass does before SWITCHCONV pass is called. I see that EVRP can properly prune dead cases of a switch, but it's not perfect: int f1(unsigned x) { if (x == 2 || x == 3 || x >= 5) __builtin_unreachable (); switch (x) { case 0: return 1; case 1: return 2; case 2: return 3; case 3 ... 8: return 4; } } after VRP we end up with: switch (x_6(D)) <default: <L8> [INV], case 1: <L3> [INV], case 2: <L4> [INV], case 3 ... 4: <L5> [INV]> but case '3' is not pruned here. Similarly, I can imagine the following reduction: if (x >= 4 && x <= 9) __builtin_unreachable (); switch (x) { case 0: return 1; case 1: return 2; case 2: return 3; case 3 ... 10: return 4; } is not simplified to: switch (x_3(D)) <default: <L6> [INV], case 0: <L8> [INV], case 1: <L3> [INV], case 2: <L4> [INV], case 3 ... 10: <L5> [INV]> but I would expect: switch (x_3(D)) <default: <L6> [INV], case 0: <L8> [INV], case 1: <L3> [INV], case 2: <L4> [INV], case 3: <L5>, case 10: <L5> [INV]> Btw, EVRP knows the information: 4->8 x_3(D) : unsigned int [11, +INF] 4->9 x_3(D) : unsigned int [0, 0] 4->5 x_3(D) : unsigned int [1, 1] 4->6 x_3(D) : unsigned int [2, 2] 4->7 x_3(D) : unsigned int [3, 3][10, 10] The question is whether we want to make the transformation by EVRP? > 2) similarly, cases that refer to blocks which have EDGE_COUNT (bb->succs) > == 0 > && gimple_seq_unreachable_p (bb_seq (bb)) should be treated again like > cases > one shouldn't need to care about I've got a patch candidate for this. > 3) to handle the #c0 testcase in C (C++ already adds __builtin_unreachable), > handle also the case where case refers to block which has EDGE_COUNT > (bb->succs) and ends in GIMPLE_RETURN without expression in a function that > returns integral or pointer value (for simplicity) and has no statements > other than debug stmts or clobber stmts before it. Note, this case can't > be > treated completely like a UB case, there is no UB in C unless the caller > checks the return value, but it could be handled conditionally, as long as > the code we emit for that doesn't invoke UB in the function, we really > don't > care about the value we return to the caller. So e.g. if we are > considering > a linear function and other case labels return that linear value and some > return unspecified value, just use the linear function to cover those too. Likewise here, it's smart to return a random value for C when there's a missing return value. > 4) to be able to optimize the int f1(unsigned x) { if (x >= 3) > __builtin_unreachable(); > switch (x) { case 0: return 1; case 1: return 2; case 2: return 3; } } > testcase, we should for consideration virtually undo the evrp optimization > which removed the case 0: and replaced it with default: - here the handled > cases (that should include the really handled ones and ones that and the > UB ones (if the case is outside of range or __builtin_unreachable) cover > everything but one case, assume the default label is that for that single > case rather than handling anything else; similarly, if the whole range > is covered, ignore the default label This seems to me like a strange EVRP transformation :/
next prev parent reply other threads:[~2020-12-17 13:36 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-04-27 0:40 [Bug tree-optimization/94779] New: " gabravier at gmail dot com 2020-04-27 4:31 ` [Bug tree-optimization/94779] " marxin at gcc dot gnu.org 2020-04-27 4:35 ` gabravier at gmail dot com 2020-04-27 4:38 ` gabravier at gmail dot com 2020-04-27 4:46 ` marxin at gcc dot gnu.org 2020-04-27 5:47 ` gabravier at gmail dot com 2020-04-27 6:15 ` gabravier at gmail dot com 2020-04-27 6:47 ` rguenth at gcc dot gnu.org 2020-04-27 6:51 ` gabravier at gmail dot com 2020-05-06 15:08 ` jakub at gcc dot gnu.org 2020-05-06 15:12 ` marxin at gcc dot gnu.org 2020-05-06 15:24 ` jakub at gcc dot gnu.org 2020-12-15 13:35 ` jakub at gcc dot gnu.org 2020-12-15 15:02 ` amacleod at redhat dot com 2020-12-17 13:36 ` marxin at gcc dot gnu.org [this message] 2020-12-17 13:41 ` jakub at gcc dot gnu.org 2020-12-17 13:57 ` marxin at gcc dot gnu.org 2020-12-17 14:07 ` jakub at gcc dot gnu.org 2020-12-17 16:38 ` amacleod at redhat dot com 2020-12-18 12:07 ` marxin at gcc dot gnu.org 2020-12-18 12:18 ` jakub at gcc dot gnu.org 2020-12-18 12:30 ` marxin at gcc dot gnu.org 2020-12-18 14:35 ` amacleod at redhat dot com 2021-08-16 12:39 ` marxin at gcc dot gnu.org
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-94779-4-2K0MIWJsqj@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).