[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / mlir / test / Conversion / SPIRVToLLVM / memory-ops-to-llvm.mlir
blob803722294b316d7de8adfd2e7aecbbdc741b855c
1 // RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
3 //===----------------------------------------------------------------------===//
4 // spirv.AccessChain
5 //===----------------------------------------------------------------------===//
7 // CHECK-LABEL: @access_chain
8 spirv.func @access_chain() "None" {
9   // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32
10   %0 = spirv.Constant 1: i32
11   %1 = spirv.Variable : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>
12   // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i32) : i32
13   // CHECK: llvm.getelementptr %{{.*}}[%[[ZERO]], 1, %[[ONE]]] : (!llvm.ptr, i32, i32) -> !llvm.ptr, !llvm.struct<packed (f32, array<4 x f32>)>
14   %2 = spirv.AccessChain %1[%0, %0] : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>, i32, i32 -> !spirv.ptr<f32, Function>
15   spirv.Return
18 // CHECK-LABEL: @access_chain_array
19 spirv.func @access_chain_array(%arg0 : i32) "None" {
20   %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>
21   // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i32) : i32
22   // CHECK: llvm.getelementptr %{{.*}}[%[[ZERO]], %{{.*}}] : (!llvm.ptr, i32, i32) -> !llvm.ptr, !llvm.array<4 x array<4 x f32>>
23   %1 = spirv.AccessChain %0[%arg0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32 -> !spirv.ptr<!spirv.array<4xf32>, Function>
24   %2 = spirv.Load "Function" %1 ["Volatile"] : !spirv.array<4xf32>
25   spirv.Return
28 //===----------------------------------------------------------------------===//
29 // spirv.GlobalVariable and spirv.mlir.addressof
30 //===----------------------------------------------------------------------===//
32 spirv.module Logical GLSL450 {
33   // CHECK: llvm.mlir.global external constant @var() {addr_space = 0 : i32} : f32
34   spirv.GlobalVariable @var : !spirv.ptr<f32, Input>
37 spirv.module Logical GLSL450 {
38   //       CHECK: llvm.mlir.global private @struct() {addr_space = 0 : i32} : !llvm.struct<packed (f32, array<10 x f32>)>
39   // CHECK-LABEL: @func
40   //       CHECK:   llvm.mlir.addressof @struct : !llvm.ptr
41   spirv.GlobalVariable @struct : !spirv.ptr<!spirv.struct<(f32, !spirv.array<10xf32>)>, Private>
42   spirv.func @func() "None" {
43     %0 = spirv.mlir.addressof @struct : !spirv.ptr<!spirv.struct<(f32, !spirv.array<10xf32>)>, Private>
44     spirv.Return
45   }
48 spirv.module Logical GLSL450 {
49   //       CHECK: llvm.mlir.global external @bar_descriptor_set0_binding0() {addr_space = 0 : i32} : i32
50   // CHECK-LABEL: @foo
51   //       CHECK:   llvm.mlir.addressof @bar_descriptor_set0_binding0 : !llvm.ptr
52   spirv.GlobalVariable @bar bind(0, 0) : !spirv.ptr<i32, StorageBuffer>
53   spirv.func @foo() "None" {
54     %0 = spirv.mlir.addressof @bar : !spirv.ptr<i32, StorageBuffer>
55     spirv.Return
56   }
59 spirv.module @name Logical GLSL450 {
60   //       CHECK: llvm.mlir.global external @name_bar_descriptor_set0_binding0() {addr_space = 0 : i32} : i32
61   // CHECK-LABEL: @foo
62   //       CHECK:   llvm.mlir.addressof @name_bar_descriptor_set0_binding0 : !llvm.ptr
63   spirv.GlobalVariable @bar bind(0, 0) : !spirv.ptr<i32, StorageBuffer>
64   spirv.func @foo() "None" {
65     %0 = spirv.mlir.addressof @bar : !spirv.ptr<i32, StorageBuffer>
66     spirv.Return
67   }
70 spirv.module Logical GLSL450 {
71   // CHECK: llvm.mlir.global external @bar() {addr_space = 0 : i32, location = 1 : i32} : i32
72   // CHECK-LABEL: @foo
73   spirv.GlobalVariable @bar {location = 1 : i32} : !spirv.ptr<i32, Output>
74   spirv.func @foo() "None" {
75     %0 = spirv.mlir.addressof @bar : !spirv.ptr<i32, Output>
76     spirv.Return
77   }
80 spirv.module Logical GLSL450 {
81   // CHECK: llvm.mlir.global external constant @bar() {addr_space = 0 : i32, location = 3 : i32} : f32
82   // CHECK-LABEL: @foo
83   spirv.GlobalVariable @bar {descriptor_set = 0 : i32, location = 3 : i32} : !spirv.ptr<f32, UniformConstant>
84   spirv.func @foo() "None" {
85     %0 = spirv.mlir.addressof @bar : !spirv.ptr<f32, UniformConstant>
86     spirv.Return
87   }
90 //===----------------------------------------------------------------------===//
91 // spirv.Load
92 //===----------------------------------------------------------------------===//
94 // CHECK-LABEL: @load
95 spirv.func @load() "None" {
96   %0 = spirv.Variable : !spirv.ptr<f32, Function>
97   //  CHECK: llvm.load %{{.*}} : !llvm.ptr -> f32
98   %1 = spirv.Load "Function" %0 : f32
99   spirv.Return
102 // CHECK-LABEL: @load_none
103 spirv.func @load_none() "None" {
104   %0 = spirv.Variable : !spirv.ptr<f32, Function>
105   //  CHECK: llvm.load %{{.*}} : !llvm.ptr -> f32
106   %1 = spirv.Load "Function" %0 ["None"] : f32
107   spirv.Return
110 // CHECK-LABEL: @load_with_alignment
111 spirv.func @load_with_alignment() "None" {
112   %0 = spirv.Variable : !spirv.ptr<f32, Function>
113   // CHECK: llvm.load %{{.*}} {alignment = 4 : i64} : !llvm.ptr -> f32
114   %1 = spirv.Load "Function" %0 ["Aligned", 4] : f32
115   spirv.Return
118 // CHECK-LABEL: @load_volatile
119 spirv.func @load_volatile() "None" {
120   %0 = spirv.Variable : !spirv.ptr<f32, Function>
121   // CHECK: llvm.load volatile %{{.*}} : !llvm.ptr -> f32
122   %1 = spirv.Load "Function" %0 ["Volatile"] : f32
123   spirv.Return
126 // CHECK-LABEL: @load_nontemporal
127 spirv.func @load_nontemporal() "None" {
128   %0 = spirv.Variable : !spirv.ptr<f32, Function>
129   // CHECK: llvm.load %{{.*}} {nontemporal} : !llvm.ptr -> f32
130   %1 = spirv.Load "Function" %0 ["Nontemporal"] : f32
131   spirv.Return
134 //===----------------------------------------------------------------------===//
135 // spirv.Store
136 //===----------------------------------------------------------------------===//
138 // CHECK-LABEL: @store
139 spirv.func @store(%arg0 : f32) "None" {
140   %0 = spirv.Variable : !spirv.ptr<f32, Function>
141   // CHECK: llvm.store %{{.*}}, %{{.*}} : f32, !llvm.ptr
142   spirv.Store "Function" %0, %arg0 : f32
143   spirv.Return
146 // CHECK-LABEL: @store_composite
147 spirv.func @store_composite(%arg0 : !spirv.struct<(f64)>) "None" {
148   %0 = spirv.Variable : !spirv.ptr<!spirv.struct<(f64)>, Function>
149   // CHECK: llvm.store %{{.*}}, %{{.*}} : !llvm.struct<packed (f64)>, !llvm.ptr
150   spirv.Store "Function" %0, %arg0 : !spirv.struct<(f64)>
151   spirv.Return
154 // CHECK-LABEL: @store_with_alignment
155 spirv.func @store_with_alignment(%arg0 : f32) "None" {
156   %0 = spirv.Variable : !spirv.ptr<f32, Function>
157   // CHECK: llvm.store %{{.*}}, %{{.*}} {alignment = 4 : i64} : f32, !llvm.ptr
158   spirv.Store "Function" %0, %arg0 ["Aligned", 4] : f32
159   spirv.Return
162 // CHECK-LABEL: @store_volatile
163 spirv.func @store_volatile(%arg0 : f32) "None" {
164   %0 = spirv.Variable : !spirv.ptr<f32, Function>
165   // CHECK: llvm.store volatile %{{.*}}, %{{.*}} : f32, !llvm.ptr
166   spirv.Store "Function" %0, %arg0 ["Volatile"] : f32
167   spirv.Return
170 // CHECK-LABEL: @store_nontemporal
171 spirv.func @store_nontemporal(%arg0 : f32) "None" {
172   %0 = spirv.Variable : !spirv.ptr<f32, Function>
173   // CHECK: llvm.store %{{.*}}, %{{.*}} {nontemporal} : f32, !llvm.ptr
174   spirv.Store "Function" %0, %arg0 ["Nontemporal"] : f32
175   spirv.Return
178 //===----------------------------------------------------------------------===//
179 // spirv.Variable
180 //===----------------------------------------------------------------------===//
182 // CHECK-LABEL: @variable_scalar
183 spirv.func @variable_scalar() "None" {
184   // CHECK: %[[SIZE1:.*]] = llvm.mlir.constant(1 : i32) : i32
185   // CHECK: llvm.alloca %[[SIZE1]] x f32 : (i32) -> !llvm.ptr
186   %0 = spirv.Variable : !spirv.ptr<f32, Function>
187   // CHECK: %[[SIZE2:.*]] = llvm.mlir.constant(1 : i32) : i32
188   // CHECK: llvm.alloca %[[SIZE2]] x i8 : (i32) -> !llvm.ptr
189   %1 = spirv.Variable : !spirv.ptr<i8, Function>
190   spirv.Return
193 // CHECK-LABEL: @variable_scalar_with_initialization
194 spirv.func @variable_scalar_with_initialization() "None" {
195   // CHECK: %[[VALUE:.*]] = llvm.mlir.constant(0 : i64) : i64
196   // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
197   // CHECK: %[[ALLOCATED:.*]] = llvm.alloca %[[SIZE]] x i64 : (i32) -> !llvm.ptr
198   // CHECK: llvm.store %[[VALUE]], %[[ALLOCATED]] : i64, !llvm.ptr
199   %c = spirv.Constant 0 : i64
200   %0 = spirv.Variable init(%c) : !spirv.ptr<i64, Function>
201   spirv.Return
204 // CHECK-LABEL: @variable_vector
205 spirv.func @variable_vector() "None" {
206   // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
207   // CHECK: llvm.alloca  %[[SIZE]] x vector<3xf32> : (i32) -> !llvm.ptr
208   %0 = spirv.Variable : !spirv.ptr<vector<3xf32>, Function>
209   spirv.Return
212 // CHECK-LABEL: @variable_vector_with_initialization
213 spirv.func @variable_vector_with_initialization() "None" {
214   // CHECK: %[[VALUE:.*]] = llvm.mlir.constant(dense<false> : vector<3xi1>) : vector<3xi1>
215   // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
216   // CHECK: %[[ALLOCATED:.*]] = llvm.alloca %[[SIZE]] x vector<3xi1> : (i32) -> !llvm.ptr
217   // CHECK: llvm.store %[[VALUE]], %[[ALLOCATED]] : vector<3xi1>, !llvm.ptr
218   %c = spirv.Constant dense<false> : vector<3xi1>
219   %0 = spirv.Variable init(%c) : !spirv.ptr<vector<3xi1>, Function>
220   spirv.Return
223 // CHECK-LABEL: @variable_array
224 spirv.func @variable_array() "None" {
225   // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
226   // CHECK: llvm.alloca %[[SIZE]] x !llvm.array<10 x i32> : (i32) -> !llvm.ptr
227   %0 = spirv.Variable : !spirv.ptr<!spirv.array<10 x i32>, Function>
228   spirv.Return