mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-30 20:44:34 +00:00 
			
		
		
		
	 cde7e805ad
			
		
	
	
		cde7e805ad
		
			
		
	
	
	
	
		
			
			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.
		
	
			
		
			
				
	
	
		
			19 lines
		
	
	
		
			474 B
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			19 lines
		
	
	
		
			474 B
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // Check that pointers are casted to addrspace(0) before they are used
 | |
| 
 | |
| //@ compile-flags: --crate-type=rlib --target=amdgcn-amd-amdhsa -Ctarget-cpu=gfx900
 | |
| //@ needs-llvm-components: amdgpu
 | |
| //@ add-core-stubs
 | |
| #![feature(no_core)]
 | |
| #![no_core]
 | |
| 
 | |
| extern crate minicore;
 | |
| 
 | |
| // CHECK-LABEL: @ref_of_local
 | |
| // CHECK: [[alloca:%[0-9]]] = alloca
 | |
| // CHECK: %i = addrspacecast ptr addrspace(5) [[alloca]] to ptr
 | |
| #[no_mangle]
 | |
| pub fn ref_of_local(f: fn(&i32)) {
 | |
|     let i = 0;
 | |
|     f(&i);
 | |
| }
 |