[Bug c++/82405] Function not inlined for switch and suboptimal assembly is generated
marxin at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Oct 3 08:03:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82405
Martin Liška <marxin at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |missed-optimization
Status|UNCONFIRMED |NEW
Last reconfirmed| |2017-10-03
CC| |jakub at gcc dot gnu.org,
| |marxin at gcc dot gnu.org,
| |rguenth at gcc dot gnu.org
Ever confirmed|0 |1
--- Comment #1 from Martin Liška <marxin at gcc dot gnu.org> ---
Confirmed, we also inline the function (-fdump-ipa-inline):
<bb 2> [100.00%]:
switch (shape_2(D)) <default: <L4> [20.00%], case 0: <L6> [20.00%], case 1:
<L7> [20.00%], case 2: <L8> [20.00%], case 3: <L9> [20.00%]>
<L6> [20.00%]:
_5 = r_4(D) * 4.0e+0;
_6 = r_4(D) * _5;
goto <bb 8>; [100.00%]
<L7> [20.00%]:
_7 = r_4(D) * 3.141500000000000181188397618825547397136688232421875e+0;
_8 = r_4(D) * _7;
goto <bb 8>; [100.00%]
<L8> [20.00%]:
_9 = r_4(D) * 1.25660000000000007247535904753021895885467529296875e+1;
_10 = r_4(D) * _9;
goto <bb 8>; [100.00%]
<L9> [20.00%]:
_11 = r_4(D) * 4.156920000000000214868123293854296207427978515625e+1;
_12 = r_4(D) * _11;
goto <bb 8>; [100.00%]
<L4> [20.00%]:
return;
<bb 8> [80.00%]:
# _1 = PHI <_6(3), _8(4), _10(5), _12(6)>
return _1;
there are probably 2 issues I see:
1) clang knowing that switch handles all enum values -> thus default branch is
removed:
$ clang++ -O2 pr82405.c -S -o/dev/stdout
_Z18test_switch_native6eShaped: # @_Z18test_switch_native6eShaped
.cfi_startproc
# BB#0:
movslq %edi, %rax
movsd .Lswitch.table(,%rax,8), %xmm1 # xmm1 = mem[0],zero
...
.Lswitch.table:
.quad 4616189618054758400 # double 4
.quad 4614256447914709615 # double 3.1415000000000002
.quad 4623263647169450607 # double 12.566000000000001
.quad 4631047162110439693 # double 41.569200000000002
.size .Lswitch.table, 32
Having a simpler test-case:
$ cat pr82405-2.c
enum class eShape { eSquare, eCircle, eShpere, eTetraeder };
double test_switch_native(eShape shape, double r) {
switch(shape) {
case eShape::eSquare: return 2;
case eShape::eCircle: return 3;
case eShape::eShpere: return 4;
case eShape::eTetraeder: return 5;
}
}
we're unable to process switch conversion because:
beginning to process the following SWITCH statement (pr82405-2.c:4) : -------
switch (shape_2(D)) <default: <L4> [0.00%], case 0: <L6> [0.00%], case 1: <L1>
[0.00%], case 2: <L2> [0.00%], case 3: <L3> [0.00%]>
Bailing out - no common successor to all case label target blocks found
I know that I discussed that with Jakub a bit, one can use | operator for enum
values, but I still believe we should optimize switch
statements where all enum values are handled. Thoughts?
2) predictive commoning is not triggered for similar reason (there's still
default edge not using r * r).
Thanks.
More information about the Gcc-bugs
mailing list