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

Cast allocas to default address space #135025

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Flakebi
Copy link
Contributor

@Flakebi Flakebi commented Jan 2, 2025

Pointers for variables all need to be in the same address space for correct compilation. Therefore ensure that even if an alloca is created in a different address space, it is casted to the default address space before its value is used.

This is necessary for the amdgpu target and others where the default address space for allocas is not 0.

For example the following code compiles incorrectly when not casting the address space to the default one:

fn f(p: *const i8 /* addrspace(0) */) -> *const i8 /* addrspace(0) */ {
    let local = 0i8; /* addrspace(5) */
    let res = if cond { p } else { &raw const local };
    res
}

results in

    %local = alloca addrspace(5) i8
    %res = alloca addrspace(5) ptr

if:
    ; Store 64-bit flat pointer
    store ptr %p, ptr addrspace(5) %res

else:
    ; Store 32-bit scratch pointer
    store ptr addrspace(5) %local, ptr addrspace(5) %res

ret:
    ; Load and return 64-bit flat pointer
    %res.load = load ptr, ptr addrspace(5) %res
    ret ptr %res.load

For amdgpu, addrspace(0) are 64-bit pointers, addrspace(5) are 32-bit pointers.
The above code may store a 32-bit pointer and read it back as a 64-bit pointer, which is obviously wrong and cannot work. Instead, we need to addrspacecast %local to ptr addrspace(0), then we store and load the correct type.

Tracking issue: #135024

Pointers for variables all need to be in the same address space for
correct compilation. Therefore ensure that even if an `alloca` is
created in a different address space, it is casted to the default
address space before its value is used.

This is necessary for the amdgpu target and others where the default
address space for `alloca`s is not 0.

For example the following code compiles incorrectly when not casting the
address space to the default one:

```rust
fn f(p: *const i8 /* addrspace(0) */) -> *const i8 /* addrspace(0) */ {
    let local = 0i8; /* addrspace(5) */
    let res = if cond { p } else { &raw const local };
    res
}
```

results in

```llvm
    %local = alloca addrspace(5) i8
    %res = alloca addrspace(5) ptr

if:
    ; Store 64-bit flat pointer
    store ptr %p, ptr addrspace(5) %res

else:
    ; Store 32-bit scratch pointer
    store ptr addrspace(5) %local, ptr addrspace(5) %res

ret:
    ; Load and return 64-bit flat pointer
    %res.load = load ptr, ptr addrspace(5) %res
    ret ptr %res.load
```

For amdgpu, `addrspace(0)` are 64-bit pointers, `addrspace(5)` are
32-bit pointers.
The above code may store a 32-bit pointer and read it back as a 64-bit
pointer, which is obviously wrong and cannot work. Instead, we need to
`addrspacecast %local to ptr addrspace(0)`, then we store and load the
correct type.
@rustbot
Copy link
Collaborator

rustbot commented Jan 2, 2025

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @compiler-errors (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 2, 2025
@Flakebi Flakebi mentioned this pull request Jan 2, 2025
12 tasks
@compiler-errors
Copy link
Member

Isn't this going to add a redundant addrspace cast for LLVM targets that don't care about this?

@Flakebi
Copy link
Contributor Author

Flakebi commented Jan 2, 2025

Isn't this going to add a redundant addrspace cast for LLVM targets that don't care about this?

No, LLVM checks itself if the cast is needed or not. So, if we checked this here, we would check twice in the case the cast is needed.

The code in LLVM is here:
https://github.com/llvm/llvm-project/blob/dd30aa83aa12e5b2b5e58cb72ec85070f725df34/llvm/include/llvm/IR/IRBuilder.h#L2201-L2204

The code for constant casts is here:
https://github.com/llvm/llvm-project/blob/dd30aa83aa12e5b2b5e58cb72ec85070f725df34/llvm/lib/IR/Instructions.cpp#L3041-L3042
(The Create(Instruction::BitCast, …) below is also a no-op if the types are already equal.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants