[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2024-02-03 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Andrew Pinski  changed:

   What|Removed |Added

 CC||b.buschinski at googlemail dot 
com

--- Comment #12 from Andrew Pinski  ---
*** Bug 113741 has been marked as a duplicate of this bug. ***

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2021-11-29 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Andrew Pinski  changed:

   What|Removed |Added

 CC||llvm at rifkin dot dev

--- Comment #11 from Andrew Pinski  ---
*** Bug 103072 has been marked as a duplicate of this bug. ***

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-12-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

--- Comment #10 from Jakub Jelinek  ---
That is just one specific special case, it can be anything else, like
case 7: p[14] = 1; break;
case 8: p[13] = 1; break;
case 9: p[12] = 1; break;
case 10: p[11] = 1; break;
etc.
I think there are advantages of doing this in switchconv, namely that it would
be done only if the switchconv pass finds out it would be beneficial, but there
can be advantages doing that in tail-merging too, mainly for -Os or proven cold
code it is often but not always to optimize this (not only if either the code
is very small or if between pre and switchconv we can simplify it if it is
constant).

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-12-14 Thread rguenther at suse dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

--- Comment #9 from rguenther at suse dot de  ---
On December 14, 2020 12:19:32 PM GMT+01:00, "jakub at gcc dot gnu.org"
 wrote:
>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245
>
>--- Comment #7 from Jakub Jelinek  ---
>Looking at godbolt and LLVM release notes, this optimization appeared
>in LLVM 9
>and looks to be a switch optimization:
>
>LLVM can now sink similar instructions to a common successor block also
>when
>the instructions have no uses, such as calls to void functions. This
>allows
>code such as
>
>void g(int);
>enum e { A, B, C, D };
>void f(e x, int y, int z) {
>  switch(x) {
>case A: g(6); break;
>case B: g(3); break;
>case C: g(9); break;
>case D: g(2); break;
>  }
>}
>
>to be optimized to a single call to g, with the argument loaded from a
>lookup
>table.
>I bet it is https://reviews.llvm.org/D59936
>
>We don't optimize even:
>void
>foo (int *p, int x)
>{
>  switch (x)
>{
>case 7: *p = 14; break;
>case 8: *p = 15; break;
>case 9: *p = 16; break;
>case 10: *p = 17; break;
>case 11: *p = 18; break;
>case 12: *p = 19; break;
>default: return;
>}
>}

Store commoning in the sink pass should do this. But it would need to create a
forwarder because of the default case. 
That's a missed piece there. 

>but do optimize if one performs the switch parametrized tail merging
>manually:
>void
>bar (int *p, int x)
>{
>  int y;
>  switch (x)
>{
>case 7: y = 14; break;
>case 8: y = 15; break;
>case 9: y = 16; break;
>case 10: y = 17; break;
>case 11: y = 18; break;
>case 12: y = 19; break;
>default: return;
>}
>  *p = y;
>}
>
>So, do you prefer to do this in tree-ssa-tail-merge.c (for blocks
>starting with
>switches) or in tree-switch-conversion.c, and should we handle both the
>case
>where the constant(s) are linear vs. the switch expression, or also any
>other
>(let the switchconv pass then create the arrays)?

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-12-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Jakub Jelinek  changed:

   What|Removed |Added

 CC||law at gcc dot gnu.org

--- Comment #8 from Jakub Jelinek  ---
Effectively it would be the inverse of jump threading optimization, though I
think we don't do it for switches, turning say:
void
foo (int *p, int x)
{
  switch (x)
{
case 7:
case 8:
case 9:
case 10:
case 11:
case 12: *p = 12 + x; break;
default: return;
}
}
into the above foo.

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-12-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

--- Comment #7 from Jakub Jelinek  ---
Looking at godbolt and LLVM release notes, this optimization appeared in LLVM 9
and looks to be a switch optimization:

LLVM can now sink similar instructions to a common successor block also when
the instructions have no uses, such as calls to void functions. This allows
code such as

void g(int);
enum e { A, B, C, D };
void f(e x, int y, int z) {
  switch(x) {
case A: g(6); break;
case B: g(3); break;
case C: g(9); break;
case D: g(2); break;
  }
}

to be optimized to a single call to g, with the argument loaded from a lookup
table.
I bet it is https://reviews.llvm.org/D59936

We don't optimize even:
void
foo (int *p, int x)
{
  switch (x)
{
case 7: *p = 14; break;
case 8: *p = 15; break;
case 9: *p = 16; break;
case 10: *p = 17; break;
case 11: *p = 18; break;
case 12: *p = 19; break;
default: return;
}
}
but do optimize if one performs the switch parametrized tail merging manually:
void
bar (int *p, int x)
{
  int y;
  switch (x)
{
case 7: y = 14; break;
case 8: y = 15; break;
case 9: y = 16; break;
case 10: y = 17; break;
case 11: y = 18; break;
case 12: y = 19; break;
default: return;
}
  *p = y;
}

So, do you prefer to do this in tree-ssa-tail-merge.c (for blocks starting with
switches) or in tree-switch-conversion.c, and should we handle both the case
where the constant(s) are linear vs. the switch expression, or also any other
(let the switchconv pass then create the arrays)?

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-12-14 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org,
   ||vries at gcc dot gnu.org

--- Comment #6 from Jakub Jelinek  ---
I think it isn't really a too special case, of course one shouldn't take it
literally and look for a particular call etc.
But, generally try to see if all the switch cases are the same except some
constant or two (same e.g. in the ICF sense) and if that constant or two is
linear vs. the corresponding case.
It can be done either in switchconv, or could be perhaps some kind of
GIMPLE_SWITCH aware parametrized tail merging/cross jumping.
As it would (or could) turn constant expressions into non-constant, I guess
we'd need to take some conservative approach with __builtin_constant_p, punt if
there is a __builtin_constant_p in the block, either altogether, or if it is
among (recursively) the immediate uses of the stmt where the constant(s)
appear.

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-09-22 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Martin Liška  changed:

   What|Removed |Added

 Status|ASSIGNED|NEW
   Assignee|marxin at gcc dot gnu.org  |unassigned at gcc dot 
gnu.org

--- Comment #5 from Martin Liška  ---
Leaving for now as it's probably not material for switch-coversion (I mean the
putchar test-case).

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-07-23 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Martin Liška  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |marxin at gcc dot 
gnu.org
 Status|NEW |ASSIGNED

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-07-20 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

--- Comment #4 from Martin Sebor  ---
Only (1) would be true.  Like the optimization, the warning wouldn't trigger in
code that didn't follow the pattern because there's no way to tell if that's
deliberate or a bug.

I'd expect the warning to be useful by discouraging a questionable pattern.  I
don't suppose this comes up a lot so like the optimization, the difference the
warning would make in practice can be debated.  Unlike the optimization alone,
though, it would lead to less repetitive and so more readable code.

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-07-20 Thread josephcsible at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Joseph C. Sible  changed:

   What|Removed |Added

 CC||josephcsible at gmail dot com

--- Comment #3 from Joseph C. Sible  ---
(In reply to Martin Sebor from comment #2)
> I wonder if discouraging this pattern by warning on it and suggesting the
> simpler alternative would be worthwhile (either in addition to or in lieu of
> the optimization) to help avoid typos resulting from copy-and-paste mistakes
> that cannot very well be detected.

I don't see how such a warning would be particularly useful in practice.
Wouldn't one of these two things have to be true?

1. It would only warn you when you used the typo-prone pattern but didn't
actually make any typos in it
2. The warning would trigger in code where the author intentionally breaks the
pattern for some cases

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-07-20 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Martin Sebor  changed:

   What|Removed |Added

 CC||msebor at gcc dot gnu.org

--- Comment #2 from Martin Sebor  ---
I wonder if discouraging this pattern by warning on it and suggesting the
simpler alternative would be worthwhile (either in addition to or in lieu of
the optimization) to help avoid typos resulting from copy-and-paste mistakes
that cannot very well be detected.  As in:

void f(int x)
{
switch (x)
{
case 0:
putchar('0');
break;
case 1:
putchar('1');
break;
...
case 7:
putchar('6');   <<< typo
break;
...
  }

[Bug tree-optimization/96245] Failure to optimize arithmetic pattern in switch

2020-07-20 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245

Richard Biener  changed:

   What|Removed |Added

   Last reconfirmed||2020-07-20
 CC||marxin at gcc dot gnu.org
   Keywords||missed-optimization
 Ever confirmed|0   |1
 Status|UNCONFIRMED |NEW

--- Comment #1 from Richard Biener  ---
switch-conversion(?), it does look like a very special case.  Similar:

int y;
void f(int x)
{
switch (x)
{
case 0:
  y = 0;
  break;
case 1:
  y = 1;
  break;
...

converting to  if (...) y = x;  or more general to x + CST.  The store
commoning patch should in this case sink this to y = PHI<...> where
switch-conversion would convert the PHI<...>.  For the putchar case
there's nothing "commoming" the call (the same code doing the store
sinking could also sink calls if we want that).  Not sure if
switch-conversion itself would want to do this (profitability increases
if we can eliminate the PHI<> by arithmetics).