[Bug tree-optimization/101701] GCC optimization and code generation for if-else chains vs ternary chains vs a switch

2021-08-03 Thread marxin at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101701

Martin Liška  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #5 from Martin Liška  ---
(In reply to Andrew Pinski from comment #2)
> So the problem here is iftoswitch should ignore if it is profitable to
> convert the ifs to a switch statement (unless there are only two ifs) and
> then allow the switchlower pass to lower the switch again.

This was my original intention, but Jakub wanted to make the if-to-switch
transformation
only conditionally based on the ability to make a jump table or a bit-test.
Reason is that
some optimization passes work only on series of gimple conditions.

> 
> So x86 we get:
> ;; Canonical GIMPLE case clusters: 1 2 3 4 
> For foo
> and then for bar:
> ;; Canonical GIMPLE case clusters: 1 2 3 4 
> ;; BT can be built: BT(values:4 comparisons:8 range:4 density: 200.00%):1-4 
> /app/example.cpp:10:21: optimized: Condition chain with 4 BBs transformed
> into a switch statement.

In my case, it's not transformed as we do JT at least for 5 cases:

unsigned int
default_case_values_threshold (void)
{
  return (targetm.have_casesi () ? 4 : 5);
}

That's why you see a different codegen on ARM target.

[Bug tree-optimization/101701] GCC optimization and code generation for if-else chains vs ternary chains vs a switch

2021-07-30 Thread llvm at rifkin dot dev via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101701

--- Comment #4 from Jeremy R.  ---
I see with gcc x86_64 it does get the fold correct if another term (val == 5)
is added to the if-else chain: https://godbolt.org/z/TE15Wf1bo.

[Bug tree-optimization/101701] GCC optimization and code generation for if-else chains vs ternary chains vs a switch

2021-07-30 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101701

Andrew Pinski  changed:

   What|Removed |Added

 Depends on||94566

--- Comment #3 from Andrew Pinski  ---
Oh yes PR 94566.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94566
[Bug 94566] conversion between std::strong_ordering and int

[Bug tree-optimization/101701] GCC optimization and code generation for if-else chains vs ternary chains vs a switch

2021-07-30 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101701

Andrew Pinski  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Last reconfirmed||2021-07-30
 Status|UNCONFIRMED |NEW
   Severity|normal  |enhancement

--- Comment #2 from Andrew Pinski  ---
So the problem here is iftoswitch should ignore if it is profitable to convert
the ifs to a switch statement (unless there are only two ifs) and then allow
the switchlower pass to lower the switch again.

I thought there was a bug about this already too.

What is interesting is that the cost for ifs are so high on arm target
(compared to a switch), we end up with the best code already:
foo(int):
subsr3, r0, #1
cmp r3, #3
it  hi
movhi   r0, #-1
bx  lr
bar(int):
subsr3, r0, #1
cmp r3, #3
it  hi
movhi   r0, #-1
bx  lr
baz(int):
subsr3, r0, #1
cmp r3, #4
it  cs
movcs   r0, #-1
bx  lr

:)

So x86 we get:
;; Canonical GIMPLE case clusters: 1 2 3 4 
For foo
and then for bar:
;; Canonical GIMPLE case clusters: 1 2 3 4 
;; BT can be built: BT(values:4 comparisons:8 range:4 density: 200.00%):1-4 
/app/example.cpp:10:21: optimized: Condition chain with 4 BBs transformed into
a switch statement.

[Bug tree-optimization/101701] GCC optimization and code generation for if-else chains vs ternary chains vs a switch

2021-07-30 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101701

--- Comment #1 from Andrew Pinski  ---
int foo(int val) {
if (val == 1) return val; 
else if(val == 2) return val;
else if(val == 3) return val;
else if(val == 4) return val;
else return -1;
}

int bar(int val) {
return val == 1 ? val :
  (val == 2 ? val :
  (val == 3 ? val :
  (val == 4 ? val : -1)));
}

int baz(int val) {
switch(val) {
case 1:
case 2:
case 3:
case 4:
return val;
default:
return -1;
}
}