1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | mlir-opt | FileCheck %s 2// RUN: mlir-opt -split-input-file -verify-diagnostics -mlir-print-op-generic %s | FileCheck %s --check-prefix=GENERIC 3 4module { 5 // GENERIC: "llvm.func" 6 // GENERIC: sym_name = "foo" 7 // GENERIC-SAME: type = !llvm.func<void ()> 8 // GENERIC-SAME: () -> () 9 // CHECK: llvm.func @foo() 10 "llvm.func"() ({ 11 }) {sym_name = "foo", type = !llvm.func<void ()>} : () -> () 12 13 // GENERIC: "llvm.func" 14 // GENERIC: sym_name = "bar" 15 // GENERIC-SAME: type = !llvm.func<i64 (i64, i64)> 16 // GENERIC-SAME: () -> () 17 // CHECK: llvm.func @bar(!llvm.i64, !llvm.i64) -> !llvm.i64 18 "llvm.func"() ({ 19 }) {sym_name = "bar", type = !llvm.func<i64 (i64, i64)>} : () -> () 20 21 // GENERIC: "llvm.func" 22 // CHECK: llvm.func @baz(%{{.*}}: !llvm.i64) -> !llvm.i64 23 "llvm.func"() ({ 24 // GENERIC: ^bb0 25 ^bb0(%arg0: !llvm.i64): 26 // GENERIC: llvm.return 27 llvm.return %arg0 : !llvm.i64 28 29 // GENERIC: sym_name = "baz" 30 // GENERIC-SAME: type = !llvm.func<i64 (i64)> 31 // GENERIC-SAME: () -> () 32 }) {sym_name = "baz", type = !llvm.func<i64 (i64)>} : () -> () 33 34 // CHECK: llvm.func @qux(!llvm.ptr<i64> {llvm.noalias = true}, !llvm.i64) 35 // CHECK: attributes {xxx = {yyy = 42 : i64}} 36 "llvm.func"() ({ 37 }) {sym_name = "qux", type = !llvm.func<void (ptr<i64>, i64)>, 38 arg0 = {llvm.noalias = true}, xxx = {yyy = 42}} : () -> () 39 40 // CHECK: llvm.func @roundtrip1() 41 llvm.func @roundtrip1() 42 43 // CHECK: llvm.func @roundtrip2(!llvm.i64, !llvm.float) -> !llvm.double 44 llvm.func @roundtrip2(!llvm.i64, !llvm.float) -> !llvm.double 45 46 // CHECK: llvm.func @roundtrip3(!llvm.i32, !llvm.i1) 47 llvm.func @roundtrip3(%a: !llvm.i32, %b: !llvm.i1) 48 49 // CHECK: llvm.func @roundtrip4(%{{.*}}: !llvm.i32, %{{.*}}: !llvm.i1) { 50 llvm.func @roundtrip4(%a: !llvm.i32, %b: !llvm.i1) { 51 llvm.return 52 } 53 54 // CHECK: llvm.func @roundtrip5() 55 // CHECK: attributes {baz = 42 : i64, foo = "bar"} 56 llvm.func @roundtrip5() attributes {foo = "bar", baz = 42} 57 58 // CHECK: llvm.func @roundtrip6() 59 // CHECK: attributes {baz = 42 : i64, foo = "bar"} 60 llvm.func @roundtrip6() attributes {foo = "bar", baz = 42} { 61 llvm.return 62 } 63 64 // CHECK: llvm.func @roundtrip7() { 65 llvm.func @roundtrip7() attributes {} { 66 llvm.return 67 } 68 69 // CHECK: llvm.func @roundtrip8() -> !llvm.i32 70 llvm.func @roundtrip8() -> !llvm.i32 attributes {} 71 72 // CHECK: llvm.func @roundtrip9(!llvm.ptr<i32> {llvm.noalias = true}) 73 llvm.func @roundtrip9(!llvm.ptr<i32> {llvm.noalias = true}) 74 75 // CHECK: llvm.func @roundtrip10(!llvm.ptr<i32> {llvm.noalias = true}) 76 llvm.func @roundtrip10(%arg0: !llvm.ptr<i32> {llvm.noalias = true}) 77 78 // CHECK: llvm.func @roundtrip11(%{{.*}}: !llvm.ptr<i32> {llvm.noalias = true}) { 79 llvm.func @roundtrip11(%arg0: !llvm.ptr<i32> {llvm.noalias = true}) { 80 llvm.return 81 } 82 83 // CHECK: llvm.func @roundtrip12(%{{.*}}: !llvm.ptr<i32> {llvm.noalias = true}) 84 // CHECK: attributes {foo = 42 : i32} 85 llvm.func @roundtrip12(%arg0: !llvm.ptr<i32> {llvm.noalias = true}) 86 attributes {foo = 42 : i32} { 87 llvm.return 88 } 89 90 // CHECK: llvm.func @variadic(...) 91 llvm.func @variadic(...) 92 93 // CHECK: llvm.func @variadic_args(!llvm.i32, !llvm.i32, ...) 94 llvm.func @variadic_args(!llvm.i32, !llvm.i32, ...) 95 96 // 97 // Check that functions can have linkage attributes. 98 // 99 100 // CHECK: llvm.func internal 101 llvm.func internal @internal_func() { 102 llvm.return 103 } 104 105 // CHECK: llvm.func weak 106 llvm.func weak @weak_linkage() { 107 llvm.return 108 } 109 110 // Omit the `external` linkage, which is the default, in the custom format. 111 // Check that it is present in the generic format using its numeric value. 112 // 113 // CHECK: llvm.func @external_func 114 // GENERIC: linkage = 10 115 llvm.func external @external_func() 116} 117 118// ----- 119 120module { 121 // expected-error@+1 {{requires one region}} 122 "llvm.func"() {sym_name = "no_region", type = !llvm.func<void ()>} : () -> () 123} 124 125// ----- 126 127module { 128 // expected-error@+1 {{requires a type attribute 'type'}} 129 "llvm.func"() ({}) {sym_name = "missing_type"} : () -> () 130} 131 132// ----- 133 134module { 135 // expected-error@+1 {{requires 'type' attribute of wrapped LLVM function type}} 136 "llvm.func"() ({}) {sym_name = "non_llvm_type", type = i64} : () -> () 137} 138 139// ----- 140 141module { 142 // expected-error@+1 {{requires 'type' attribute of wrapped LLVM function type}} 143 "llvm.func"() ({}) {sym_name = "non_function_type", type = !llvm.i64} : () -> () 144} 145 146// ----- 147 148module { 149 // expected-error@+1 {{entry block must have 0 arguments}} 150 "llvm.func"() ({ 151 ^bb0(%arg0: !llvm.i64): 152 llvm.return 153 }) {sym_name = "wrong_arg_number", type = !llvm.func<void ()>} : () -> () 154} 155 156// ----- 157 158module { 159 // expected-error@+1 {{entry block argument #0 is not of LLVM type}} 160 "llvm.func"() ({ 161 ^bb0(%arg0: i64): 162 llvm.return 163 }) {sym_name = "wrong_arg_number", type = !llvm.func<void (i64)>} : () -> () 164} 165 166// ----- 167 168module { 169 // expected-error@+1 {{entry block argument #0 does not match the function signature}} 170 "llvm.func"() ({ 171 ^bb0(%arg0: !llvm.i32): 172 llvm.return 173 }) {sym_name = "wrong_arg_number", type = !llvm.func<void (i64)>} : () -> () 174} 175 176// ----- 177 178module { 179 // expected-error@+1 {{failed to construct function type: expected LLVM type for function arguments}} 180 llvm.func @foo(i64) 181} 182 183// ----- 184 185module { 186 // expected-error@+1 {{failed to construct function type: expected LLVM type for function results}} 187 llvm.func @foo() -> i64 188} 189 190// ----- 191 192module { 193 // expected-error@+1 {{failed to construct function type: expected zero or one function result}} 194 llvm.func @foo() -> (!llvm.i64, !llvm.i64) 195} 196 197// ----- 198 199module { 200 // expected-error@+1 {{only external functions can be variadic}} 201 llvm.func @variadic_def(...) { 202 llvm.return 203 } 204} 205 206// ----- 207 208module { 209 // expected-error@+1 {{variadic arguments must be in the end of the argument list}} 210 llvm.func @variadic_inside(%arg0: !llvm.i32, ..., %arg1: !llvm.i32) 211} 212 213// ----- 214 215module { 216 // expected-error@+1 {{external functions must have 'external' or 'extern_weak' linkage}} 217 llvm.func internal @internal_external_func() 218} 219 220// ----- 221 222module { 223 // expected-error@+1 {{functions cannot have 'common' linkage}} 224 llvm.func common @common_linkage_func() 225} 226