[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