xref: /llvm-project/mlir/test/Target/Cpp/common-cpp.mlir (revision 8b2ad5c8f18096c8ef25d77906391b7c09342137)
1// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s
2
3// CHECK: #include "myheader.h"
4emitc.include "myheader.h"
5// CHECK: #include <myheader.h>
6emitc.include <"myheader.h">
7
8// CHECK: void test_include() {
9func.func @test_include() {
10  // CHECK: #include "myheader.h"
11  emitc.include "myheader.h"
12  return
13}
14
15// CHECK: void test_foo_print() {
16func.func @test_foo_print() {
17  // CHECK: [[V1:[^ ]*]] = foo::constant({0, 1});
18  %0 = emitc.call_opaque "foo::constant"() {args = [dense<[0, 1]> : tensor<2xi32>]} : () -> (i32)
19  // CHECK: [[V2:[^ ]*]] = foo::op_and_attr({0, 1}, [[V1]]);
20  %1 = emitc.call_opaque "foo::op_and_attr"(%0) {args = [dense<[0, 1]> : tensor<2xi32>, 0 : index]} : (i32) -> (i32)
21  // CHECK: [[V3:[^ ]*]] = foo::op_and_attr([[V2]], {0, 1});
22  %2 = emitc.call_opaque "foo::op_and_attr"(%1) {args = [0 : index, dense<[0, 1]> : tensor<2xi32>]} : (i32) -> (i32)
23  // CHECK: foo::print([[V3]]);
24  emitc.call_opaque "foo::print"(%2): (i32) -> ()
25  return
26}
27
28// CHECK: int32_t test_single_return(int32_t [[V2:.*]])
29func.func @test_single_return(%arg0 : i32) -> i32 {
30  // CHECK: return [[V2]]
31  return %arg0 : i32
32}
33
34// CHECK: std::tuple<int32_t, int32_t> test_multiple_return()
35func.func @test_multiple_return() -> (i32, i32) {
36  // CHECK: std::tie([[V3:.*]], [[V4:.*]]) = foo::blah();
37  %0:2 = emitc.call_opaque "foo::blah"() : () -> (i32, i32)
38  // CHECK: [[V5:[^ ]*]] = test_single_return([[V3]]);
39  %1 = call @test_single_return(%0#0) : (i32) -> i32
40  // CHECK: return std::make_tuple([[V5]], [[V4]]);
41  return %1, %0#1 : i32, i32
42}
43
44// CHECK: test_float
45func.func @test_float() {
46  // CHECK: foo::constant({0.0e+00f, 1.000000000e+00f})
47  %0 = emitc.call_opaque "foo::constant"() {args = [dense<[0.000000e+00, 1.000000e+00]> : tensor<2xf32>]} : () -> f32
48  return
49}
50
51// CHECK: test_uint
52func.func @test_uint() {
53  // CHECK: uint32_t
54  %0 = emitc.call_opaque "foo::constant"() {args = [dense<[0, 1]> : tensor<2xui32>]} : () -> ui32
55  // CHECK: uint64_t
56  %1 = emitc.call_opaque "foo::constant"() {args = [dense<[0, 1]> : tensor<2xui64>]} : () -> ui64
57  return
58}
59
60// CHECK: int64_t test_plus_int(int64_t [[V1]])
61func.func @test_plus_int(%arg0 : i64) -> i64 {
62  // CHECK: mhlo::add([[V1]], [[V1]])
63  %0 = emitc.call_opaque "mhlo::add"(%arg0, %arg0) {args = [0 : index, 1 : index]} : (i64, i64) -> i64
64  return %0 : i64
65}
66
67// CHECK: Tensor<float, 2> mixed_types(Tensor<double, 2> [[V1]])
68func.func @mixed_types(%arg0: tensor<2xf64>) -> tensor<2xf32> {
69  // CHECK: foo::mixed_types([[V1]]);
70  %0 = emitc.call_opaque "foo::mixed_types"(%arg0) {args = [0 : index]} : (tensor<2xf64>) -> tensor<2xf32>
71  return %0 : tensor<2xf32>
72}
73
74// CHECK: Tensor<uint64_t> mhlo_convert(Tensor<uint32_t> [[V1]])
75func.func @mhlo_convert(%arg0: tensor<ui32>) -> tensor<ui64> {
76  // CHECK: mhlo::convert([[V1]]);
77  %0 = emitc.call_opaque "mhlo::convert"(%arg0) {args = [0 : index]} : (tensor<ui32>) -> tensor<ui64>
78  return %0 : tensor<ui64>
79}
80
81// CHECK: status_t opaque_types(bool [[V1:[^ ]*]], char [[V2:[^ ]*]]) {
82func.func @opaque_types(%arg0: !emitc.opaque<"bool">, %arg1: !emitc.opaque<"char">) -> !emitc.opaque<"status_t"> {
83  // CHECK: int [[V3:[^ ]*]] = a([[V1]], [[V2]]);
84  %0 = emitc.call_opaque "a"(%arg0, %arg1) : (!emitc.opaque<"bool">, !emitc.opaque<"char">) -> (!emitc.opaque<"int">)
85  // CHECK: char [[V4:[^ ]*]] = b([[V3]]);
86  %1 = emitc.call_opaque "b"(%0): (!emitc.opaque<"int">) -> (!emitc.opaque<"char">)
87  // CHECK: status_t [[V5:[^ ]*]] = c([[V3]], [[V4]]);
88  %2 = emitc.call_opaque "c"(%0, %1): (!emitc.opaque<"int">, !emitc.opaque<"char">) -> (!emitc.opaque<"status_t">)
89  return %2 : !emitc.opaque<"status_t">
90}
91
92// CHECK-LABEL: int32_t* apply() {
93func.func @apply() -> !emitc.ptr<i32> {
94  // CHECK-NEXT: int32_t [[V1:[^ ]*]];
95  %0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>
96  // CHECK-NEXT: int32_t* [[V2:[^ ]*]] = &[[V1]];
97  %1 = emitc.apply "&"(%0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
98  // CHECK-NEXT: int32_t [[V3:[^ ]*]];
99  %2 = "emitc.variable"() {value = #emitc.opaque<"">} : () -> !emitc.lvalue<i32>
100  // CHECK-NEXT: int32_t [[V4:[^ ]*]] = *[[V2]];
101  %3 = emitc.apply "*"(%1) : (!emitc.ptr<i32>) -> i32
102  // CHECK-NEXT: [[V3]] = [[V4]];
103  emitc.assign %3 : i32 to %2 : !emitc.lvalue<i32>
104  // CHECK-NEXT: return [[V2]];
105  return %1 : !emitc.ptr<i32>
106}
107
108// CHECK: void array_type(int32_t v1[3], float v2[10][20])
109func.func @array_type(%arg0: !emitc.array<3xi32>, %arg1: !emitc.array<10x20xf32>) {
110  return
111}
112