Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Musttail calls do not work when compiling to x86 Windows #53271

Open
ngg opened this issue Jan 18, 2022 · 2 comments
Open

Musttail calls do not work when compiling to x86 Windows #53271

ngg opened this issue Jan 18, 2022 · 2 comments

Comments

@ngg
Copy link
Contributor

ngg commented Jan 18, 2022

Clang version in use: 13.0.0 (installed from Gentoo's package manager), but the problem is not Gentoo-specific and I could reproduce with current trunk as well. (Godbolt: https://gcc.godbolt.org/z/boxqK5r6d)

Compiling the following C++ code with clang++ -c -target i386-windows x.cpp fails with error in backend: failed to perform tail call elimination on a call site marked musttail error. When clang is compiled with assertions, the error message is musttail call must precede a ret with an optional bitcast.

// x.cpp
// clang++ -c -target i386-windows x.cpp
struct X {
  ~X();
  void f();
};

void g();

template <typename T>
struct Y {
  static void h()
  {
    X().f();
    [[clang::musttail]] return g();
  }
};

template struct Y<void>;

The reduced bugpoint-reduced-simplified.bc from running bugpoint -run-llc x.bc is uploaded here: https://web.tresorit.com/l/VVWGy#E9cy7Z9o6YakdQ_jmTsPPw

What happens is that the x86-winehstate LLVM pass inserts instructions between the musttail call and the ret instructions, which makes the code invalid.

IR dump before and after the x86-winehstate pass
*** IR Dump Before Windows 32-bit x86 EH state insertion (x86-winehstate) ***
define dso_local void @"?h@?$Y@X@@SAXXZ"() #0 comdat align 2 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  invoke x86_thiscallcc void @"?f@X@@QAEXXZ"()
          to label %1 unwind label %2

1:                                                ; preds = %0
  musttail call void @"?g@@YAXXZ"()
  ret void

2:                                                ; preds = %0
  %3 = cleanuppad within none []
  cleanupret from %3 unwind to caller
} 
*** IR Dump After Windows 32-bit x86 EH state insertion (x86-winehstate) ***
define dso_local void @"?h@?$Y@X@@SAXXZ"() #0 comdat align 2 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  %1 = alloca %CXXExceptionRegistration, align 4
  %2 = bitcast %CXXExceptionRegistration* %1 to i8*
  call void @llvm.x86.seh.ehregnode(i8* %2)
  %3 = call i8* @llvm.stacksave()
  %4 = getelementptr inbounds %CXXExceptionRegistration, %CXXExceptionRegistration* %1, i32 0, i32 0
  store i8* %3, i8** %4, align 4
  %5 = getelementptr inbounds %CXXExceptionRegistration, %CXXExceptionRegistration* %1, i32 0, i32 2
  store i32 -1, i32* %5, align 4
  %6 = getelementptr inbounds %CXXExceptionRegistration, %CXXExceptionRegistration* %1, i32 0, i32 1
  %7 = getelementptr inbounds %EHRegistrationNode, %EHRegistrationNode* %6, i32 0, i32 1
  store i8* bitcast (i32 (i8*, i8*, i8*, i8*)* @"__ehhandler$?h@?$Y@X@@SAXXZ" to i8*), i8** %7, align 4
  %8 = load %EHRegistrationNode*, %EHRegistrationNode* addrspace(257)* null, align 4
  %9 = getelementptr inbounds %EHRegistrationNode, %EHRegistrationNode* %6, i32 0, i32 0
  store %EHRegistrationNode* %8, %EHRegistrationNode** %9, align 4
  store %EHRegistrationNode* %6, %EHRegistrationNode* addrspace(257)* null, align 4
  %10 = getelementptr inbounds %CXXExceptionRegistration, %CXXExceptionRegistration* %1, i32 0, i32 2
  store i32 0, i32* %10, align 4
  invoke x86_thiscallcc void @"?f@X@@QAEXXZ"()
          to label %11 unwind label %16

11:                                               ; preds = %0
  %12 = getelementptr inbounds %CXXExceptionRegistration, %CXXExceptionRegistration* %1, i32 0, i32 2
  store i32 -1, i32* %12, align 4
  musttail call void @"?g@@YAXXZ"()
  %13 = getelementptr inbounds %CXXExceptionRegistration, %CXXExceptionRegistration* %1, i32 0, i32 1
  %14 = getelementptr inbounds %EHRegistrationNode, %EHRegistrationNode* %13, i32 0, i32 0
  %15 = load %EHRegistrationNode*, %EHRegistrationNode** %14, align 4
  store %EHRegistrationNode* %15, %EHRegistrationNode* addrspace(257)* null, align 4
  ret void

16:                                               ; preds = %0
  %17 = cleanuppad within none []
  cleanupret from %17 unwind to caller
} 
@llvmbot
Copy link
Member

llvmbot commented Jan 18, 2022

@llvm/issue-subscribers-backend-x86

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants
@ngg @EugeneZelenko @llvmbot and others