https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68390
Bug ID: 68390 Summary: Incorrect code due to indirect tail call of varargs function with hard float ABI Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: kugan at gcc dot gnu.org Target Milestone: --- __attribute__ ((noinline)) double direct(int x, ...) { return x*x; } __attribute__ ((noinline)) double broken(double (*indirect)(int x, ...), int v) { return indirect(v); } int main () { double d1, d2; int i = 2; d1 = broken (direct, i); if (d1 != i*i) { __builtin_abort (); } return 0; } Please note that we have a sibcall from "broken" to "indirect". "direct" is variadic function so it is conforming to AAPCS base standard. "broken" is a non-variadic function and will return the value in floating point register for TARGET_HARD_FLOAT. Thus we should not be doing sibcall here.