blob: c60c05975600a8bc9ec1224686b5b681fc09de34 [file] [log] [blame]
Matt Arsenault06028dd2014-05-01 16:37:52 +00001; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck %s --check-prefix=R600-CHECK --check-prefix=FUNC
2; RUN: llc -verify-machineinstrs -march=r600 -mcpu=SI < %s | FileCheck %s --check-prefix=SI-CHECK --check-prefix=FUNC
Tom Stellardaad53762013-06-05 03:43:06 +00003
Tom Stellarde9373602014-01-22 19:24:14 +00004; FUNC-LABEL: @mova_same_clause
5
Tom Stellard880a80a2014-06-17 16:53:14 +00006; R600-CHECK: LDS_WRITE
7; R600-CHECK: LDS_WRITE
8; R600-CHECK: LDS_READ
9; R600-CHECK: LDS_READ
Tom Stellardaad53762013-06-05 03:43:06 +000010
Tom Stellard880a80a2014-06-17 16:53:14 +000011; SI-CHECK: DS_WRITE_B32
12; SI-CHECK: DS_WRITE_B32
13; SI-CHECK: DS_READ_B32
14; SI-CHECK: DS_READ_B32
Tom Stellardaad53762013-06-05 03:43:06 +000015define void @mova_same_clause(i32 addrspace(1)* nocapture %out, i32 addrspace(1)* nocapture %in) {
16entry:
17 %stack = alloca [5 x i32], align 4
18 %0 = load i32 addrspace(1)* %in, align 4
19 %arrayidx1 = getelementptr inbounds [5 x i32]* %stack, i32 0, i32 %0
20 store i32 4, i32* %arrayidx1, align 4
21 %arrayidx2 = getelementptr inbounds i32 addrspace(1)* %in, i32 1
22 %1 = load i32 addrspace(1)* %arrayidx2, align 4
23 %arrayidx3 = getelementptr inbounds [5 x i32]* %stack, i32 0, i32 %1
24 store i32 5, i32* %arrayidx3, align 4
25 %arrayidx10 = getelementptr inbounds [5 x i32]* %stack, i32 0, i32 0
26 %2 = load i32* %arrayidx10, align 4
27 store i32 %2, i32 addrspace(1)* %out, align 4
28 %arrayidx12 = getelementptr inbounds [5 x i32]* %stack, i32 0, i32 1
29 %3 = load i32* %arrayidx12
30 %arrayidx13 = getelementptr inbounds i32 addrspace(1)* %out, i32 1
31 store i32 %3, i32 addrspace(1)* %arrayidx13
32 ret void
33}
Tom Stellardd7458372013-06-07 20:52:05 +000034
35; This test checks that the stack offset is calculated correctly for structs.
36; All register loads/stores should be optimized away, so there shouldn't be
37; any MOVA instructions.
38;
39; XXX: This generated code has unnecessary MOVs, we should be able to optimize
40; this.
41
Tom Stellarde9373602014-01-22 19:24:14 +000042; FUNC-LABEL: @multiple_structs
Tom Stellard81d871d2013-11-13 23:36:50 +000043; R600-CHECK-NOT: MOVA_INT
Tom Stellard81d871d2013-11-13 23:36:50 +000044; SI-CHECK-NOT: V_MOVREL
Tom Stellardd7458372013-06-07 20:52:05 +000045%struct.point = type { i32, i32 }
46
47define void @multiple_structs(i32 addrspace(1)* %out) {
48entry:
49 %a = alloca %struct.point
50 %b = alloca %struct.point
51 %a.x.ptr = getelementptr %struct.point* %a, i32 0, i32 0
52 %a.y.ptr = getelementptr %struct.point* %a, i32 0, i32 1
53 %b.x.ptr = getelementptr %struct.point* %b, i32 0, i32 0
54 %b.y.ptr = getelementptr %struct.point* %b, i32 0, i32 1
55 store i32 0, i32* %a.x.ptr
56 store i32 1, i32* %a.y.ptr
57 store i32 2, i32* %b.x.ptr
58 store i32 3, i32* %b.y.ptr
59 %a.indirect.ptr = getelementptr %struct.point* %a, i32 0, i32 0
60 %b.indirect.ptr = getelementptr %struct.point* %b, i32 0, i32 0
61 %a.indirect = load i32* %a.indirect.ptr
62 %b.indirect = load i32* %b.indirect.ptr
63 %0 = add i32 %a.indirect, %b.indirect
64 store i32 %0, i32 addrspace(1)* %out
65 ret void
66}
Tom Stellard26a3b672013-10-22 18:19:10 +000067
68; Test direct access of a private array inside a loop. The private array
69; loads and stores should be lowered to copies, so there shouldn't be any
70; MOVA instructions.
71
Tom Stellarde9373602014-01-22 19:24:14 +000072; FUNC-LABEL: @direct_loop
Tom Stellard81d871d2013-11-13 23:36:50 +000073; R600-CHECK-NOT: MOVA_INT
Tom Stellard81d871d2013-11-13 23:36:50 +000074; SI-CHECK-NOT: V_MOVREL
Tom Stellard26a3b672013-10-22 18:19:10 +000075
76define void @direct_loop(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
77entry:
78 %prv_array_const = alloca [2 x i32]
79 %prv_array = alloca [2 x i32]
80 %a = load i32 addrspace(1)* %in
81 %b_src_ptr = getelementptr i32 addrspace(1)* %in, i32 1
82 %b = load i32 addrspace(1)* %b_src_ptr
83 %a_dst_ptr = getelementptr [2 x i32]* %prv_array_const, i32 0, i32 0
84 store i32 %a, i32* %a_dst_ptr
85 %b_dst_ptr = getelementptr [2 x i32]* %prv_array_const, i32 0, i32 1
86 store i32 %b, i32* %b_dst_ptr
87 br label %for.body
88
89for.body:
90 %inc = phi i32 [0, %entry], [%count, %for.body]
91 %x_ptr = getelementptr [2 x i32]* %prv_array_const, i32 0, i32 0
92 %x = load i32* %x_ptr
93 %y_ptr = getelementptr [2 x i32]* %prv_array, i32 0, i32 0
94 %y = load i32* %y_ptr
95 %xy = add i32 %x, %y
96 store i32 %xy, i32* %y_ptr
97 %count = add i32 %inc, 1
98 %done = icmp eq i32 %count, 4095
99 br i1 %done, label %for.end, label %for.body
100
101for.end:
102 %value_ptr = getelementptr [2 x i32]* %prv_array, i32 0, i32 0
103 %value = load i32* %value_ptr
104 store i32 %value, i32 addrspace(1)* %out
105 ret void
106}
Tom Stellarde9373602014-01-22 19:24:14 +0000107
108; FUNC-LABEL: @short_array
109
Tom Stellarde9373602014-01-22 19:24:14 +0000110; R600-CHECK: MOVA_INT
111
Tom Stellarde9373602014-01-22 19:24:14 +0000112; SI-CHECK: V_MOVRELS_B32_e32
113define void @short_array(i32 addrspace(1)* %out, i32 %index) {
114entry:
115 %0 = alloca [2 x i16]
116 %1 = getelementptr [2 x i16]* %0, i32 0, i32 0
117 %2 = getelementptr [2 x i16]* %0, i32 0, i32 1
118 store i16 0, i16* %1
119 store i16 1, i16* %2
120 %3 = getelementptr [2 x i16]* %0, i32 0, i32 %index
121 %4 = load i16* %3
122 %5 = sext i16 %4 to i32
123 store i32 %5, i32 addrspace(1)* %out
124 ret void
125}
126
127; FUNC-LABEL: @char_array
128
Tom Stellard880a80a2014-06-17 16:53:14 +0000129; R600-CHECK: MOVA_INT
Tom Stellarde9373602014-01-22 19:24:14 +0000130
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000131; SI-CHECK: V_OR_B32_e32 v{{[0-9]}}, 0x100
Tom Stellarde9373602014-01-22 19:24:14 +0000132; SI-CHECK: V_MOVRELS_B32_e32
133define void @char_array(i32 addrspace(1)* %out, i32 %index) {
134entry:
135 %0 = alloca [2 x i8]
136 %1 = getelementptr [2 x i8]* %0, i32 0, i32 0
137 %2 = getelementptr [2 x i8]* %0, i32 0, i32 1
138 store i8 0, i8* %1
139 store i8 1, i8* %2
140 %3 = getelementptr [2 x i8]* %0, i32 0, i32 %index
141 %4 = load i8* %3
142 %5 = sext i8 %4 to i32
143 store i32 %5, i32 addrspace(1)* %out
144 ret void
145
146}
Tom Stellard27982b12014-01-22 19:24:19 +0000147
148; Make sure we don't overwrite workitem information with private memory
149
150; FUNC-LABEL: @work_item_info
151; R600-CHECK-NOT: MOV T0.X
152; Additional check in case the move ends up in the last slot
153; R600-CHECK-NOT: MOV * TO.X
154
155; SI-CHECK-NOT: V_MOV_B32_e{{(32|64)}} v0
156define void @work_item_info(i32 addrspace(1)* %out, i32 %in) {
157entry:
158 %0 = alloca [2 x i32]
159 %1 = getelementptr [2 x i32]* %0, i32 0, i32 0
160 %2 = getelementptr [2 x i32]* %0, i32 0, i32 1
161 store i32 0, i32* %1
162 store i32 1, i32* %2
163 %3 = getelementptr [2 x i32]* %0, i32 0, i32 %in
164 %4 = load i32* %3
165 %5 = call i32 @llvm.r600.read.tidig.x()
166 %6 = add i32 %4, %5
167 store i32 %6, i32 addrspace(1)* %out
168 ret void
169}
170
Tom Stellard598f3942014-01-22 19:24:23 +0000171; Test that two stack objects are not stored in the same register
172; The second stack object should be in T3.X
173; FUNC-LABEL: @no_overlap
Tom Stellard880a80a2014-06-17 16:53:14 +0000174; R600_CHECK: MOV
175; R600_CHECK: [[CHAN:[XYZW]]]+
176; R600-CHECK-NOT: [[CHAN]]+
Tom Stellard598f3942014-01-22 19:24:23 +0000177; SI-CHECK: V_MOV_B32_e32 v3
178define void @no_overlap(i32 addrspace(1)* %out, i32 %in) {
179entry:
180 %0 = alloca [3 x i8], align 1
181 %1 = alloca [2 x i8], align 1
182 %2 = getelementptr [3 x i8]* %0, i32 0, i32 0
183 %3 = getelementptr [3 x i8]* %0, i32 0, i32 1
184 %4 = getelementptr [3 x i8]* %0, i32 0, i32 2
185 %5 = getelementptr [2 x i8]* %1, i32 0, i32 0
186 %6 = getelementptr [2 x i8]* %1, i32 0, i32 1
187 store i8 0, i8* %2
188 store i8 1, i8* %3
189 store i8 2, i8* %4
190 store i8 1, i8* %5
191 store i8 0, i8* %6
192 %7 = getelementptr [3 x i8]* %0, i32 0, i32 %in
193 %8 = getelementptr [2 x i8]* %1, i32 0, i32 %in
194 %9 = load i8* %7
195 %10 = load i8* %8
196 %11 = add i8 %9, %10
197 %12 = sext i8 %11 to i32
198 store i32 %12, i32 addrspace(1)* %out
199 ret void
200}
201
202
203
Tom Stellard27982b12014-01-22 19:24:19 +0000204declare i32 @llvm.r600.read.tidig.x() nounwind readnone