1; RUN: llc %s -o - | FileCheck %s
2
3target triple = "spirv32-unknown-unknown"
4
5; CHECK-DAG: OpName [[ADD:%.*]] "test_add"
6; CHECK-DAG: OpName [[SUB:%.*]] "test_sub"
7; CHECK-DAG: OpName [[MIN:%.*]] "test_min"
8; CHECK-DAG: OpName [[MAX:%.*]] "test_max"
9; CHECK-DAG: OpName [[UMIN:%.*]] "test_umin"
10; CHECK-DAG: OpName [[UMAX:%.*]] "test_umax"
11; CHECK-DAG: OpName [[AND:%.*]] "test_and"
12; CHECK-DAG: OpName [[OR:%.*]] "test_or"
13; CHECK-DAG: OpName [[XOR:%.*]] "test_xor"
14
15; CHECK-DAG: [[I32Ty:%.*]] = OpTypeInt 32 0
16; Device scope is encoded with constant 1
17; CHECK-DAG: [[SCOPE:%.*]] = OpConstant [[I32Ty]] 1
18; "sequentially consistent" maps to constant 16
19; CHECK-DAG: [[SEQ:%.*]] = OpConstant [[I32Ty]] 16
20
21; CHECK: [[ADD]] = OpFunction [[I32Ty]]
22; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
23; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
24; CHECK-NEXT: OpLabel
25; CHECK-NEXT: [[R:%.*]] = OpAtomicIAdd [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
26; CHECK-NEXT: OpReturnValue [[R]]
27; CHECK-NEXT: OpFunctionEnd
28define i32 @test_add(i32* %ptr, i32 %val) {
29  %r = atomicrmw add i32* %ptr, i32 %val seq_cst
30  ret i32 %r
31}
32
33; CHECK: [[SUB]] = OpFunction [[I32Ty]]
34; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
35; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
36; CHECK-NEXT: OpLabel
37; CHECK-NEXT: [[R:%.*]] = OpAtomicISub [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
38; CHECK-NEXT: OpReturnValue [[R]]
39; CHECK-NEXT: OpFunctionEnd
40define i32 @test_sub(i32* %ptr, i32 %val) {
41  %r = atomicrmw sub i32* %ptr, i32 %val seq_cst
42  ret i32 %r
43}
44
45; CHECK: [[MIN]] = OpFunction [[I32Ty]]
46; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
47; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
48; CHECK-NEXT: OpLabel
49; CHECK-NEXT: [[R:%.*]] = OpAtomicSMin [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
50; CHECK-NEXT: OpReturnValue [[R]]
51; CHECK-NEXT: OpFunctionEnd
52define i32 @test_min(i32* %ptr, i32 %val) {
53  %r = atomicrmw min i32* %ptr, i32 %val seq_cst
54  ret i32 %r
55}
56
57; CHECK: [[MAX]] = OpFunction [[I32Ty]]
58; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
59; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
60; CHECK-NEXT: OpLabel
61; CHECK-NEXT: [[R:%.*]] = OpAtomicSMax [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
62; CHECK-NEXT: OpReturnValue [[R]]
63; CHECK-NEXT: OpFunctionEnd
64define i32 @test_max(i32* %ptr, i32 %val) {
65  %r = atomicrmw max i32* %ptr, i32 %val seq_cst
66  ret i32 %r
67}
68
69; CHECK: [[UMIN]] = OpFunction [[I32Ty]]
70; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
71; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
72; CHECK-NEXT: OpLabel
73; CHECK-NEXT: [[R:%.*]] = OpAtomicUMin [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
74; CHECK-NEXT: OpReturnValue [[R]]
75; CHECK-NEXT: OpFunctionEnd
76define i32 @test_umin(i32* %ptr, i32 %val) {
77  %r = atomicrmw umin i32* %ptr, i32 %val seq_cst
78  ret i32 %r
79}
80
81; CHECK: [[UMAX]] = OpFunction [[I32Ty]]
82; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
83; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
84; CHECK-NEXT: OpLabel
85; CHECK-NEXT: [[R:%.*]] = OpAtomicUMax [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
86; CHECK-NEXT: OpReturnValue [[R]]
87; CHECK-NEXT: OpFunctionEnd
88define i32 @test_umax(i32* %ptr, i32 %val) {
89  %r = atomicrmw umax i32* %ptr, i32 %val seq_cst
90  ret i32 %r
91}
92
93; CHECK: [[AND]] = OpFunction [[I32Ty]]
94; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
95; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
96; CHECK-NEXT: OpLabel
97; CHECK-NEXT: [[R:%.*]] = OpAtomicAnd [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
98; CHECK-NEXT: OpReturnValue [[R]]
99; CHECK-NEXT: OpFunctionEnd
100define i32 @test_and(i32* %ptr, i32 %val) {
101  %r = atomicrmw and i32* %ptr, i32 %val seq_cst
102  ret i32 %r
103}
104
105; CHECK: [[OR]] = OpFunction [[I32Ty]]
106; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
107; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
108; CHECK-NEXT: OpLabel
109; CHECK-NEXT: [[R:%.*]] = OpAtomicOr [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
110; CHECK-NEXT: OpReturnValue [[R]]
111; CHECK-NEXT: OpFunctionEnd
112define i32 @test_or(i32* %ptr, i32 %val) {
113  %r = atomicrmw or i32* %ptr, i32 %val seq_cst
114  ret i32 %r
115}
116
117; CHECK: [[XOR]] = OpFunction [[I32Ty]]
118; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter
119; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter
120; CHECK-NEXT: OpLabel
121; CHECK-NEXT: [[R:%.*]] = OpAtomicXor [[I32Ty]] [[A]] [[SCOPE]] [[SEQ]] [[B]]
122; CHECK-NEXT: OpReturnValue [[R]]
123; CHECK-NEXT: OpFunctionEnd
124define i32 @test_xor(i32* %ptr, i32 %val) {
125  %r = atomicrmw xor i32* %ptr, i32 %val seq_cst
126  ret i32 %r
127}
128