https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82405

            Bug ID: 82405
           Summary: Function not inlined for switch and suboptimal
                    assembly is generated
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: antoshkka at gmail dot com
  Target Milestone: ---

Following code 

enum class eShape { eSquare, eCircle, eShpere, eTetraeder };

static inline double eval_square(double r) { return 4 * r*r; }
static inline double eval_circle(double r) { return 3.1415 * r * r; }
static inline double eval_sphere(double r) { return 4 * 3.1415 * r * r; }
static inline double eval_tetraeder(double r) { return 24 * 1.73205 * r*r; }

double test_switch_native(eShape shape, double r) {
    switch(shape) {
    case eShape::eSquare:    return eval_square(r);
    case eShape::eCircle:    return eval_circle(r);
    case eShape::eShpere:    return eval_sphere(r);
    case eShape::eTetraeder: return eval_tetraeder(r);
    }
}

Produces very long suboptimal assembly output with -O2 and -O3.

Clang inlines the functions and merges the common `r*r` part:

test_switch_native(eShape, double):         # @test_switch_native(eShape,
double)
        movsxd  rax, edi
        movsd   xmm1, qword ptr [8*rax +
.Lswitch.table._Z18test_switch_native6eShaped] # xmm1 = mem[0],zero
        mulsd   xmm1, xmm0
        mulsd   xmm0, xmm1
        ret
.Lswitch.table._Z18test_switch_native6eShaped:
        .quad   4616189618054758400     # double 4
        .quad   4614256447914709615     # double 3.1415000000000002
        .quad   4623263647169450607     # double 12.566000000000001
        .quad   4631047162110439693     # double 41.569200000000002

Reply via email to