Skip to content

Commit cf5ce8c

Browse files
committed
AMDGPU: Add some tests for i128 and fp128 atomic expansion
These produce garbage libcalls, so the result is not useful but this at least shows we don't assert.
1 parent 9cd3622 commit cf5ce8c

File tree

2 files changed

+323
-0
lines changed

2 files changed

+323
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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
3+
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]]
11+
;
12+
%res = atomicrmw xchg ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
13+
ret fp128 %res
14+
}
15+
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]]
38+
;
39+
%res = atomicrmw fadd ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
40+
ret fp128 %res
41+
}
42+
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]]
65+
;
66+
%res = atomicrmw fsub ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
67+
ret fp128 %res
68+
}
69+
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]]
92+
;
93+
%res = atomicrmw fmin ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
94+
ret fp128 %res
95+
}
96+
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]]
119+
;
120+
%res = atomicrmw fmax ptr addrspace(1) %ptr, fp128 %value syncscope("agent") seq_cst
121+
ret fp128 %res
122+
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
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
3+
4+
define i128 @test_atomicrmw_xchg_i128_global(ptr addrspace(1) %ptr, i128 %value) {
5+
; CHECK-LABEL: @test_atomicrmw_xchg_i128_global(
6+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
7+
; CHECK-NEXT: [[RES:%.*]] = call i128 @__atomic_exchange_16(ptr [[TMP1]], i128 [[VALUE:%.*]], i32 5)
8+
; CHECK-NEXT: ret i128 [[RES]]
9+
;
10+
%res = atomicrmw xchg ptr addrspace(1) %ptr, i128 %value seq_cst
11+
ret i128 %res
12+
}
13+
14+
define i128 @test_atomicrmw_add_i128_global(ptr addrspace(1) %ptr, i128 %value) {
15+
; CHECK-LABEL: @test_atomicrmw_add_i128_global(
16+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
17+
; CHECK-NEXT: [[RES:%.*]] = call i128 @__atomic_fetch_add_16(ptr [[TMP1]], i128 [[VALUE:%.*]], i32 5)
18+
; CHECK-NEXT: ret i128 [[RES]]
19+
;
20+
%res = atomicrmw add ptr addrspace(1) %ptr, i128 %value seq_cst
21+
ret i128 %res
22+
}
23+
24+
define i128 @test_atomicrmw_sub_i128_global(ptr addrspace(1) %ptr, i128 %value) {
25+
; CHECK-LABEL: @test_atomicrmw_sub_i128_global(
26+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
27+
; CHECK-NEXT: [[RES:%.*]] = call i128 @__atomic_fetch_sub_16(ptr [[TMP1]], i128 [[VALUE:%.*]], i32 5)
28+
; CHECK-NEXT: ret i128 [[RES]]
29+
;
30+
%res = atomicrmw sub ptr addrspace(1) %ptr, i128 %value seq_cst
31+
ret i128 %res
32+
}
33+
34+
define i128 @test_atomicrmw_and_i128_global(ptr addrspace(1) %ptr, i128 %value) {
35+
; CHECK-LABEL: @test_atomicrmw_and_i128_global(
36+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
37+
; CHECK-NEXT: [[TMP7:%.*]] = call i128 @__atomic_fetch_and_16(ptr [[TMP1]], i128 [[VALUE:%.*]], i32 5)
38+
; CHECK-NEXT: ret i128 [[TMP7]]
39+
;
40+
%res = atomicrmw and ptr addrspace(1) %ptr, i128 %value seq_cst
41+
ret i128 %res
42+
}
43+
44+
define i128 @test_atomicrmw_nand_i128_global(ptr addrspace(1) %ptr, i128 %value) {
45+
; CHECK-LABEL: @test_atomicrmw_nand_i128_global(
46+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
47+
; CHECK-NEXT: [[TMP12:%.*]] = call i128 @__atomic_fetch_nand_16(ptr [[TMP1]], i128 [[VALUE:%.*]], i32 5)
48+
; CHECK-NEXT: ret i128 [[TMP12]]
49+
;
50+
%res = atomicrmw nand ptr addrspace(1) %ptr, i128 %value seq_cst
51+
ret i128 %res
52+
}
53+
54+
define i128 @test_atomicrmw_or_i128_global(ptr addrspace(1) %ptr, i128 %value) {
55+
; CHECK-LABEL: @test_atomicrmw_or_i128_global(
56+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
57+
; CHECK-NEXT: [[TMP7:%.*]] = call i128 @__atomic_fetch_or_16(ptr [[TMP1]], i128 [[VALUE:%.*]], i32 5)
58+
; CHECK-NEXT: ret i128 [[TMP7]]
59+
;
60+
%res = atomicrmw or ptr addrspace(1) %ptr, i128 %value seq_cst
61+
ret i128 %res
62+
}
63+
64+
define i128 @test_atomicrmw_xor_i128_global(ptr addrspace(1) %ptr, i128 %value) {
65+
; CHECK-LABEL: @test_atomicrmw_xor_i128_global(
66+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(1) [[PTR:%.*]] to ptr
67+
; CHECK-NEXT: [[TMP7:%.*]] = call i128 @__atomic_fetch_xor_16(ptr [[TMP1]], i128 [[VALUE:%.*]], i32 5)
68+
; CHECK-NEXT: ret i128 [[TMP7]]
69+
;
70+
%res = atomicrmw xor ptr addrspace(1) %ptr, i128 %value seq_cst
71+
ret i128 %res
72+
}
73+
74+
define i128 @test_atomicrmw_max_i128_global(ptr addrspace(1) %ptr, i128 %value) {
75+
; CHECK-LABEL: @test_atomicrmw_max_i128_global(
76+
; CHECK-NEXT: [[TMP1:%.*]] = alloca i128, align 8, addrspace(5)
77+
; CHECK-NEXT: [[TMP2:%.*]] = load i128, ptr addrspace(1) [[PTR:%.*]], align 16
78+
; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
79+
; CHECK: atomicrmw.start:
80+
; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[RES:%.*]], [[ATOMICRMW_START]] ]
81+
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i128 [[LOADED]], [[VALUE:%.*]]
82+
; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i128 [[LOADED]], i128 [[VALUE]]
83+
; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
84+
; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
85+
; CHECK-NEXT: store i128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
86+
; CHECK-NEXT: [[TMP5:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP4]], ptr addrspace(5) [[TMP1]], i128 [[NEW]], i32 5, i32 5)
87+
; CHECK-NEXT: [[TMP6:%.*]] = load i128, ptr addrspace(5) [[TMP1]], align 8
88+
; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
89+
; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i128, i1 } poison, i128 [[TMP6]], 0
90+
; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i128, i1 } [[TMP7]], i1 [[TMP5]], 1
91+
; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP8]], 1
92+
; CHECK-NEXT: [[RES]] = extractvalue { i128, i1 } [[TMP8]], 0
93+
; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
94+
; CHECK: atomicrmw.end:
95+
; CHECK-NEXT: ret i128 [[RES]]
96+
;
97+
%res = atomicrmw max ptr addrspace(1) %ptr, i128 %value seq_cst
98+
ret i128 %res
99+
}
100+
101+
define i128 @test_atomicrmw_min_i128_global(ptr addrspace(1) %ptr, i128 %value) {
102+
; CHECK-LABEL: @test_atomicrmw_min_i128_global(
103+
; CHECK-NEXT: [[TMP1:%.*]] = alloca i128, align 8, addrspace(5)
104+
; CHECK-NEXT: [[TMP2:%.*]] = load i128, ptr addrspace(1) [[PTR:%.*]], align 16
105+
; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
106+
; CHECK: atomicrmw.start:
107+
; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[RES:%.*]], [[ATOMICRMW_START]] ]
108+
; CHECK-NEXT: [[TMP3:%.*]] = icmp sle i128 [[LOADED]], [[VALUE:%.*]]
109+
; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i128 [[LOADED]], i128 [[VALUE]]
110+
; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
111+
; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
112+
; CHECK-NEXT: store i128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
113+
; CHECK-NEXT: [[TMP5:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP4]], ptr addrspace(5) [[TMP1]], i128 [[NEW]], i32 5, i32 5)
114+
; CHECK-NEXT: [[TMP6:%.*]] = load i128, ptr addrspace(5) [[TMP1]], align 8
115+
; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
116+
; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i128, i1 } poison, i128 [[TMP6]], 0
117+
; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i128, i1 } [[TMP7]], i1 [[TMP5]], 1
118+
; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP8]], 1
119+
; CHECK-NEXT: [[RES]] = extractvalue { i128, i1 } [[TMP8]], 0
120+
; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
121+
; CHECK: atomicrmw.end:
122+
; CHECK-NEXT: ret i128 [[RES]]
123+
;
124+
%res = atomicrmw min ptr addrspace(1) %ptr, i128 %value seq_cst
125+
ret i128 %res
126+
}
127+
128+
define i128 @test_atomicrmw_umax_i128_global(ptr addrspace(1) %ptr, i128 %value) {
129+
; CHECK-LABEL: @test_atomicrmw_umax_i128_global(
130+
; CHECK-NEXT: [[TMP1:%.*]] = alloca i128, align 8, addrspace(5)
131+
; CHECK-NEXT: [[TMP2:%.*]] = load i128, ptr addrspace(1) [[PTR:%.*]], align 16
132+
; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
133+
; CHECK: atomicrmw.start:
134+
; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[RES:%.*]], [[ATOMICRMW_START]] ]
135+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i128 [[LOADED]], [[VALUE:%.*]]
136+
; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i128 [[LOADED]], i128 [[VALUE]]
137+
; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
138+
; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
139+
; CHECK-NEXT: store i128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
140+
; CHECK-NEXT: [[TMP5:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP4]], ptr addrspace(5) [[TMP1]], i128 [[NEW]], i32 5, i32 5)
141+
; CHECK-NEXT: [[TMP6:%.*]] = load i128, ptr addrspace(5) [[TMP1]], align 8
142+
; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
143+
; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i128, i1 } poison, i128 [[TMP6]], 0
144+
; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i128, i1 } [[TMP7]], i1 [[TMP5]], 1
145+
; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP8]], 1
146+
; CHECK-NEXT: [[RES]] = extractvalue { i128, i1 } [[TMP8]], 0
147+
; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
148+
; CHECK: atomicrmw.end:
149+
; CHECK-NEXT: ret i128 [[RES]]
150+
;
151+
%res = atomicrmw umax ptr addrspace(1) %ptr, i128 %value seq_cst
152+
ret i128 %res
153+
}
154+
155+
define i128 @test_atomicrmw_umin_i128_global(ptr addrspace(1) %ptr, i128 %value) {
156+
; CHECK-LABEL: @test_atomicrmw_umin_i128_global(
157+
; CHECK-NEXT: [[TMP1:%.*]] = alloca i128, align 8, addrspace(5)
158+
; CHECK-NEXT: [[TMP2:%.*]] = load i128, ptr addrspace(1) [[PTR:%.*]], align 16
159+
; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
160+
; CHECK: atomicrmw.start:
161+
; CHECK-NEXT: [[LOADED:%.*]] = phi i128 [ [[TMP2]], [[TMP0:%.*]] ], [ [[RES:%.*]], [[ATOMICRMW_START]] ]
162+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i128 [[LOADED]], [[VALUE:%.*]]
163+
; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i128 [[LOADED]], i128 [[VALUE]]
164+
; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast ptr addrspace(1) [[PTR]] to ptr
165+
; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
166+
; CHECK-NEXT: store i128 [[LOADED]], ptr addrspace(5) [[TMP1]], align 8
167+
; CHECK-NEXT: [[TMP5:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP4]], ptr addrspace(5) [[TMP1]], i128 [[NEW]], i32 5, i32 5)
168+
; CHECK-NEXT: [[TMP6:%.*]] = load i128, ptr addrspace(5) [[TMP1]], align 8
169+
; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
170+
; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i128, i1 } poison, i128 [[TMP6]], 0
171+
; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i128, i1 } [[TMP7]], i1 [[TMP5]], 1
172+
; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP8]], 1
173+
; CHECK-NEXT: [[RES]] = extractvalue { i128, i1 } [[TMP8]], 0
174+
; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
175+
; CHECK: atomicrmw.end:
176+
; CHECK-NEXT: ret i128 [[RES]]
177+
;
178+
%res = atomicrmw umin ptr addrspace(1) %ptr, i128 %value seq_cst
179+
ret i128 %res
180+
}
181+
182+
define i128 @test_cmpxchg_i128_global(ptr addrspace(1) %out, i128 %in, i128 %old) {
183+
; CHECK-LABEL: @test_cmpxchg_i128_global(
184+
; CHECK-NEXT: [[TMP1:%.*]] = alloca i128, align 8, addrspace(5)
185+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i128, ptr addrspace(1) [[OUT:%.*]], i64 4
186+
; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(1) [[GEP]] to ptr
187+
; CHECK-NEXT: call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) [[TMP1]])
188+
; CHECK-NEXT: store i128 [[OLD:%.*]], ptr addrspace(5) [[TMP1]], align 8
189+
; CHECK-NEXT: [[TMP15:%.*]] = call zeroext i1 @__atomic_compare_exchange_16(ptr [[TMP2]], ptr addrspace(5) [[TMP1]], i128 [[IN:%.*]], i32 5, i32 5)
190+
; CHECK-NEXT: [[TMP4:%.*]] = load i128, ptr addrspace(5) [[TMP1]], align 8
191+
; CHECK-NEXT: call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) [[TMP1]])
192+
; CHECK-NEXT: [[TMP20:%.*]] = insertvalue { i128, i1 } poison, i128 [[TMP4]], 0
193+
; CHECK-NEXT: [[TMP21:%.*]] = insertvalue { i128, i1 } [[TMP20]], i1 [[TMP15]], 1
194+
; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue { i128, i1 } [[TMP21]], 0
195+
; CHECK-NEXT: ret i128 [[EXTRACT]]
196+
;
197+
%gep = getelementptr i128, ptr addrspace(1) %out, i64 4
198+
%res = cmpxchg ptr addrspace(1) %gep, i128 %old, i128 %in seq_cst seq_cst
199+
%extract = extractvalue {i128, i1} %res, 0
200+
ret i128 %extract
201+
}

0 commit comments

Comments
 (0)