Skip to content

[Typed throws] Workaround for LLVM miscompile of unused swifterror, add executable test #69043

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

Merged

Conversation

kubamracek
Copy link
Contributor

While experimenting with typed throws, I discovered that on x86_64 and -Onone only, the IR that typed throws generates (which is identical to IR on arm64!) ends up getting lowered in a wrong way and the execution of the program ends up taking the wrong branch, this is demonstrated by the testcase added in this PR -- the "this cannot happen" call actually happens. I don't have the ability to diagnose the LLVM problem further, and so instead this PR adds a workaround to enable executable testing of typed throws. This PR also adds a simple executable test.


The following IR demonstrates the problem. When the following is built for x86_64 under -O0…

target triple = "x86_64-apple-macosx14.0.0"
declare swiftcc i64 @throwing(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable(8) %1)
define swiftcc void @catching() {
entry:
  %swifterror = alloca swifterror ptr, align 8
  store ptr null, ptr %swifterror, align 8
  %0 = call swiftcc i64 @throwing(ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable(8) %swifterror)
  %1 = load ptr, ptr %swifterror, align 8
  %2 = icmp ne ptr %1, null
  br i1 %2, label %catch, label %continue
catch:
  ; %dummy_use = ptrtoint ptr %1 to i64    ; UNCOMMENT THIS TO GET CORRECT OUTPUT
  br label %ret
continue:
  br label %ret
ret:
  ret void
}

…it produces this machine code:

] ../llvm-macosx-arm64/bin/llc -O0 x86.ll -o -
_catching:                              ## @catching
	pushq	%r13
	pushq	%r12
	pushq	%rax
	xorl	%eax, %eax
	movl	%eax, %r12d
	callq	_throwing
	cmpq	$0, (%rsp)
	je	LBB0_2

Notice that the cmp is comparing (%rsp), which is a miscompile -- swifterror is expected to be in r12. Interestingly, this only happens if there is no use of %1 in the catch block in the IR, and even a dummy unused instruction that just ends up using %1 suddenly makes the output correct.

@kubamracek
Copy link
Contributor Author

@swift-ci please test

@kubamracek
Copy link
Contributor Author

@swift-ci please test Windows platform

@kubamracek kubamracek merged commit b9150ab into swiftlang:main Oct 8, 2023
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.

2 participants