| ; 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 @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) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[TMP3:%.*]] = call [[LOAD_PTR_AFTER_STORE:%.*]] @[[LOAD_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 [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 1 |
| ; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 |
| ; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 0 |
| ; CHECK-NEXT: ret i32 [[TMP5]] |
| ; |
| 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) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP3:%.*]] = call [[VOLATILE_LOAD_PTR_AFTER_STORE:%.*]] @[[VOLATILE_LOAD_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 [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 1 |
| ; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 |
| ; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 0 |
| ; CHECK-NEXT: ret i32 [[TMP5]] |
| ; |
| 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]] { |
| ; 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) [[TMP0:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP2:%.*]] = call [[OPAQUE_READ_CALL_AFTER_STORE:%.*]] @[[OPAQUE_READ_CALL_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison) |
| ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[OPAQUE_READ_CALL_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 |
| 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) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]], ptr addrspace(5) noalias [[TMP2:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP4:%.*]] = call [[MEMCPY_AFTER_STORE:%.*]] @[[MEMCPY_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[TMP2]]) |
| ; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[MEMCPY_AFTER_STORE]] [[TMP4]], 0 |
| ; CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[TMP0]], align 4 |
| ; 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) |