| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt -S -mtriple=amdgpu9.00-amd-amdhsa -passes=infer-address-spaces < %s | FileCheck %s | |
| ; An addrspacecast from flat that is folded into a constant expression is a | |
| ; root, the same as an addrspacecast instruction. So the pass finds the flat | |
| ; address expression in any operand, not only in the pointer operand of a memory | |
| ; access. | |
| @lds = addrspace(3) global [4 x i32] poison | |
| declare void @use_local(ptr addrspace(3)) | |
| declare void @use_local_local(ptr addrspace(3), ptr addrspace(3)) | |
| define void @call_operand() { | |
| ; CHECK-LABEL: define void @call_operand() { | |
| ; CHECK-NEXT: call void @use_local(ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) @lds, i64 4)) | |
| ; CHECK-NEXT: ret void | |
| ; | |
| call void @use_local(ptr addrspace(3) addrspacecast (ptr getelementptr inbounds (i8, ptr addrspacecast (ptr addrspace(3) @lds to ptr), i64 4) to ptr addrspace(3))) | |
| ret void | |
| } | |
| define void @nested_call_operand() { | |
| ; CHECK-LABEL: define void @nested_call_operand() { | |
| ; CHECK-NEXT: call void @use_local(ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) @lds, i64 4), i32 4)) | |
| ; CHECK-NEXT: ret void | |
| ; | |
| call void @use_local(ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) addrspacecast (ptr getelementptr inbounds (i8, ptr addrspacecast (ptr addrspace(3) @lds to ptr), i64 4) to ptr addrspace(3)), i32 4)) | |
| ret void | |
| } | |
| define void @stored_value(ptr addrspace(1) %out) { | |
| ; CHECK-LABEL: define void @stored_value( | |
| ; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) { | |
| ; CHECK-NEXT: store ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) @lds, i64 4), ptr addrspace(1) [[OUT]], align 4 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| store ptr addrspace(3) addrspacecast (ptr getelementptr inbounds (i8, ptr addrspacecast (ptr addrspace(3) @lds to ptr), i64 4) to ptr addrspace(3)), ptr addrspace(1) %out, align 4 | |
| ret void | |
| } | |
| define ptr addrspace(3) @phi_incoming(i1 %cond) { | |
| ; CHECK-LABEL: define ptr addrspace(3) @phi_incoming( | |
| ; CHECK-SAME: i1 [[COND:%.*]]) { | |
| ; CHECK-NEXT: [[ENTRY:.*]]: | |
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF:.*]], label %[[END:.*]] | |
| ; CHECK: [[IF]]: | |
| ; CHECK-NEXT: br label %[[END]] | |
| ; CHECK: [[END]]: | |
| ; CHECK-NEXT: [[PTR:%.*]] = phi ptr addrspace(3) [ getelementptr inbounds (i8, ptr addrspace(3) @lds, i64 4), %[[ENTRY]] ], [ @lds, %[[IF]] ] | |
| ; CHECK-NEXT: ret ptr addrspace(3) [[PTR]] | |
| ; | |
| entry: | |
| br i1 %cond, label %if, label %end | |
| if: | |
| br label %end | |
| end: | |
| %ptr = phi ptr addrspace(3) [ addrspacecast (ptr getelementptr inbounds (i8, ptr addrspacecast (ptr addrspace(3) @lds to ptr), i64 4) to ptr addrspace(3)), %entry ], [ @lds, %if ] | |
| ret ptr addrspace(3) %ptr | |
| } | |
| define void @two_casts_in_one_call() { | |
| ; CHECK-LABEL: define void @two_casts_in_one_call() { | |
| ; CHECK-NEXT: call void @use_local_local(ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) @lds, i64 4), ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) @lds, i64 8)) | |
| ; CHECK-NEXT: ret void | |
| ; | |
| call void @use_local_local(ptr addrspace(3) addrspacecast (ptr getelementptr inbounds (i8, ptr addrspacecast (ptr addrspace(3) @lds to ptr), i64 4) to ptr addrspace(3)), ptr addrspace(3) addrspacecast (ptr getelementptr inbounds (i8, ptr addrspacecast (ptr addrspace(3) @lds to ptr), i64 8) to ptr addrspace(3))) | |
| ret void | |
| } |