488 lines · plain
1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | mlir-opt | FileCheck %s2// RUN: mlir-opt -split-input-file -verify-diagnostics -mlir-print-op-generic %s | FileCheck %s --check-prefix=GENERIC3// RUN: mlir-opt -split-input-file -verify-diagnostics -mlir-print-debuginfo %s | mlir-opt -split-input-file -mlir-print-debuginfo | FileCheck %s --check-prefix=LOCINFO4// RUN: mlir-translate -mlir-to-llvmir -split-input-file -verify-diagnostics %s | FileCheck %s --check-prefix=CHECK-LLVM5 6module {7 // GENERIC: "llvm.func"8 // GENERIC-SAME: function_type = !llvm.func<void ()>9 // GENERIC-SAME: sym_name = "foo"10 // GENERIC: () -> ()11 // CHECK: llvm.func @foo()12 "llvm.func" () ({13 }) {sym_name = "foo", function_type = !llvm.func<void ()>} : () -> ()14 15 // GENERIC: "llvm.func"16 // GENERIC-SAME: function_type = !llvm.func<i64 (i64, i64)>17 // GENERIC-SAME: sym_name = "bar"18 // GENERIC: () -> ()19 // CHECK: llvm.func @bar(i64, i64) -> i6420 "llvm.func"() ({21 }) {sym_name = "bar", function_type = !llvm.func<i64 (i64, i64)>} : () -> ()22 23 // GENERIC: "llvm.func"24 // GENERIC-SAME: function_type = !llvm.func<i64 (i64)>25 // GENERIC-SAME: sym_name = "baz"26 // CHECK: llvm.func @baz(%{{.*}}: i64) -> i6427 "llvm.func"() <{sym_name = "baz", function_type = !llvm.func<i64 (i64)>}> ({28 // GENERIC: ^bb029 ^bb0(%arg0: i64):30 // GENERIC: llvm.return31 llvm.return %arg0 : i6432 33 // GENERIC: () -> ()34 }) : () -> ()35 36 // CHECK: llvm.func @qux(!llvm.ptr {llvm.noalias}, i64)37 // CHECK: attributes {xxx = {yyy = 42 : i64}}38 "llvm.func"() ({39 }) {sym_name = "qux", function_type = !llvm.func<void (ptr, i64)>,40 arg_attrs = [{llvm.noalias}, {}], xxx = {yyy = 42}} : () -> ()41 42 // CHECK: llvm.func @roundtrip1()43 llvm.func @roundtrip1()44 45 // CHECK: llvm.func @roundtrip2(i64, f32) -> f6446 llvm.func @roundtrip2(i64, f32) -> f6447 48 // CHECK: llvm.func @roundtrip3(i32, i1)49 llvm.func @roundtrip3(%a: i32, %b: i1)50 51 // CHECK: llvm.func @roundtrip4(%{{.*}}: i32, %{{.*}}: i1) {52 llvm.func @roundtrip4(%a: i32, %b: i1) {53 llvm.return54 }55 56 // CHECK: llvm.func @roundtrip5()57 // CHECK: attributes {baz = 42 : i64, foo = "bar"}58 llvm.func @roundtrip5() attributes {foo = "bar", baz = 42}59 60 // CHECK: llvm.func @roundtrip6()61 // CHECK: attributes {baz = 42 : i64, foo = "bar"}62 llvm.func @roundtrip6() attributes {foo = "bar", baz = 42} {63 llvm.return64 }65 66 // CHECK: llvm.func @roundtrip7() {67 llvm.func @roundtrip7() attributes {} {68 llvm.return69 }70 71 // CHECK: llvm.func @roundtrip8() -> i3272 llvm.func @roundtrip8() -> i32 attributes {}73 74 // CHECK: llvm.func @roundtrip9(!llvm.ptr {llvm.noalias})75 llvm.func @roundtrip9(!llvm.ptr {llvm.noalias})76 77 // CHECK: llvm.func @roundtrip10(!llvm.ptr {llvm.noalias})78 llvm.func @roundtrip10(%arg0: !llvm.ptr {llvm.noalias})79 80 // CHECK: llvm.func @roundtrip11(%{{.*}}: !llvm.ptr {llvm.noalias}) {81 llvm.func @roundtrip11(%arg0: !llvm.ptr {llvm.noalias}) {82 llvm.return83 }84 85 // CHECK: llvm.func @roundtrip12(%{{.*}}: !llvm.ptr {llvm.noalias})86 // CHECK: attributes {foo = 42 : i32}87 llvm.func @roundtrip12(%arg0: !llvm.ptr {llvm.noalias})88 attributes {foo = 42 : i32} {89 llvm.return90 }91 92 // CHECK: llvm.func @byvalattr(%{{.*}}: !llvm.ptr {llvm.byval = i32})93 llvm.func @byvalattr(%arg0: !llvm.ptr {llvm.byval = i32}) {94 llvm.return95 }96 97 // CHECK: llvm.func @sretattr(%{{.*}}: !llvm.ptr {llvm.sret = i32})98 // LOCINFO: llvm.func @sretattr(%{{.*}}: !llvm.ptr {llvm.sret = i32} loc("some_source_loc"))99 llvm.func @sretattr(%arg0: !llvm.ptr {llvm.sret = i32} loc("some_source_loc")) {100 llvm.return101 }102 103 // CHECK: llvm.func @nestattr(%{{.*}}: !llvm.ptr {llvm.nest})104 llvm.func @nestattr(%arg0: !llvm.ptr {llvm.nest}) {105 llvm.return106 }107 108 // CHECK: llvm.func @llvm_noalias_decl(!llvm.ptr {llvm.noalias})109 llvm.func @llvm_noalias_decl(!llvm.ptr {llvm.noalias})110 // CHECK: llvm.func @byrefattr_decl(!llvm.ptr {llvm.byref = i32})111 llvm.func @byrefattr_decl(!llvm.ptr {llvm.byref = i32})112 // CHECK: llvm.func @byvalattr_decl(!llvm.ptr {llvm.byval = i32})113 llvm.func @byvalattr_decl(!llvm.ptr {llvm.byval = i32})114 // CHECK: llvm.func @sretattr_decl(!llvm.ptr {llvm.sret = i32})115 llvm.func @sretattr_decl(!llvm.ptr {llvm.sret = i32})116 // CHECK: llvm.func @nestattr_decl(!llvm.ptr {llvm.nest})117 llvm.func @nestattr_decl(!llvm.ptr {llvm.nest})118 // CHECK: llvm.func @noundefattr_decl(i32 {llvm.noundef})119 llvm.func @noundefattr_decl(i32 {llvm.noundef})120 // CHECK: llvm.func @llvm_align_decl(!llvm.ptr {llvm.align = 4 : i64})121 llvm.func @llvm_align_decl(!llvm.ptr {llvm.align = 4})122 // CHECK: llvm.func @inallocaattr_decl(!llvm.ptr {llvm.inalloca = i32})123 llvm.func @inallocaattr_decl(!llvm.ptr {llvm.inalloca = i32})124 125 126 // CHECK: llvm.func @variadic(...)127 llvm.func @variadic(...)128 129 // CHECK: llvm.func @variadic_args(i32, i32, ...)130 llvm.func @variadic_args(i32, i32, ...)131 132 //133 // Check that functions can have linkage attributes.134 //135 136 // CHECK: llvm.func internal137 llvm.func internal @internal_func() {138 llvm.return139 }140 141 // CHECK: llvm.func weak142 llvm.func weak @weak_linkage() {143 llvm.return144 }145 146 // CHECK-LLVM: define ptx_kernel void @calling_conv147 llvm.func ptx_kernelcc @calling_conv() {148 llvm.return149 }150 151 // Omit the `external` linkage, which is the default, in the custom format.152 // Check that it is present in the generic format using its numeric value.153 //154 // CHECK: llvm.func @external_func155 // GENERIC: linkage = #llvm.linkage<external>156 llvm.func external @external_func()157 158 // CHECK-LABEL: llvm.func @arg_struct_attr(159 // CHECK-SAME: %{{.*}}: !llvm.struct<(i32)> {llvm.struct_attrs = [{llvm.noalias}]}) {160 llvm.func @arg_struct_attr(161 %arg0 : !llvm.struct<(i32)> {llvm.struct_attrs = [{llvm.noalias}]}) {162 llvm.return163 }164 165 // CHECK-LABEL: llvm.func @res_struct_attr(%{{.*}}: !llvm.struct<(i32)>)166 // CHECK-SAME:-> (!llvm.struct<(i32)> {llvm.struct_attrs = [{llvm.noalias}]}) {167 llvm.func @res_struct_attr(%arg0 : !llvm.struct<(i32)>)168 -> (!llvm.struct<(i32)> {llvm.struct_attrs = [{llvm.noalias}]}) {169 llvm.return %arg0 : !llvm.struct<(i32)>170 }171 172 // CHECK: llvm.func @cconv1173 llvm.func ccc @cconv1() {174 llvm.return175 }176 177 // CHECK: llvm.func weak @cconv2178 llvm.func weak ccc @cconv2() {179 llvm.return180 }181 182 // CHECK: llvm.func weak fastcc @cconv3183 llvm.func weak fastcc @cconv3() {184 llvm.return185 }186 187 // CHECK: llvm.func cc_10 @cconv4188 llvm.func cc_10 @cconv4() {189 llvm.return190 }191 192 // CHECK: llvm.func @test_ccs193 llvm.func @test_ccs() {194 // CHECK-NEXT: %[[PTR:.*]] = llvm.mlir.addressof @cconv4 : !llvm.ptr195 %ptr = llvm.mlir.addressof @cconv4 : !llvm.ptr196 // CHECK-NEXT: llvm.call @cconv1() : () -> ()197 // CHECK-NEXT: llvm.call @cconv2() : () -> ()198 // CHECK-NEXT: llvm.call fastcc @cconv3() : () -> ()199 // CHECK-NEXT: llvm.call cc_10 %[[PTR]]() : !llvm.ptr, () -> ()200 llvm.call @cconv1() : () -> ()201 llvm.call ccc @cconv2() : () -> ()202 llvm.call fastcc @cconv3() : () -> ()203 llvm.call cc_10 %ptr() : !llvm.ptr, () -> ()204 llvm.return205 }206 207 // CHECK-LABEL: llvm.func @variadic_def208 llvm.func @variadic_def(...) {209 llvm.return210 }211 212 // CHECK-LABEL: llvm.func @memory_attr213 // CHECK-SAME: attributes {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>} {214 llvm.func @memory_attr() attributes {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>} {215 llvm.return216 }217 218 // CHECK-LABEL: llvm.func hidden @hidden219 llvm.func hidden @hidden() {220 llvm.return221 }222 223 // CHECK-LABEL: llvm.func protected @protected224 llvm.func protected @protected() {225 llvm.return226 }227 228 // CHECK-LABEL: local_unnamed_addr @local_unnamed_addr_func229 llvm.func local_unnamed_addr @local_unnamed_addr_func() {230 llvm.return231 }232 233 // CHECK-LABEL: @align_func234 // CHECK-SAME: attributes {alignment = 2 : i64}235 llvm.func @align_func() attributes {alignment = 2 : i64} {236 llvm.return237 }238 239 // CHECK: llvm.comdat @__llvm_comdat240 llvm.comdat @__llvm_comdat {241 // CHECK: llvm.comdat_selector @any any242 llvm.comdat_selector @any any243 }244 // CHECK: @any() comdat(@__llvm_comdat::@any) attributes245 llvm.func @any() comdat(@__llvm_comdat::@any) attributes { dso_local } {246 llvm.return247 }248 249 llvm.func @vscale_roundtrip() vscale_range(1, 2) {250 // CHECK: @vscale_roundtrip251 // CHECK-SAME: vscale_range(1, 2)252 llvm.return253 }254 255 // CHECK-LABEL: @frame_pointer_roundtrip()256 // CHECK-SAME: attributes {frame_pointer = #llvm.framePointerKind<"non-leaf">}257 llvm.func @frame_pointer_roundtrip() attributes {frame_pointer = #llvm.framePointerKind<"non-leaf">} {258 llvm.return259 }260 261 llvm.func @no_infs_fp_math_roundtrip() attributes {no_infs_fp_math = true} {262 // CHECK: @no_infs_fp_math_roundtrip263 // CHECK-SAME: attributes {no_infs_fp_math = true}264 llvm.return265 }266 267 llvm.func @no_nans_fp_math_roundtrip() attributes {no_nans_fp_math = true} {268 // CHECK: @no_nans_fp_math_roundtrip269 // CHECK-SAME: attributes {no_nans_fp_math = true}270 llvm.return271 }272 273 llvm.func @no_signed_zeros_fp_math_roundtrip() attributes {no_signed_zeros_fp_math = true} {274 // CHECK: @no_signed_zeros_fp_math_roundtrip275 // CHECK-SAME: attributes {no_signed_zeros_fp_math = true}276 llvm.return277 }278 279 llvm.func @convergent_function() attributes {convergent} {280 // CHECK: @convergent_function281 // CHECK-SAME: attributes {convergent}282 llvm.return283 }284 285 llvm.func @denormal_fp_math_roundtrip() attributes {denormal_fp_math = "preserve-sign"} {286 // CHECK: @denormal_fp_math_roundtrip287 // CHECK-SAME: attributes {denormal_fp_math = "preserve-sign"}288 llvm.return289 }290 291 llvm.func @denormal_fp_math_f32_roundtrip() attributes {denormal_fp_math_f32 = "preserve-sign"} {292 // CHECK: @denormal_fp_math_f32_roundtrip293 // CHECK-SAME: attributes {denormal_fp_math_f32 = "preserve-sign"}294 llvm.return295 }296 297 llvm.func @fp_contract_roundtrip() attributes {fp_contract = "fast"} {298 // CHECK: @fp_contract_roundtrip299 // CHECK-SAME: attributes {fp_contract = "fast"}300 llvm.return301 }302 303 llvm.func @instrument_function_entry_function() attributes {instrument_function_entry = "__cyg_profile_func_enter"} {304 // CHECK: @instrument_function_entry_function305 // CHECK-SAME: attributes {instrument_function_entry = "__cyg_profile_func_enter"}306 llvm.return307 }308 309 llvm.func @instrument_function_exit_function() attributes {instrument_function_exit = "__cyg_profile_func_exit"} {310 // CHECK: @instrument_function_exit_function311 // CHECK-SAME: attributes {instrument_function_exit = "__cyg_profile_func_exit"}312 llvm.return313 }314 315 llvm.func @nounwind_function() attributes {no_unwind} {316 // CHECK: @nounwind_function317 // CHECK-SAME: attributes {no_unwind}318 llvm.return319 }320 321 llvm.func @willreturn_function() attributes {will_return} {322 // CHECK: @willreturn_function323 // CHECK-SAME: attributes {will_return}324 llvm.return325 }326 327 328}329 330// -----331 332module {333 // expected-error@+1 {{requires one region}}334 "llvm.func"() {function_type = !llvm.func<void ()>, sym_name = "no_region"} : () -> ()335}336 337// -----338 339module {340 // expected-error@+1 {{requires attribute 'function_type'}}341 "llvm.func"() ({}) {sym_name = "missing_type"} : () -> ()342}343 344// -----345 346module {347 // expected-error@+1 {{attribute 'function_type' failed to satisfy constraint: type attribute of LLVM function type}}348 "llvm.func"() ({}) {sym_name = "non_llvm_type", function_type = i64} : () -> ()349}350 351// -----352 353module {354 // expected-error@+1 {{attribute 'function_type' failed to satisfy constraint: type attribute of LLVM function type}}355 "llvm.func"() ({}) {sym_name = "non_function_type", function_type = i64} : () -> ()356}357 358// -----359 360module {361 // expected-error@+1 {{entry block must have 0 arguments}}362 "llvm.func"() ({363 ^bb0(%arg0: i64):364 llvm.return365 }) {function_type = !llvm.func<void ()>, sym_name = "wrong_arg_number"} : () -> ()366}367 368// -----369 370module {371 // expected-error@+1 {{entry block argument #0('tensor<*xf32>') must match the type of the corresponding argument in function signature('i64')}}372 "llvm.func"() ({373 ^bb0(%arg0: tensor<*xf32>):374 llvm.return375 }) {function_type = !llvm.func<void (i64)>, sym_name = "wrong_arg_number"} : () -> ()376}377 378// -----379 380module {381 // expected-error@+1 {{failed to construct function type: expected LLVM type for function arguments}}382 llvm.func @foo(tensor<*xf32>)383}384 385// -----386 387module {388 // expected-error@+1 {{failed to construct function type: expected LLVM type for function results}}389 llvm.func @foo() -> tensor<*xf32>390}391 392// -----393 394module {395 // expected-error@+1 {{failed to construct function type: expected zero or one function result}}396 llvm.func @foo() -> (i64, i64)397}398 399// -----400 401module {402 // expected-error@+1 {{variadic arguments must be in the end of the argument list}}403 llvm.func @variadic_inside(%arg0: i32, ..., %arg1: i32)404}405 406// -----407 408module {409 // expected-error@+1 {{external functions must have 'external' or 'extern_weak' linkage}}410 llvm.func internal @internal_external_func()411}412 413// -----414 415module {416 // expected-error@+1 {{functions cannot have 'common' linkage}}417 llvm.func common @common_linkage_func()418}419 420// -----421 422module {423 // expected-error@+1 {{custom op 'llvm.func' expected valid '@'-identifier for symbol name}}424 llvm.func cc_12 @unknown_calling_convention()425}426 427// -----428 429module {430 "llvm.func"() ({431 // expected-error @below {{expected one of [ccc, fastcc, coldcc, cc_10, cc_11, anyregcc, preserve_mostcc, preserve_allcc, swiftcc, cxx_fast_tlscc, tailcc, cfguard_checkcc, swifttailcc, x86_stdcallcc, x86_fastcallcc, arm_apcscc, arm_aapcscc, arm_aapcs_vfpcc, msp430_intrcc, x86_thiscallcc, ptx_kernelcc, ptx_devicecc, spir_funccc, spir_kernelcc, intel_ocl_bicc, x86_64_sysvcc, win64cc, x86_vectorcallcc, hhvmcc, hhvm_ccc, x86_intrcc, avr_intrcc, avr_builtincc, amdgpu_vscc, amdgpu_gscc, amdgpu_cscc, amdgpu_kernelcc, x86_regcallcc, amdgpu_hscc, msp430_builtincc, amdgpu_lscc, amdgpu_escc, aarch64_vectorcallcc, aarch64_sve_vectorcallcc, wasm_emscripten_invokecc, amdgpu_gfxcc, m68k_intrcc] for Calling Conventions, got: cc_12}}432 // expected-error @below {{failed to parse CConvAttr parameter 'CallingConv' which is to be a `CConv`}}433 }) {sym_name = "generic_unknown_calling_convention", CConv = #llvm.cconv<cc_12>, function_type = !llvm.func<i64 (i64, i64)>} : () -> ()434}435 436// -----437 438// CHECK: @vec_type_hint()439// CHECK-SAME: vec_type_hint = #llvm.vec_type_hint<hint = i32>440llvm.func @vec_type_hint() attributes {vec_type_hint = #llvm.vec_type_hint<hint = i32>}441 442// CHECK: @vec_type_hint_signed()443// CHECK-SAME: vec_type_hint = #llvm.vec_type_hint<hint = i32, is_signed = true>444llvm.func @vec_type_hint_signed() attributes {vec_type_hint = #llvm.vec_type_hint<hint = i32, is_signed = true>}445 446// CHECK: @vec_type_hint_signed_vec()447// CHECK-SAME: vec_type_hint = #llvm.vec_type_hint<hint = vector<2xi32>, is_signed = true>448llvm.func @vec_type_hint_signed_vec() attributes {vec_type_hint = #llvm.vec_type_hint<hint = vector<2xi32>, is_signed = true>}449 450// CHECK: @vec_type_hint_float_vec()451// CHECK-SAME: vec_type_hint = #llvm.vec_type_hint<hint = vector<3xf32>>452llvm.func @vec_type_hint_float_vec() attributes {vec_type_hint = #llvm.vec_type_hint<hint = vector<3xf32>>}453 454// CHECK: @vec_type_hint_bfloat_vec()455// CHECK-SAME: vec_type_hint = #llvm.vec_type_hint<hint = vector<8xbf16>>456llvm.func @vec_type_hint_bfloat_vec() attributes {vec_type_hint = #llvm.vec_type_hint<hint = vector<8xbf16>>}457 458// -----459 460// CHECK: @work_group_size_hint()461// CHECK-SAME: work_group_size_hint = array<i32: 128, 128, 128>462llvm.func @work_group_size_hint() attributes {work_group_size_hint = array<i32: 128, 128, 128>}463 464// -----465 466// CHECK: @reqd_work_group_size_hint()467// CHECK-SAME: reqd_work_group_size = array<i32: 128, 256, 128>468llvm.func @reqd_work_group_size_hint() attributes {reqd_work_group_size = array<i32: 128, 256, 128>}469 470// -----471 472// CHECK: @intel_reqd_sub_group_size_hint()473// CHECK-SAME: intel_reqd_sub_group_size = 32 : i32474llvm.func @intel_reqd_sub_group_size_hint() attributes {llvm.intel_reqd_sub_group_size = 32 : i32}475 476// -----477 478// CHECK: @workgroup_attribution479// CHECK-SAME: llvm.workgroup_attribution = #llvm.mlir.workgroup_attribution<512 : i64, i32>480// CHECK-SAME: llvm.workgroup_attribution = #llvm.mlir.workgroup_attribution<128 : i64, !llvm.struct<(i32, i64, f32)>481llvm.func @workgroup_attribution(%arg0: !llvm.ptr {llvm.workgroup_attribution = #llvm.mlir.workgroup_attribution<512 : i64, i32>}, %arg1: !llvm.ptr {llvm.workgroup_attribution = #llvm.mlir.workgroup_attribution<128 : i64, !llvm.struct<(i32, i64, f32)>>})482 483// -----484 485// CHECK: @constant_range_negative486// CHECK-SAME: llvm.range = #llvm.constant_range<i32, 0, -2147483648>487llvm.func @constant_range_negative() -> (i32 {llvm.range = #llvm.constant_range<i32, 0, -2147483648>})488