Skip to content

For tail calls, clang generates extra alloca for sret parameter on 32 bit targets #104794

@kiran-isaac

Description

@kiran-isaac

While running a fuzzer to verify #102896, I kept getting errors for any cases using double _Complex or _BitInt(n>64) as return types for [[clang::musttail]] functions on 32 bit targets. These cases would compile such that new memory is alloca'd for the sret parameter, rather than passing through the same sret ptr from the caller. For example

double _Complex F11(signed short P0);

double _Complex F12(signed short P0) {
  [[clang::musttail]] return F11(1000);
}
clang -S -emit-llvm --target=(arm/x86/any 32 bit target) -o - 

Gives you (see #104770 for more info about weird no predecessors block):

; Function Attrs: mustprogress noinline optnone
define dso_local arm_aapcscc void @_Z3F12s(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, i16 noundef signext %P0) #0 {
entry:
  %P0.addr = alloca i16, align 2
  %tmp = alloca { double, double }, align 8
  store i16 %P0, ptr %P0.addr, align 2
  %0 = load i16, ptr %P0.addr, align 2
  musttail call arm_aapcscc void @_Z3F11s(ptr dead_on_unwind writable sret({ double, double }) align 8 %tmp, i16 noundef signext %0)
  ret void

1:                                                ; No predecessors!
...
  ret void
}

This is an invalid tail call. Similar behaviour can be observed when replacing double _Complex with _BitInt(N>64).

Metadata

Metadata

Assignees

Labels

clang:codegenIR generation bugs: mangling, exceptions, etc.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions