xref: /llvm-project/mlir/test/Conversion/SPIRVToLLVM/misc-ops-to-llvm.mlir (revision 8cbb8ac02cc481723a0e0c20beab03fdc50accd9)
1// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
2
3//===----------------------------------------------------------------------===//
4// spirv.CompositeExtract
5//===----------------------------------------------------------------------===//
6
7// CHECK-LABEL: @composite_extract_array
8spirv.func @composite_extract_array(%arg: !spirv.array<4x!spirv.array<4xf32>>) "None" {
9  // CHECK: llvm.extractvalue %{{.*}}[1, 3] : !llvm.array<4 x array<4 x f32>>
10  %0 = spirv.CompositeExtract %arg[1 : i32, 3 : i32] : !spirv.array<4x!spirv.array<4xf32>>
11  spirv.Return
12}
13
14// CHECK-LABEL: @composite_extract_vector
15spirv.func @composite_extract_vector(%arg: vector<3xf32>) "None" {
16  // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i32) : i32
17  // CHECK: llvm.extractelement %{{.*}}[%[[ZERO]] : i32] : vector<3xf32>
18  %0 = spirv.CompositeExtract %arg[0 : i32] : vector<3xf32>
19  spirv.Return
20}
21
22//===----------------------------------------------------------------------===//
23// spirv.CompositeInsert
24//===----------------------------------------------------------------------===//
25
26// CHECK-LABEL: @composite_insert_struct
27spirv.func @composite_insert_struct(%arg0: i32, %arg1: !spirv.struct<(f32, !spirv.array<4xi32>)>) "None" {
28  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[1, 3] : !llvm.struct<packed (f32, array<4 x i32>)>
29  %0 = spirv.CompositeInsert %arg0, %arg1[1 : i32, 3 : i32] : i32 into !spirv.struct<(f32, !spirv.array<4xi32>)>
30  spirv.Return
31}
32
33// CHECK-LABEL: @composite_insert_vector
34spirv.func @composite_insert_vector(%arg0: vector<3xf32>, %arg1: f32) "None" {
35  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32
36  // CHECK: llvm.insertelement %{{.*}}, %{{.*}}[%[[ONE]] : i32] : vector<3xf32>
37  %0 = spirv.CompositeInsert %arg1, %arg0[1 : i32] : f32 into vector<3xf32>
38  spirv.Return
39}
40
41//===----------------------------------------------------------------------===//
42// spirv.Select
43//===----------------------------------------------------------------------===//
44
45// CHECK-LABEL: @select_scalar
46spirv.func @select_scalar(%arg0: i1, %arg1: vector<3xi32>, %arg2: vector<3xi32>, %arg3: f32, %arg4: f32) "None" {
47  // CHECK: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : i1, vector<3xi32>
48  %0 = spirv.Select %arg0, %arg1, %arg2 : i1, vector<3xi32>
49  // CHECK: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : i1, f32
50  %1 = spirv.Select %arg0, %arg3, %arg4 : i1, f32
51  spirv.Return
52}
53
54// CHECK-LABEL: @select_vector
55spirv.func @select_vector(%arg0: vector<2xi1>, %arg1: vector<2xi32>, %arg2: vector<2xi32>) "None" {
56  // CHECK: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : vector<2xi1>, vector<2xi32>
57  %0 = spirv.Select %arg0, %arg1, %arg2 : vector<2xi1>, vector<2xi32>
58  spirv.Return
59}
60
61//===----------------------------------------------------------------------===//
62// spirv.VectorShuffle
63//===----------------------------------------------------------------------===//
64
65spirv.func @vector_shuffle_same_size(%vector1: vector<2xf32>, %vector2: vector<2xf32>) -> vector<3xf32> "None" {
66  //      CHECK: %[[res:.*]] = llvm.shufflevector {{.*}} [0, 2, -1] : vector<2xf32>
67  // CHECK-NEXT: return %[[res]] : vector<3xf32>
68  %0 = spirv.VectorShuffle [0: i32, 2: i32, 0xffffffff: i32] %vector1, %vector2 : vector<2xf32>, vector<2xf32> -> vector<3xf32>
69  spirv.ReturnValue %0: vector<3xf32>
70}
71
72spirv.func @vector_shuffle_different_size(%vector1: vector<3xf32>, %vector2: vector<2xf32>) -> vector<3xf32> "None" {
73  //      CHECK: %[[UNDEF:.*]] = llvm.mlir.undef : vector<3xf32>
74  // CHECK-NEXT: %[[C0_0:.*]] = llvm.mlir.constant(0 : i32) : i32
75  // CHECK-NEXT: %[[C0_1:.*]] = llvm.mlir.constant(0 : i32) : i32
76  // CHECK-NEXT: %[[EXT0:.*]] = llvm.extractelement %arg0[%[[C0_1]] : i32] : vector<3xf32>
77  // CHECK-NEXT: %[[INSERT0:.*]] = llvm.insertelement %[[EXT0]], %[[UNDEF]][%[[C0_0]] : i32] : vector<3xf32>
78  // CHECK-NEXT: %[[C1_0:.*]] = llvm.mlir.constant(1 : i32) : i32
79  // CHECK-NEXT: %[[C1_1:.*]] = llvm.mlir.constant(1 : i32) : i32
80  // CHECK-NEXT: %[[EXT1:.*]] = llvm.extractelement {{.*}}[%[[C1_1]] : i32] : vector<2xf32>
81  // CHECK-NEXT: %[[RES:.*]] = llvm.insertelement %[[EXT1]], %[[INSERT0]][%[[C1_0]] : i32] : vector<3xf32>
82  // CHECK-NEXT: llvm.return %[[RES]] : vector<3xf32>
83  %0 = spirv.VectorShuffle [0: i32, 4: i32, 0xffffffff: i32] %vector1, %vector2 : vector<3xf32>, vector<2xf32> -> vector<3xf32>
84  spirv.ReturnValue %0: vector<3xf32>
85}
86
87//===----------------------------------------------------------------------===//
88// spirv.EntryPoint and spirv.ExecutionMode
89//===----------------------------------------------------------------------===//
90
91//      CHECK: module {
92// CHECK-NEXT:   llvm.mlir.global external constant @{{.*}}() {addr_space = 0 : i32} : !llvm.struct<(i32)> {
93// CHECK-NEXT:     %[[UNDEF:.*]] = llvm.mlir.undef : !llvm.struct<(i32)>
94// CHECK-NEXT:     %[[VAL:.*]] = llvm.mlir.constant(31 : i32) : i32
95// CHECK-NEXT:     %[[RET:.*]] = llvm.insertvalue %[[VAL]], %[[UNDEF]][0] : !llvm.struct<(i32)>
96// CHECK-NEXT:     llvm.return %[[RET]] : !llvm.struct<(i32)>
97// CHECK-NEXT:   }
98// CHECK-NEXT:   llvm.func @empty
99// CHECK-NEXT:     llvm.return
100// CHECK-NEXT:   }
101// CHECK-NEXT: }
102spirv.module Logical OpenCL {
103  spirv.func @empty() "None" {
104    spirv.Return
105  }
106  spirv.EntryPoint "Kernel" @empty
107  spirv.ExecutionMode @empty "ContractionOff"
108}
109
110//      CHECK: module {
111// CHECK-NEXT:   llvm.mlir.global external constant @{{.*}}() {addr_space = 0 : i32} : !llvm.struct<(i32, array<3 x i32>)> {
112// CHECK-NEXT:     %[[UNDEF:.*]] = llvm.mlir.undef : !llvm.struct<(i32, array<3 x i32>)>
113// CHECK-NEXT:     %[[EM:.*]] = llvm.mlir.constant(18 : i32) : i32
114// CHECK-NEXT:     %[[T0:.*]] = llvm.insertvalue %[[EM]], %[[UNDEF]][0] : !llvm.struct<(i32, array<3 x i32>)>
115// CHECK-NEXT:     %[[C0:.*]] = llvm.mlir.constant(32 : i32) : i32
116// CHECK-NEXT:     %[[T1:.*]] = llvm.insertvalue %[[C0]], %[[T0]][1, 0] : !llvm.struct<(i32, array<3 x i32>)>
117// CHECK-NEXT:     %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32
118// CHECK-NEXT:     %[[T2:.*]] = llvm.insertvalue %[[C1]], %[[T1]][1, 1] : !llvm.struct<(i32, array<3 x i32>)>
119// CHECK-NEXT:     %[[C2:.*]] = llvm.mlir.constant(1 : i32) : i32
120// CHECK-NEXT:     %[[RET:.*]] = llvm.insertvalue %[[C2]], %[[T2]][1, 2] : !llvm.struct<(i32, array<3 x i32>)>
121// CHECK-NEXT:     llvm.return %[[RET]] : !llvm.struct<(i32, array<3 x i32>)>
122// CHECK-NEXT:   }
123// CHECK-NEXT:   llvm.mlir.global external constant @{{.*}}() {addr_space = 0 : i32} : !llvm.struct<(i32)> {
124//      CHECK:   llvm.func @bar
125// CHECK-NEXT:     llvm.return
126// CHECK-NEXT:   }
127// CHECK-NEXT: }
128spirv.module Logical OpenCL {
129  spirv.func @bar() "None" {
130    spirv.Return
131  }
132  spirv.EntryPoint "Kernel" @bar
133  spirv.ExecutionMode @bar "ContractionOff"
134  spirv.ExecutionMode @bar "LocalSizeHint", 32, 1, 1
135}
136
137//===----------------------------------------------------------------------===//
138// spirv.Undef
139//===----------------------------------------------------------------------===//
140
141// CHECK-LABEL: @undef_scalar
142spirv.func @undef_scalar() "None" {
143  // CHECK: llvm.mlir.undef : f32
144  %0 = spirv.Undef : f32
145  spirv.Return
146}
147
148// CHECK-LABEL: @undef_vector
149spirv.func @undef_vector() "None" {
150  // CHECK: llvm.mlir.undef : vector<2xi32>
151  %0 = spirv.Undef : vector<2xi32>
152  spirv.Return
153}
154