Skip to content

Missed tail call optimization on undefined return value for all architectures #82387

@widlarizer

Description

@widlarizer

See compiler explorer to confirm it to affect x64, arm, aarch64, RISC-V clang, but not gcc, at -O3.

LLVM

TaillRecursionElimination.cpp does kick in and marks the call with tail, but sdag lowers it to PsuedoCALL. Interestingly, adding -fglobal-isel -mllvm -global-isel-abort=1 to AArch64 shows that with gisel, the IRTranslator turns tail call directly to BL, so it's not sdag-specific.

GCC

I believe gcc's TCO in this case to be correct even just based on the C language spec since when a function doesn't return a value, the function call expression's value is undefined

Reproducer

Build with -O3 with any gcc, any clang:

int i;
int bar(void);
int foo (void)
{
  if (i)
  {
    bar();
  }
}

Code has been reduced from Proc_1 calling Proc_7 in Dhrystone, where functions with prefix Proc_ for "procedure" have unspecified return value types, and therefore default to int (since C89) despite the original intention clearly being void. Nevertheless this stinky use case is probably rather common and worth addressing

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions