1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand %s | FileCheck %s
4 define fp128 @test_atomicrmw_xchg_fp128_global_agent(ptr addrspace(1) %ptr, fp128 %value) {
5 ; CHECK-LABEL: @test_atomicrmw_xchg_fp128_global_agent(
6 ; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
7 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast fp128 [[VALUE:%.*]] to i128
8 ; CHECK-NEXT: [[TMP3:%.*]] = call i128 @__atomic_exchange_16(ptr [[TMP1]], i128 [[TMP2]], i32 5)
9 ; CHECK-NEXT: [[TMP4:%.*]] = bitcast i128 [[TMP3]] to fp128
10 ; CHECK-NEXT: ret fp128 [[TMP4]]
12 %res = atomicrmw xchg ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
16 define fp128 @test_atomicrmw_fadd_fp128_global_agent(ptr addrspace(1) %ptr, fp128 %value) {
17 ; CHECK-LABEL: @test_atomicrmw_fadd_fp128_global_agent(
18 ; CHECK-NEXT: [[TMP1:%.*]] = alloca fp128, align 8, addrspace(5)
19 ; CHECK-NEXT: [[TMP2:%.*]] = load fp128, ptr addrspace(1) [[PTR:%.*]], align 16
20 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
21 ; CHECK: atomicrmw.start:
22 ; CHECK-NEXT: [[LOADED:%.*]] = phi fp128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
23 ; CHECK-NEXT: [[NEW:%.*]] = fadd fp128 [[LOADED]], [[VALUE:%.*]]
24 ; CHECK-NEXT: [[TMP3:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
25 ; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
26 ; CHECK-NEXT: store fp128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
27 ; CHECK-NEXT: [[TMP4:%.*]] = bitcast fp128 [[NEW]] to i128
28 ; CHECK-NEXT: [[TMP5:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP3]], ptr addrspace(5) [[TMP1]], i128 [[TMP4]], i32 5, i32 5)
29 ; CHECK-NEXT: [[TMP6:%.*]] = load fp128, ptr addrspace(5) [[TMP1]], align 8
30 ; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
31 ; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { fp128, i1 } poison, fp128 [[TMP6]], 0
32 ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { fp128, i1 } [[TMP7]], i1 [[TMP5]], 1
33 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { fp128, i1 } [[TMP8]], 1
34 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { fp128, i1 } [[TMP8]], 0
35 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
36 ; CHECK: atomicrmw.end:
37 ; CHECK-NEXT: ret fp128 [[NEWLOADED]]
39 %res = atomicrmw fadd ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
43 define fp128 @test_atomicrmw_fsub_fp128_global_agent(ptr addrspace(1) %ptr, fp128 %value) {
44 ; CHECK-LABEL: @test_atomicrmw_fsub_fp128_global_agent(
45 ; CHECK-NEXT: [[TMP1:%.*]] = alloca fp128, align 8, addrspace(5)
46 ; CHECK-NEXT: [[TMP2:%.*]] = load fp128, ptr addrspace(1) [[PTR:%.*]], align 16
47 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
48 ; CHECK: atomicrmw.start:
49 ; CHECK-NEXT: [[LOADED:%.*]] = phi fp128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
50 ; CHECK-NEXT: [[NEW:%.*]] = fsub fp128 [[LOADED]], [[VALUE:%.*]]
51 ; CHECK-NEXT: [[TMP3:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
52 ; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
53 ; CHECK-NEXT: store fp128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
54 ; CHECK-NEXT: [[TMP4:%.*]] = bitcast fp128 [[NEW]] to i128
55 ; CHECK-NEXT: [[TMP5:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP3]], ptr addrspace(5) [[TMP1]], i128 [[TMP4]], i32 5, i32 5)
56 ; CHECK-NEXT: [[TMP6:%.*]] = load fp128, ptr addrspace(5) [[TMP1]], align 8
57 ; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
58 ; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { fp128, i1 } poison, fp128 [[TMP6]], 0
59 ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { fp128, i1 } [[TMP7]], i1 [[TMP5]], 1
60 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { fp128, i1 } [[TMP8]], 1
61 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { fp128, i1 } [[TMP8]], 0
62 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
63 ; CHECK: atomicrmw.end:
64 ; CHECK-NEXT: ret fp128 [[NEWLOADED]]
66 %res = atomicrmw fsub ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
70 define fp128 @test_atomicrmw_fmin_fp128_global_agent(ptr addrspace(1) %ptr, fp128 %value) {
71 ; CHECK-LABEL: @test_atomicrmw_fmin_fp128_global_agent(
72 ; CHECK-NEXT: [[TMP1:%.*]] = alloca fp128, align 8, addrspace(5)
73 ; CHECK-NEXT: [[TMP2:%.*]] = load fp128, ptr addrspace(1) [[PTR:%.*]], align 16
74 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
75 ; CHECK: atomicrmw.start:
76 ; CHECK-NEXT: [[LOADED:%.*]] = phi fp128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
77 ; CHECK-NEXT: [[TMP3:%.*]] = call fp128 @llvm.minnum.f128(fp128 [[LOADED]], fp128 [[VALUE:%.*]])
78 ; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
79 ; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
80 ; CHECK-NEXT: store fp128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
81 ; CHECK-NEXT: [[TMP5:%.*]] = bitcast fp128 [[TMP3]] to i128
82 ; CHECK-NEXT: [[TMP6:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP4]], ptr addrspace(5) [[TMP1]], i128 [[TMP5]], i32 5, i32 5)
83 ; CHECK-NEXT: [[TMP7:%.*]] = load fp128, ptr addrspace(5) [[TMP1]], align 8
84 ; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
85 ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { fp128, i1 } poison, fp128 [[TMP7]], 0
86 ; CHECK-NEXT: [[TMP9:%.*]] = insertvalue { fp128, i1 } [[TMP8]], i1 [[TMP6]], 1
87 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { fp128, i1 } [[TMP9]], 1
88 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { fp128, i1 } [[TMP9]], 0
89 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
90 ; CHECK: atomicrmw.end:
91 ; CHECK-NEXT: ret fp128 [[NEWLOADED]]
93 %res = atomicrmw fmin ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
97 define fp128 @test_atomicrmw_fmax_fp128_global_agent(ptr addrspace(1) %ptr, fp128 %value) {
98 ; CHECK-LABEL: @test_atomicrmw_fmax_fp128_global_agent(
99 ; CHECK-NEXT: [[TMP1:%.*]] = alloca fp128, align 8, addrspace(5)
100 ; CHECK-NEXT: [[TMP2:%.*]] = load fp128, ptr addrspace(1) [[PTR:%.*]], align 16
101 ; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
102 ; CHECK: atomicrmw.start:
103 ; CHECK-NEXT: [[LOADED:%.*]] = phi fp128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ]
104 ; CHECK-NEXT: [[TMP3:%.*]] = call fp128 @llvm.maxnum.f128(fp128 [[LOADED]], fp128 [[VALUE:%.*]])
105 ; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
106 ; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
107 ; CHECK-NEXT: store fp128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
108 ; CHECK-NEXT: [[TMP5:%.*]] = bitcast fp128 [[TMP3]] to i128
109 ; CHECK-NEXT: [[TMP6:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP4]], ptr addrspace(5) [[TMP1]], i128 [[TMP5]], i32 5, i32 5)
110 ; CHECK-NEXT: [[TMP7:%.*]] = load fp128, ptr addrspace(5) [[TMP1]], align 8
111 ; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
112 ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { fp128, i1 } poison, fp128 [[TMP7]], 0
113 ; CHECK-NEXT: [[TMP9:%.*]] = insertvalue { fp128, i1 } [[TMP8]], i1 [[TMP6]], 1
114 ; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { fp128, i1 } [[TMP9]], 1
115 ; CHECK-NEXT: [[NEWLOADED]] = extractvalue { fp128, i1 } [[TMP9]], 0
116 ; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
117 ; CHECK: atomicrmw.end:
118 ; CHECK-NEXT: ret fp128 [[NEWLOADED]]
120 %res = atomicrmw fmax ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst