https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108844
Bug ID: 108844 Summary: sincos opportunity missed Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: tkoenig at gcc dot gnu.org Target Milestone: --- Two related test cases (which do the same, but are handled differently). This is code for calculating a Jacobian, a frequent task in solving non-linear systems of equations. (I am using C instead of Fortran because Fortran does not support fallthrough). $ cat a.c #include <math.h> void f1 (double x, double y, double f[2], double fjac[2][2], int flag) { switch (flag) { case 1: f[0] = x * y; f[1] = sin(x)*y*y; break; case 2: fjac[0][0] = y; fjac[1][0] = cos(x)*y*y; fjac[0][1] = x; fjac[1][1] = 2*sin(x)*y; break; case 3: f[0] = x * y; f[1] = sin(x)*y*y; fjac[0][0] = y; fjac[1][0] = cos(x)*y*y; fjac[0][1] = x; fjac[1][1] = 2*sin(x)*y; break; default: __builtin_unreachable(); } } $ cat b.c #include <math.h> void f1 (double x, double y, double f[2], double fjac[2][2], int flag) { switch (flag) { case 1: case 3: f[0] = x * y; f[1] = sin(x)*y*y; if (flag != 3) break; /* Fallthrough */ case 2: fjac[0][0] = y; fjac[1][0] = cos(x)*y*y; fjac[0][1] = x; fjac[1][1] = 2*sin(x)*y; break; default: __builtin_unreachable(); } } $ gcc -O3 -S a.c b.c a.s looks good for flag=3: leaq 64(%rsp), %rsi leaq 72(%rsp), %rdi movaps %xmm3, 48(%rsp) movsd %xmm1, 32(%rsp) movsd %xmm0, 24(%rsp) call sincos but the code for flag=2 looks like cmpl $2, %edx je .L2 [...] .L2: .cfi_restore_state movaps %xmm3, 32(%rsp) movsd %xmm1, 24(%rsp) movsd %xmm0, (%rsp) call cos movsd (%rsp), %xmm2 movq %xmm0, %rbx movapd %xmm2, %xmm0 call sin b.s generates no call to sincos: $ egrep '(sin|cos)' b.s call sin call sin call cos