blob: f35047d0ce643c5fc3a35b5d8e94cbd5eb036fce [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -mtriple=amdgpu7.00-amd-amdhsa -amdgpu-rewrite-out-arguments < %s | FileCheck %s
define i32 @load_out_ptr_after_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define i32 @load_out_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
store i32 0, ptr addrspace(5) %out
%load = load i32, ptr addrspace(5) %out
ret i32 %load
}
define i32 @callee_with_aliasing_args(ptr addrspace(5) %val, ptr addrspace(5) %other) {
; CHECK-LABEL: define i32 @callee_with_aliasing_args(
; CHECK-SAME: ptr addrspace(5) [[VAL:%.*]], ptr addrspace(5) [[OTHER:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OTHER]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
store i32 0, ptr addrspace(5) %val
%load = load i32, ptr addrspace(5) %other
ret i32 %load
}
define amdgpu_kernel void @caller_with_aliasing_args(ptr addrspace(1) %out) {
; CHECK-LABEL: define amdgpu_kernel void @caller_with_aliasing_args(
; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) {
; CHECK-NEXT: [[SLOT:%.*]] = alloca i32, align 4, addrspace(5)
; CHECK-NEXT: store i32 1, ptr addrspace(5) [[SLOT]], align 4
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @callee_with_aliasing_args(ptr addrspace(5) [[SLOT]], ptr addrspace(5) [[SLOT]])
; CHECK-NEXT: store i32 [[RESULT]], ptr addrspace(1) [[OUT]], align 4
; CHECK-NEXT: ret void
;
%slot = alloca i32, addrspace(5)
store i32 1, ptr addrspace(5) %slot
%result = call i32 @callee_with_aliasing_args(ptr addrspace(5) %slot, ptr addrspace(5) %slot)
store i32 %result, ptr addrspace(1) %out
ret void
}
define i32 @load_out_ptr_before_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define i32 @load_out_ptr_before_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
%load = load i32, ptr addrspace(5) %out
store i32 0, ptr addrspace(5) %out
ret i32 %load
}
define i32 @volatile_load_out_ptr_after_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define i32 @volatile_load_out_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
store i32 0, ptr addrspace(5) %out
%load = load volatile i32, ptr addrspace(5) %out
ret i32 %load
}
define i32 @atomic_load_out_ptr_before_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define i32 @atomic_load_out_ptr_before_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: [[LOAD:%.*]] = load atomic i32, ptr addrspace(5) [[OUT]] monotonic, align 4
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
%load = load atomic i32, ptr addrspace(5) %out monotonic, align 4
store i32 0, ptr addrspace(5) %out
ret i32 %load
}
define void @volatile_store_out_ptr(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @volatile_store_out_ptr(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store volatile i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: ret void
;
store volatile i32 0, ptr addrspace(5) %out
ret void
}
define void @atomic_store_out_ptr(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @atomic_store_out_ptr(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store atomic i32 0, ptr addrspace(5) [[OUT]] monotonic, align 4
; CHECK-NEXT: ret void
;
store atomic i32 0, ptr addrspace(5) %out monotonic, align 4
ret void
}
define void @atomic_store_out_ptr_after_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @atomic_store_out_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[OUT]] release, align 4
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
store atomic i32 1, ptr addrspace(5) %out release, align 4
ret void
}
define i32 @load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define i32 @load_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[PTR]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
store i32 0, ptr addrspace(5) %out
%load = load i32, ptr addrspace(5) %ptr
ret i32 %load
}
define i32 @volatile_load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define i32 @volatile_load_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(5) [[PTR]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
store i32 0, ptr addrspace(5) %out
%load = load volatile i32, ptr addrspace(5) %ptr
ret i32 %load
}
define i32 @atomic_load_acquire_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define i32 @atomic_load_acquire_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: [[LOAD:%.*]] = load atomic i32, ptr addrspace(5) [[PTR]] acquire, align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
store i32 0, ptr addrspace(5) %out
%load = load atomic i32, ptr addrspace(5) %ptr acquire, align 4
ret i32 %load
}
define i32 @atomic_load_monotonic_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define i32 @atomic_load_monotonic_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE:%.*]] @[[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE]] [[TMP3]], 1
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE]] [[TMP3]], 0
; CHECK-NEXT: ret i32 [[TMP5]]
;
store i32 0, ptr addrspace(5) %out
%load = load atomic i32, ptr addrspace(5) %ptr monotonic, align 4
ret i32 %load
}
define void @volatile_store_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define void @volatile_store_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: store volatile i32 1, ptr addrspace(5) [[PTR]], align 4
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
store volatile i32 1, ptr addrspace(5) %ptr
ret void
}
define void @atomic_store_release_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define void @atomic_store_release_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[PTR]] release, align 4
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
store atomic i32 1, ptr addrspace(5) %ptr release, align 4
ret void
}
define void @atomic_store_unordered_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define void @atomic_store_unordered_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[PTR]] unordered, align 4
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
store atomic i32 1, ptr addrspace(5) %ptr unordered, align 4
ret void
}
define void @opaque_read_call_after_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @opaque_read_call_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: call void @opaque_read()
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
call void @opaque_read()
ret void
}
define void @opaque_rw_call_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define void @opaque_rw_call_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: call void @opaque_rw_argmem(ptr addrspace(5) [[PTR]])
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
call void @opaque_rw_argmem(ptr addrspace(5) %ptr)
ret void
}
define void @opaque_call_after_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @opaque_call_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: call void @opaque()
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
call void @opaque()
ret void
}
define void @memcpy_after_store(ptr addrspace(5) %out, ptr addrspace(5) %src, ptr addrspace(5) noalias %dst) {
; CHECK-LABEL: define void @memcpy_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[SRC:%.*]], ptr addrspace(5) noalias [[DST:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) [[DST]], ptr addrspace(5) [[SRC]], i32 4, i1 false)
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) %dst, ptr addrspace(5) %src, i32 4, i1 false)
ret void
}
define void @memset_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define void @memset_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: call void @llvm.memset.p5.i32(ptr addrspace(5) [[PTR]], i8 0, i32 4, i1 false)
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
call void @llvm.memset.p5.i32(ptr addrspace(5) %ptr, i8 0, i32 4, i1 false)
ret void
}
define void @memset_noalias_ptr_after_store(ptr addrspace(5) noalias %out, ptr addrspace(5) noalias %ptr) {
; CHECK-LABEL: define void @memset_noalias_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) noalias [[TMP0:%.*]], ptr addrspace(5) noalias [[TMP1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[MEMSET_NOALIAS_PTR_AFTER_STORE:%.*]] @[[MEMSET_NOALIAS_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[MEMSET_NOALIAS_PTR_AFTER_STORE]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
call void @llvm.memset.p5.i32(ptr addrspace(5) %ptr, i8 0, i32 4, i1 false)
ret void
}
define i32 @load_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define i32 @load_ptr_before_store(
; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[LOAD_PTR_BEFORE_STORE:%.*]] @[[LOAD_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[LOAD_PTR_BEFORE_STORE]] [[TMP3]], 1
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[LOAD_PTR_BEFORE_STORE]] [[TMP3]], 0
; CHECK-NEXT: ret i32 [[TMP5]]
;
%load = load i32, ptr addrspace(5) %ptr
store i32 0, ptr addrspace(5) %out
ret i32 %load
}
define i32 @volatile_load_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define i32 @volatile_load_ptr_before_store(
; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[VOLATILE_LOAD_PTR_BEFORE_STORE:%.*]] @[[VOLATILE_LOAD_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_BEFORE_STORE]] [[TMP3]], 1
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_BEFORE_STORE]] [[TMP3]], 0
; CHECK-NEXT: ret i32 [[TMP5]]
;
%load = load volatile i32, ptr addrspace(5) %ptr
store i32 0, ptr addrspace(5) %out
ret i32 %load
}
define void @atomic_store_release_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
; CHECK-LABEL: define void @atomic_store_release_ptr_before_store(
; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE:%.*]] @[[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
store atomic i32 1, ptr addrspace(5) %ptr release, align 4
store i32 0, ptr addrspace(5) %out
ret void
}
define void @atomic_store_seq_cst_noalias_ptr_after_store(ptr addrspace(5) noalias %out, ptr addrspace(5) noalias %ptr) {
; CHECK-LABEL: define void @atomic_store_seq_cst_noalias_ptr_after_store(
; CHECK-SAME: ptr addrspace(5) noalias [[TMP0:%.*]], ptr addrspace(5) noalias [[TMP1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE:%.*]] @[[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
store atomic i32 1, ptr addrspace(5) %ptr seq_cst, align 4
ret void
}
define void @fence_release_after_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @fence_release_after_store(
; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[FENCE_RELEASE_AFTER_STORE:%.*]] @[[FENCE_RELEASE_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[FENCE_RELEASE_AFTER_STORE]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
fence release
ret void
}
define void @fence_seq_cst_after_store(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @fence_seq_cst_after_store(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: fence seq_cst
; CHECK-NEXT: ret void
;
store i32 0, ptr addrspace(5) %out
fence seq_cst
ret void
}
define void @store_cross_bb(ptr addrspace(5) %out) {
; CHECK-LABEL: define void @store_cross_bb(
; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
store i32 0, ptr addrspace(5) %out
br label %exit
exit:
ret void
}
declare void @opaque_read() memory(read)
declare void @opaque()
declare void @opaque_rw_argmem(ptr addrspace(5)) memory(argmem: readwrite)
declare void @llvm.memcpy.p5.p5.i32(ptr addrspace(5), ptr addrspace(5), i32, i1)
declare void @llvm.memset.p5.i32(ptr addrspace(5), i8, i32, i1)