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

Implement Intel HLE and RTM intrinsics #718

Open
gnzlbg opened this issue Apr 14, 2019 · 7 comments
Open

Implement Intel HLE and RTM intrinsics #718

gnzlbg opened this issue Apr 14, 2019 · 7 comments

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Apr 14, 2019

@mtak- mentioned _xbegin recently, we should probably expose them all via core::arch.

The Intel RTM (Restricted Transactional Memory) intrinsics (Intel Intrinsic Guide, clang header, CPUID: RTM, EAX=7, ECX=0: Extended Features, EBX=11):

  • void _xabort (const unsigned int imm8) (assert_instr(xabort), `llvm.x86.xabort)
  • unsigned int _xbegin (void) (assert_instr(xbegin), llvm.x86.xbegin, note: can return multiple times)
  • void _xend (void) (assert_instr(xend), llvm.x86.xend)
  • unsigned char _xtest (void) (assert_instr(xtest), llvm.x86.xtest)

We'd need to whitelist the rtm feature in rust-lang/rust as part of this.

I've asked on the LLVM bugzilla whether xbegin needs to be marked returns_twice: https://bugs.llvm.org/show_bug.cgi?id=41493, Craig Topper suggested on IRC to submit an LLVM patch to mark this intrinsic / clang intrinsic as returns_twice (cc @ctopper - hope I get the github id right), but @TNorthover mentioned that this might not be necessary or enough. We don't have to figure this out for the initial implementation, as @mtack- mentions, clang does not do this, but we should not forget about this issue.

@TNorthover
Copy link

I've done some more thinking, and I now don't think returns_twice is the right model at all. The only way the processor is getting back to the xbegin itself is via normal control flow that LLVM can see.

I think what we actually have is something akin to a call that might throw an exception. From LLVM's perspective, either the transaction eventually succeeds, in which case the xbegin has acted like a normal intrinsic call, or it fails, in which case execution proceeds from the landingpad as if nothing had happened.

Someone would need to investigate how well the existing landingpad actually fits in with what happens though. Key questions to answer will be

  1. Current landingpads in use provide two values to the handler. One is usually (but not always) in rax so should be good; is the other just harmlessly undef, or will its presence break things? Is it even needed?
  2. What registers are preserved through to the landingpad and how does LLVM know? It could either be special logic, or inherited from the assumptions about the preceding call.
  3. I think landingpads need a personality function right now, but there isn't really one here. As far as I know it's only used for unwinding metadata, which we also don't need. So perhaps the real issue here is to make sure we don't try to generate that metadata for RTM invokes.

xabort should probably be noreturn, though I don't think that would affect correctness; it'll just allow more dead code elimination.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Apr 14, 2019 via email

@Amanieu
Copy link
Member

Amanieu commented Apr 14, 2019

If _xabort is used outside of a transaction then it acts as a no-op, so it shouldn't return !.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Apr 14, 2019

Indeed, then it can't be noreturn.

@mtak-
Copy link
Contributor

mtak- commented Apr 14, 2019

@TNorthover
Copy link

Oops, it looks like I didn't investigate just what @llvm.x86.xbegin did properly. It's a slightly higher level wrapper over the xbegin instruction that does seem to re-merge both success and failure paths into its return value.

So returns_twice is looking a lot more sensible again for that particular intrinsic now (though I still think an invoke-like interface would be more powerful and natural).

@mtak-
Copy link
Contributor

mtak- commented Apr 14, 2019

@TNorthover What is special from an LLVM perspective about _xbegin?

IIUC xbegin is a lot like a read from volatile memory and then a branch based on the value read (was the transaction started or aborted). Even though we know it might take both branches, it's "as-if" only one were taken for any single call to _xbegin. Very much the same as the CPU speculating that it might take a certain branch, and then rolling that back when it realizes that it mispredicted the branch.

Centril added a commit to Centril/rust that referenced this issue Apr 18, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 18, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 18, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 18, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 18, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 18, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 18, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 19, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 19, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 19, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
Centril added a commit to Centril/rust that referenced this issue Apr 19, 2019
whitelist RTM x86 target cpu feature

This PR adds support for intels restricted transactional memory cpu feature. I mostly copied what was done for the [movbe](rust-lang#57999) feature.

rust-lang/stdarch#718
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