Skip to content

Add swiftcc attribute for runtime functions called from Swift #30938

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

Closed

Conversation

kateinoigakukun
Copy link
Member

@kateinoigakukun kateinoigakukun commented Apr 10, 2020

This change marks all functions called using swiftcc as swiftcc attribute.

Resolves SR-15188.

On most of architectures, C calling convention functions can be invoked using swiftcc.
However on WebAssembly, swiftcc invocation strictly requires callee function is swiftcc to match the number of parameters with arguments.

Reference: https://reviews.llvm.org/D76049

cc: @jckarter

EDIT: 2020-04-13 1:37 JST

Sorry for not explaining enough.

I mean that the all functions I changed are called using swiftcc by binaries built with currently shipped compilers.

For example,

@_silgen_name("foo")
func foo()

foo()

the code is represented in that LLVM IR

define i32 @main(i32, i8**) #0 {
entry:
  %2 = bitcast i8** %1 to i8*
  call swiftcc void @foo()
  ret i32 0
}

declare swiftcc void @foo() #0

As well as this example, the caller of functions that are defined with silgen_name attribute are called using swiftcc.
So I think we should define those functions with swiftcc attribute.

Especially on WebAssembly, these calling convention mismatches causes runtime error, so I want to correct the mismatches.

@compnerd
Copy link
Member

Doesn't this break backwards compatibility on macOS?

@kateinoigakukun
Copy link
Member Author

@compnerd As far as I know, C calling convention is compatible with swiftcc when not using swiftself or swifterror, so this doesn't break backward compatibility.

Copy link
Contributor

@jckarter jckarter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This absolutely breaks ABI compatibility even if you aren't using the special registers. Aside from using the special self and error registers, Swift functions have a higher threshold for number of return registers, and divide aggregates differently from the C calling convention. It is not generally safe to mix the Swift and C calling conventions. Why do you want to make this change?

@omochi
Copy link
Contributor

omochi commented Apr 12, 2020

@jckarter @kateinoigakukun

It's interesting.

Some swift code in standard library import runtime function by using @_silgen_name like here.

https://github.com/apple/swift/blob/0c9c901c94e7aa9c3df0c68b8825fc55d46f043e/stdlib/public/core/DebuggerSupport.swift#L261-L262

In my understanding, all name only declared functions are considered as swiftcc in swift compiler.

So, are these implementations generally unsafe currently?

Instead of defining runtime function as swiftcc,
we should introduce a way that declare functions as c convention in swift side.

Example:

@_silgen_name("swift_retainCount") @convention(c)
public func _getRetainCount(_ Value: AnyObject) -> UInt

@jckarter
Copy link
Contributor

Yes, it is a bug to use @_silgen_name to call a function with the C calling convention. C functions can be declared by importing the C declaration from a C header. In this case, it looks like _getRetainCount is only used in tests, so I would try removing the _getRetainCount declaration and updating the test to import swift_getRetainCount with a C header.

@jckarter
Copy link
Contributor

cc @dcci who added those _retainCount declarations. Are those used by the debugger or other tools in addition to stdlib tests?

For functions like swift_retainCount with only one register-size argument and return, changing them to swiftcc might be harmless if we need to keep the API around. I'd hesitate to change the calling convention more generally than that, though.

@MaxDesiatov
Copy link
Contributor

Per our discussion in https://forums.swift.org/t/calling-convention-mismatch-violations-between-runtime-stdlib-and-emitted-code/51975, it seems that this could still proceed? Or is there anything else that needs to be addressed?

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@MaxDesiatov
Copy link
Contributor

MaxDesiatov commented Sep 18, 2021

Requesting a review from @meg-gupta as an author of recent changes that caused some minor conflicts.

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test macOS platform

@MaxDesiatov
Copy link
Contributor

@kateinoigakukun could you have a look at the failing macOS test? That seems to persist after re-running CI

@kateinoigakukun
Copy link
Member Author

kateinoigakukun commented Oct 1, 2021

This PR contains some types of changes and is a little bit old now. I'm splitting this into small PRs, so close this for now.
e.g. #39119 #39546

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

Successfully merging this pull request may close these issues.

5 participants