This is an archive of the discontinued LLVM Phabricator instance.

[CodeGen][Darwin] Set the calling-convention of a thread-local variable initialization function to fix calling-convention mismatch
ClosedPublic

Authored by ahatanak on May 24 2018, 6:01 PM.

Details

Summary

There is a bug in IRGen where the calling convention of initialization functions for thread-local static members of c++ template classes isn't set. This caused InstCombine to remove a call to an initialization function because of the mismatch in the calling conventions between the initialization function and the call.

For example, when the following piece of code (this is in test/CodeGenCXX/cxx11-thread-local.cpp) is compiled,

int g();
template<typename T> struct V { static thread_local int m; };
template<typename T> thread_local int V<T>::m = g();
int e = V<int>::m;

IRGen generates the following IR:

@_ZTHN1VIiE1mE = linkonce_odr alias void (), void ()* @__cxx_global_var_init.9

define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1VIiE1mE() #2 {
  call cxx_fast_tlscc void @_ZTHN1VIiE1mE() ; this calls @__cxx_global_var_init.9
  ret i32* @_ZN1VIiE1mE
}

; this function is missing the calling convention "cxx_fast_tlscc".

define internal void @__cxx_global_var_init.9() #0 section "__TEXT,__StaticInit,regular,pure_instructions" {
  ...
}

To fix the bug, this patch sets the calling convention of the initialization functions to 'cxx_fast_tlscc'. Alternatively, I could remove 'cxx_fast_tlscc' from the call instruction, but I suppose we don't want to do so for performance reasons.

rdar://problem/40447463

Diff Detail

Repository
rL LLVM

Event Timeline

ahatanak created this revision.May 24 2018, 6:01 PM
rjmccall accepted this revision.May 24 2018, 8:09 PM

LGTM.

This revision is now accepted and ready to land.May 24 2018, 8:09 PM
This revision was automatically updated to reflect the committed changes.