xref: /llvm-project/mlir/test/Target/LLVMIR/llvmir-debug.mlir (revision 3b35b4c7f9141c59fbac415e335489494b7d507e)
1// RUN: mlir-translate -mlir-to-llvmir --write-experimental-debuginfo=false --split-input-file %s | FileCheck %s --check-prefixes=CHECK,INTRINSICS
2// RUN: mlir-translate -mlir-to-llvmir --write-experimental-debuginfo=true --split-input-file %s | FileCheck %s --check-prefixes=CHECK,RECORDS
3
4// CHECK-LABEL: define void @func_with_empty_named_info()
5// Check that translation doens't crash in the presence of an inlineble call
6// with a named loc that has no backing source info.
7llvm.func @callee() {
8  llvm.return
9} loc("calleesource.cc":1:1)
10llvm.func @func_with_empty_named_info() {
11  llvm.call @callee() : () -> () loc("named with no line info")
12  llvm.return
13}
14
15// CHECK-LABEL: define void @func_no_debug()
16// CHECK-NOT: !dbg
17llvm.func @func_no_debug() {
18  llvm.return loc(unknown)
19} loc(unknown)
20
21#file = #llvm.di_file<"foo.mlir" in "/test/">
22#si64 = #llvm.di_basic_type<
23  // Omit the optional sizeInBits and encoding parameters.
24  tag = DW_TAG_base_type, name = "si64"
25>
26#si32 = #llvm.di_basic_type<
27  tag = DW_TAG_base_type, name = "si32",
28  sizeInBits = 32, encoding = DW_ATE_signed
29>
30#ptr = #llvm.di_derived_type<
31  tag = DW_TAG_pointer_type, baseType = #si32,
32  sizeInBits = 64, alignInBits = 32, offsetInBits = 8,
33  extraData = #si32
34>
35#named = #llvm.di_derived_type<
36  // Specify the name parameter.
37  tag = DW_TAG_pointer_type, name = "named", baseType = #si32
38>
39#ptrWithAddressSpace = #llvm.di_derived_type<
40  tag = DW_TAG_pointer_type, baseType = #si32,
41  sizeInBits = 64, alignInBits = 32, offsetInBits = 8,
42  dwarfAddressSpace = 3
43>
44#cu = #llvm.di_compile_unit<
45  id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #file,
46  producer = "MLIR", isOptimized = true, emissionKind = Full,
47  nameTableKind = None
48>
49#composite = #llvm.di_composite_type<
50  tag = DW_TAG_structure_type, name = "composite", file = #file,
51  line = 42, sizeInBits = 64, alignInBits = 32,
52  elements = #llvm.di_subrange<count = 4>
53>
54#vector = #llvm.di_composite_type<
55  tag = DW_TAG_array_type, name = "array", file = #file,
56  baseType = #si64, flags = Vector,
57  elements = #llvm.di_subrange<lowerBound = 0, upperBound = 4, stride = 1>
58>
59#null = #llvm.di_null_type
60#spType0 = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #null, #si64, #ptr, #named, #ptrWithAddressSpace, #composite, #vector>
61#toplevel_namespace = #llvm.di_namespace<
62  name = "toplevel", exportSymbols = true
63>
64#nested_namespace = #llvm.di_namespace<
65  name = "nested", scope = #toplevel_namespace, exportSymbols = false
66>
67#sp0 = #llvm.di_subprogram<
68  compileUnit = #cu, scope = #nested_namespace, name = "func_with_debug", linkageName = "func_with_debug",
69  file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType0
70>
71#calleeType = #llvm.di_subroutine_type<
72  // Omit the optional callingConvention parameter.
73  types = #si64, #si64>
74#callee = #llvm.di_subprogram<
75  // Omit the optional linkageName, line, and scopeLine parameters.
76  compileUnit = #cu, scope = #composite, name = "callee",
77  file = #file, subprogramFlags = "Definition", type = #calleeType
78>
79#fileScope = #llvm.di_lexical_block_file<scope = #sp0, file = #file, discriminator = 0>
80#blockScope = #llvm.di_lexical_block<scope = #sp0>
81#variable = #llvm.di_local_variable<scope = #fileScope, name = "arg", file = #file, line = 6, arg = 1, alignInBits = 32, type = #si64>
82#variableAddr = #llvm.di_local_variable<scope = #blockScope, name = "alloc">
83#noNameVariable = #llvm.di_local_variable<scope = #blockScope>
84#module = #llvm.di_module<
85  file = #file, scope = #file, name = "module",
86  configMacros = "bar", includePath = "/",
87  apinotes = "/", line = 42, isDecl = true
88>
89#spType1 = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
90#sp1 = #llvm.di_subprogram<
91  compileUnit = #cu, scope = #module, name = "empty_types",
92  file = #file, subprogramFlags = "Definition", type = #spType1,
93  annotations = #llvm.di_annotation<name = "foo", value = "bar">
94>
95
96// CHECK-LABEL: define void @func_with_debug(
97// CHECK-SAME: i64 %[[ARG:.*]]) !dbg ![[FUNC_LOC:[0-9]+]]
98llvm.func @func_with_debug(%arg: i64) {
99  // CHECK: %[[ALLOC:.*]] = alloca
100  %allocCount = llvm.mlir.constant(1 : i32) : i32
101  %alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr
102
103  // INTRINSICS: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 1))
104  // RECORDS: #dbg_value(i64 %[[ARG]], ![[VAR_LOC:[0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 1), !{{.*}})
105  llvm.intr.dbg.value #variable #llvm.di_expression<[DW_OP_LLVM_fragment(0, 1)]> = %arg : i64
106
107  // INTRINSICS: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[ADDR_LOC:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_LLVM_convert, 4, DW_ATE_signed))
108  // RECORDS: #dbg_declare(ptr %[[ALLOC]], ![[ADDR_LOC:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_LLVM_convert, 4, DW_ATE_signed), !{{.*}})
109  llvm.intr.dbg.declare #variableAddr #llvm.di_expression<[DW_OP_deref, DW_OP_LLVM_convert(4, DW_ATE_signed)]> = %alloc : !llvm.ptr
110
111  // INTRINSICS: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[NO_NAME_VAR:[0-9]+]], metadata !DIExpression())
112  // RECORDS: #dbg_value(i64 %[[ARG]], ![[NO_NAME_VAR:[0-9]+]], !DIExpression(), !{{.*}})
113  llvm.intr.dbg.value #noNameVariable = %arg : i64
114
115  // CHECK: call void @func_no_debug(), !dbg ![[FILE_LOC:[0-9]+]]
116  llvm.call @func_no_debug() : () -> () loc("foo.mlir":1:2)
117
118  // CHECK: call void @func_no_debug(), !dbg ![[FILE_LOC:[0-9]+]]
119  llvm.call @func_no_debug() : () -> () loc("foo.mlir":1:2 to 5:6)
120
121  // CHECK: call void @func_no_debug(), !dbg ![[NAMED_LOC:[0-9]+]]
122  llvm.call @func_no_debug() : () -> () loc("named"("foo.mlir":10:10))
123
124  // CHECK: call void @func_no_debug(), !dbg ![[MY_SOURCE_LOC:[0-9]+]]
125  llvm.call @func_no_debug() : () -> () loc(callsite("nodebug.cc":3:4 at "mysource.cc":5:6))
126
127  // CHECK: call void @func_no_debug(), !dbg ![[MY_SOURCE_LOC]]
128  llvm.call @func_no_debug() : () -> () loc(callsite("nodebug.cc":3:4 at fused<#sp0>["mysource.cc":5:6]))
129
130  // CHECK: call void @func_no_debug(), !dbg ![[FUSED_LOC:[0-9]+]]
131  llvm.call @func_no_debug() : () -> () loc(fused[callsite(fused<#callee>["mysource.cc":5:6] at "mysource.cc":1:1), "mysource.cc":1:1])
132
133  // CHECK: call void @func_no_debug(), !dbg ![[FUSEDWITH_LOC:[0-9]+]]
134  llvm.call @func_no_debug() : () -> () loc(callsite(callsite(fused<#callee>["foo.mlir":2:4] at "foo.mlir":1:1) at fused<#sp0>["foo.mlir":28:5]))
135
136  // CHECK: add i64 %[[ARG]], %[[ARG]], !dbg ![[FUSEDWITH_LOC]]
137  %sum = llvm.add %arg, %arg : i64 loc(callsite(fused<#callee>["foo.mlir":2:4] at fused<#sp0>["foo.mlir":28:5]))
138
139  llvm.return
140} loc(fused<#sp0>["foo.mlir":1:1])
141
142// CHECK: define void @empty_types() !dbg ![[EMPTY_TYPES_LOC:[0-9]+]]
143llvm.func @empty_types() {
144  llvm.return
145} loc(fused<#sp1>["foo.mlir":2:1])
146
147// CHECK: ![[CU_LOC:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[CU_FILE_LOC:.*]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, nameTableKind: None)
148// CHECK: ![[CU_FILE_LOC]] = !DIFile(filename: "foo.mlir", directory: "/test/")
149
150// CHECK: ![[FUNC_LOC]] = distinct !DISubprogram(name: "func_with_debug", linkageName: "func_with_debug", scope: ![[NESTED_NAMESPACE:.*]], file: ![[CU_FILE_LOC]], line: 3, type: ![[FUNC_TYPE:.*]], scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU_LOC]])
151// CHECK: ![[NESTED_NAMESPACE]] = !DINamespace(name: "nested", scope: ![[TOPLEVEL_NAMESPACE:.*]])
152// CHECK: ![[TOPLEVEL_NAMESPACE]] = !DINamespace(name: "toplevel", scope: null, exportSymbols: true)
153// CHECK: ![[FUNC_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[FUNC_ARGS:.*]])
154// CHECK: ![[FUNC_ARGS]] = !{null, ![[ARG_TYPE:.*]], ![[PTR_TYPE:.*]], ![[NAMED_TYPE:.*]], ![[PTR_WITH_ADDR_SPACE:.*]], ![[COMPOSITE_TYPE:.*]], ![[VECTOR_TYPE:.*]]}
155// CHECK: ![[ARG_TYPE]] = !DIBasicType(name: "si64")
156// CHECK: ![[PTR_TYPE]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BASE_TYPE:.*]], size: 64, align: 32, offset: 8, extraData: ![[BASE_TYPE]])
157// CHECK: ![[BASE_TYPE]] = !DIBasicType(name: "si32", size: 32, encoding: DW_ATE_signed)
158// CHECK: ![[NAMED_TYPE]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "named", baseType: ![[BASE_TYPE:.*]])
159// CHECK: ![[PTR_WITH_ADDR_SPACE]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BASE_TYPE:.*]], size: 64, align: 32, offset: 8, dwarfAddressSpace: 3)
160// CHECK: ![[COMPOSITE_TYPE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "composite", file: ![[CU_FILE_LOC]], line: 42, size: 64, align: 32, elements: ![[COMPOSITE_ELEMENTS:.*]])
161// CHECK: ![[COMPOSITE_ELEMENTS]] = !{![[COMPOSITE_ELEMENT:.*]]}
162// CHECK: ![[COMPOSITE_ELEMENT]] = !DISubrange(count: 4)
163// CHECK: ![[VECTOR_TYPE]] = !DICompositeType(tag: DW_TAG_array_type, name: "array", file: ![[CU_FILE_LOC]], baseType: ![[ARG_TYPE]], flags: DIFlagVector, elements: ![[VECTOR_ELEMENTS:.*]])
164// CHECK: ![[VECTOR_ELEMENTS]] = !{![[VECTOR_ELEMENT:.*]]}
165// CHECK: ![[VECTOR_ELEMENT]] = !DISubrange(lowerBound: 0, upperBound: 4, stride: 1)
166
167// CHECK: ![[VAR_LOC]] = !DILocalVariable(name: "arg", arg: 1, scope: ![[VAR_SCOPE:.*]], file: ![[CU_FILE_LOC]], line: 6, type: ![[ARG_TYPE]], align: 32)
168// CHECK: ![[VAR_SCOPE]] = distinct !DILexicalBlockFile(scope: ![[FUNC_LOC]], file: ![[CU_FILE_LOC]], discriminator: 0)
169// CHECK: ![[ADDR_LOC]] = !DILocalVariable(name: "alloc", scope: ![[BLOCK_LOC:.*]])
170// CHECK: ![[BLOCK_LOC]] = distinct !DILexicalBlock(scope: ![[FUNC_LOC]])
171// CHECK: ![[NO_NAME_VAR]] = !DILocalVariable(scope: ![[BLOCK_LOC]])
172
173// CHECK-DAG: ![[MY_SOURCE_LOC]] = !DILocation(line: 5, column: 6
174// CHECK-DAG: ![[FILE_LOC]] = !DILocation(line: 1, column: 2,
175// CHECK-DAG: ![[NAMED_LOC]] = !DILocation(line: 10, column: 10
176// CHECK-DAG: ![[FUSED_LOC]] = !DILocation(line: 1, column: 1
177
178// CHECK: ![[FUSEDWITH_LOC]] = !DILocation(line: 2, column: 4, scope: ![[CALLEE_LOC:.*]], inlinedAt: ![[INLINE_LOC:.*]])
179// CHECK: ![[CALLEE_LOC]] = distinct !DISubprogram(name: "callee", scope: ![[COMPOSITE_TYPE]], file: ![[CU_FILE_LOC]], type: ![[CALLEE_TYPE:.*]], spFlags: DISPFlagDefinition, unit: ![[CU_LOC]])
180// CHECK: ![[CALLEE_TYPE]] = !DISubroutineType(types: ![[CALLEE_ARGS:.*]])
181// CHECK: ![[CALLEE_ARGS]] = !{![[ARG_TYPE:.*]], ![[ARG_TYPE:.*]]}
182// CHECK: ![[INLINE_LOC]] = !DILocation(line: 28, column: 5,
183
184// CHECK: ![[EMPTY_TYPES_LOC]] = distinct !DISubprogram(name: "empty_types", scope: ![[MODULE:.*]], file: ![[CU_FILE_LOC]], type: ![[EMPTY_TYPES_TYPE:.*]], spFlags: DISPFlagDefinition, unit: ![[CU_LOC]], annotations: ![[ANNOTATIONS:.*]])
185// CHECK: ![[MODULE]] = !DIModule(scope: ![[CU_FILE_LOC]], name: "module", configMacros: "bar", includePath: "/", apinotes: "/", file: ![[CU_FILE_LOC]], line: 42, isDecl: true)
186// CHECK: ![[EMPTY_TYPES_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[EMPTY_TYPES_ARGS:.*]])
187// CHECK: ![[EMPTY_TYPES_ARGS]] = !{}
188
189// CHECK: ![[ANNOTATIONS]] = !{![[ANNOTATION:.*]]}
190// CHECK: ![[ANNOTATION]] = !{!"foo", !"bar"}
191
192// -----
193
194#di_file = #llvm.di_file<"foo.mlir" in "/test/">
195#di_subprogram = #llvm.di_subprogram<
196  scope = #di_file, name = "func_decl_with_subprogram", file = #di_file
197>
198
199// CHECK-LABEL: declare !dbg
200// CHECK-SAME: ![[SUBPROGRAM:.*]] i32 @func_decl_with_subprogram(
201llvm.func @func_decl_with_subprogram() -> (i32) loc(fused<#di_subprogram>["foo.mlir":2:1])
202
203// CHECK: ![[SUBPROGRAM]] = !DISubprogram(name: "func_decl_with_subprogram", scope: ![[FILE:.*]], file: ![[FILE]], spFlags: 0)
204// CHECK: ![[FILE]] = !DIFile(filename: "foo.mlir", directory: "/test/")
205
206// -----
207
208#di_basic_type = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32, encoding = DW_ATE_signed>
209#di_file = #llvm.di_file<"foo.mlir" in "/test/">
210#di_compile_unit = #llvm.di_compile_unit<
211  id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file,
212  producer = "MLIR", isOptimized = true, emissionKind = Full
213>
214#di_subprogram = #llvm.di_subprogram<
215  compileUnit = #di_compile_unit, scope = #di_file, name = "outer_func",
216  file = #di_file, subprogramFlags = "Definition|Optimized"
217>
218#di_subprogram1 = #llvm.di_subprogram<
219  compileUnit = #di_compile_unit, scope = #di_file, name = "inner_func",
220  file = #di_file, subprogramFlags = "LocalToUnit|Definition|Optimized"
221>
222#di_local_variable0 = #llvm.di_local_variable<scope = #di_subprogram, name = "a", file = #di_file, type = #di_basic_type>
223#di_lexical_block_file = #llvm.di_lexical_block_file<scope = #di_subprogram1, file = #di_file, discriminator = 0>
224#di_local_variable1 = #llvm.di_local_variable<scope = #di_lexical_block_file, name = "b", file = #di_file, type = #di_basic_type>
225#di_label = #llvm.di_label<scope = #di_lexical_block_file, name = "label", file = #di_file, line = 42>
226
227#loc0 = loc("foo.mlir":0:0)
228#loc1 = loc(callsite(fused<#di_lexical_block_file>[#loc0] at fused<#di_subprogram>["foo.mlir":4:2]))
229
230// CHECK-LABEL: define i32 @func_with_inlined_dbg_value(
231// CHECK-SAME: i32 %[[ARG:.*]]) !dbg ![[OUTER_FUNC:[0-9]+]]
232llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
233  // INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC0:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
234  // RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC0:[0-9]+]], !DIExpression(), ![[DBG_LOC0:.*]])
235  llvm.intr.dbg.value #di_local_variable0 = %arg0 : i32 loc(fused<#di_subprogram>[#loc0])
236  // INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC1:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC1:.*]]
237  // RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC1:[0-9]+]], !DIExpression(), ![[DBG_LOC1:.*]])
238  llvm.intr.dbg.value #di_local_variable1 = %arg0 : i32 loc(#loc1)
239  // INTRINSICS: call void @llvm.dbg.label(metadata ![[LABEL:[0-9]+]]), !dbg ![[DBG_LOC1:.*]]
240  // RECORDS: #dbg_label(![[LABEL:[0-9]+]], ![[DBG_LOC1:.*]])
241  llvm.intr.dbg.label #di_label loc(#loc1)
242  llvm.return %arg0 : i32
243} loc(fused<#di_subprogram>["caller"])
244
245// CHECK: ![[FILE:.*]] = !DIFile(filename: "foo.mlir", directory: "/test/")
246// CHECK-DAG: ![[OUTER_FUNC]] = distinct !DISubprogram(name: "outer_func", scope: ![[FILE]]
247// CHECK-DAG: ![[INNER_FUNC:.*]] = distinct !DISubprogram(name: "inner_func", scope: ![[FILE]]
248// CHECK-DAG: ![[LEXICAL_BLOCK_FILE:.*]] = distinct !DILexicalBlockFile(scope: ![[INNER_FUNC]], file: ![[FILE]], discriminator: 0)
249// CHECK-DAG: ![[VAR_LOC0]] = !DILocalVariable(name: "a", scope: ![[OUTER_FUNC]], file: ![[FILE]]
250// CHECK-DAG: ![[VAR_LOC1]] = !DILocalVariable(name: "b", scope: ![[LEXICAL_BLOCK_FILE]], file: ![[FILE]]
251// CHECK-DAG: ![[LABEL]] = !DILabel(scope: ![[LEXICAL_BLOCK_FILE]], name: "label", file: ![[FILE]], line: 42)
252
253// -----
254
255#di_basic_type = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32, encoding = DW_ATE_signed>
256#di_file = #llvm.di_file<"foo.mlir" in "/test/">
257#di_compile_unit = #llvm.di_compile_unit<
258  id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file,
259  producer = "MLIR", isOptimized = true, emissionKind = Full
260>
261#di_subprogram = #llvm.di_subprogram<
262  compileUnit = #di_compile_unit, scope = #di_file, name = "func",
263  file = #di_file, subprogramFlags = Definition>
264#di_local_variable = #llvm.di_local_variable<scope = #di_subprogram, name = "a", file = #di_file, type = #di_basic_type>
265
266#loc = loc("foo.mlir":0:0)
267
268// CHECK-LABEL: define void @func_without_subprogram(
269// CHECK-SAME: i32 %[[ARG:.*]])
270llvm.func @func_without_subprogram(%0 : i32) {
271  // INTRINSICS: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
272  // RECORDS: #dbg_value(i32 %[[ARG]], ![[VAR_LOC:[0-9]+]], !DIExpression(), ![[DBG_LOC0:.*]])
273  llvm.intr.dbg.value #di_local_variable = %0 : i32 loc(fused<#di_subprogram>[#loc])
274  llvm.return
275}
276
277// CHECK: ![[FILE:.*]] = !DIFile(filename: "foo.mlir", directory: "/test/")
278// CHECK-DAG: ![[FUNC:.*]] = distinct !DISubprogram(name: "func", scope: ![[FILE]]
279// CHECK-DAG: ![[VAR_LOC]] = !DILocalVariable(name: "a", scope: ![[FUNC]], file: ![[FILE]]
280
281// -----
282
283// Ensures that debug intrinsics without a valid location are not exported to
284// avoid broken LLVM IR.
285
286#di_file = #llvm.di_file<"foo.mlir" in "/test/">
287#di_compile_unit = #llvm.di_compile_unit<
288  id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file,
289  producer = "MLIR", isOptimized = true, emissionKind = Full
290>
291#di_subprogram = #llvm.di_subprogram<
292  compileUnit = #di_compile_unit, scope = #di_file, name = "outer_func",
293  file = #di_file, subprogramFlags = "Definition|Optimized"
294>
295#di_local_variable = #llvm.di_local_variable<scope = #di_subprogram, name = "a">
296#declared_var = #llvm.di_local_variable<scope = #di_subprogram, name = "alloc">
297#di_label = #llvm.di_label<scope = #di_subprogram, name = "label", file = #di_file, line = 42>
298
299// CHECK-LABEL: define i32 @dbg_intrinsics_with_no_location(
300llvm.func @dbg_intrinsics_with_no_location(%arg0: i32) -> (i32) {
301  %allocCount = llvm.mlir.constant(1 : i32) : i32
302  %alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr
303  // INTRINSICS-NOT: @llvm.dbg.value
304  // RECORDS-NOT: #dbg_value
305  llvm.intr.dbg.value #di_local_variable = %arg0 : i32
306  // INTRINSICS-NOT: @llvm.dbg.declare
307  // RECORDS-NOT: #dbg_declare
308  llvm.intr.dbg.declare #declared_var = %alloc : !llvm.ptr
309  // INTRINSICS-NOT: @llvm.dbg.label
310  // RECORDS-NOT: #dbg_label
311  llvm.intr.dbg.label #di_label
312  llvm.return %arg0 : i32
313}
314
315// -----
316
317// CHECK: @global_with_expr_1 = external global i64, !dbg {{.*}}
318// CHECK: @global_with_expr_2 = external global i64, !dbg {{.*}}
319// CHECK: !llvm.module.flags = !{{{.*}}}
320// CHECK: !llvm.dbg.cu = !{{{.*}}}
321// CHECK-DAG: ![[FILE:.*]] = !DIFile(filename: "not", directory: "existence")
322// CHECK-DAG: ![[TYPE:.*]] = !DIBasicType(name: "uint64_t", size: 64, encoding: DW_ATE_unsigned)
323// CHECK-DAG: ![[SCOPE:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[FILE]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: ![[GVALS:.*]])
324// CHECK-DAG: ![[GVAR0:.*]] = distinct !DIGlobalVariable(name: "global_with_expr_1", linkageName: "global_with_expr_1", scope: ![[SCOPE]], file: ![[FILE]], line: 370, type: ![[TYPE]], isLocal: false, isDefinition: false)
325// CHECK-DAG: ![[GVAR1:.*]] = distinct !DIGlobalVariable(name: "global_with_expr_2", linkageName: "global_with_expr_2", scope: ![[SCOPE]], file: ![[FILE]], line: 371, type: ![[TYPE]], isLocal: true, isDefinition: true, align: 8)
326// CHECK-DAG: ![[GEXPR0:.*]] = !DIGlobalVariableExpression(var: ![[GVAR0]], expr: !DIExpression())
327// CHECK-DAG: ![[GEXPR1:.*]] = !DIGlobalVariableExpression(var: ![[GVAR1]], expr: !DIExpression())
328// CHECK-DAG: ![[GVALS]] = !{![[GEXPR0]], ![[GEXPR1]]}
329
330#di_file_2 = #llvm.di_file<"not" in "existence">
331#di_compile_unit_2 = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file_2, producer = "MLIR", isOptimized = true, emissionKind = Full>
332#di_basic_type_2 = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "uint64_t", sizeInBits = 64, encoding = DW_ATE_unsigned>
333llvm.mlir.global external @global_with_expr_1() {addr_space = 0 : i32, dbg_exprs = [#llvm.di_global_variable_expression<var = <scope = #di_compile_unit_2, name = "global_with_expr_1", linkageName = "global_with_expr_1", file = #di_file_2, line = 370, type = #di_basic_type_2>, expr = <>>]} : i64
334llvm.mlir.global external @global_with_expr_2() {addr_space = 0 : i32, dbg_exprs = [#llvm.di_global_variable_expression<var = <scope = #di_compile_unit_2, name = "global_with_expr_2", linkageName = "global_with_expr_2", file = #di_file_2, line = 371, type = #di_basic_type_2, isLocalToUnit = true, isDefined = true, alignInBits = 8>, expr = <>>]} : i64
335
336// -----
337
338// CHECK: @module_global = external global i64, !dbg {{.*}}
339// CHECK: !llvm.module.flags = !{{{.*}}}
340// CHECK: !llvm.dbg.cu = !{{{.*}}}
341// CHECK-DAG: ![[FILE:.*]] = !DIFile(filename: "test.f90", directory: "existence")
342// CHECK-DAG: ![[TYPE:.*]] = !DIBasicType(name: "integer", size: 64, encoding: DW_ATE_signed)
343// CHECK-DAG: ![[SCOPE:.*]] = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: ![[FILE]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: ![[GVALS:.*]])
344// CHECK-DAG: ![[SCOPE1:.*]] = !DIModule(scope: ![[SCOPE]], name: "module2", file: ![[FILE]], line: 120)
345// CHECK-DAG: ![[GVAR:.*]] = distinct !DIGlobalVariable(name: "module_global", linkageName: "module_global", scope: ![[SCOPE1]], file: ![[FILE]], line: 121, type: ![[TYPE]], isLocal: false, isDefinition: true)
346// CHECK-DAG: ![[GEXPR:.*]] = !DIGlobalVariableExpression(var: ![[GVAR]], expr: !DIExpression())
347// CHECK-DAG: ![[GVALS]] = !{![[GEXPR]]}
348
349#di_file = #llvm.di_file<"test.f90" in "existence">
350#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "MLIR", isOptimized = true, emissionKind = Full>
351#di_basic_type = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 64, encoding = DW_ATE_signed>
352#di_module = #llvm.di_module<file = #di_file, scope = #di_compile_unit, name = "module2", configMacros = "", includePath = "", apinotes = "", line = 120, isDecl = false >
353llvm.mlir.global external @module_global() {dbg_exprs = [#llvm.di_global_variable_expression<var = <scope = #di_module, name = "module_global", linkageName = "module_global", file = #di_file, line = 121, type = #di_basic_type, isLocalToUnit = false, isDefined = true>, expr = <>>]} : i64
354
355// -----
356
357// CHECK: @func_global = external global i64, !dbg {{.*}}
358// CHECK-DAG: ![[CU:.*]] = distinct !DICompileUnit({{.*}}globals: ![[GVALS:.*]])
359// CHECK-DAG: ![[SP:.*]] = distinct !DISubprogram(name: "fn_with_gl"{{.*}}unit: ![[CU]])
360// CHECK-DAG: ![[GVAR:.*]] = distinct !DIGlobalVariable(name: "func_global"{{.*}}, scope: ![[SP]]{{.*}})
361// CHECK-DAG: ![[GEXPR:.*]] = !DIGlobalVariableExpression(var: ![[GVAR]], expr: !DIExpression())
362// CHECK-DAG: ![[GVALS]] = !{![[GEXPR]]}
363
364#file = #llvm.di_file<"test.f90" in "existence">
365#cu = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_Fortran95, file = #file, producer = "MLIR", isOptimized = true, emissionKind = Full>
366#ty1 = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 64, encoding = DW_ATE_signed>
367#sp = #llvm.di_subprogram<compileUnit = #cu, scope = #file, name = "fn_with_gl", file = #file, subprogramFlags = "Definition|Optimized">
368llvm.mlir.global @func_global() {dbg_exprs = [#llvm.di_global_variable_expression<var = <scope = #sp, name = "func_global", linkageName = "func_global", file = #file, line = 121, type = #ty1, isLocalToUnit = true, isDefined = true>, expr = <>>]} : i64
369
370llvm.func @fn_with_gl() {
371  llvm.return
372} loc(fused<#sp>["foo1.mlir":0:0])
373
374// -----
375
376// Test that imported entries correctly generates 'retainedNodes' in the
377// subprogram.
378
379llvm.func @imp_fn() {
380  llvm.return
381} loc(#loc2)
382
383#di_file = #llvm.di_file<"test.f90" in "">
384#di_subroutine_type = #llvm.di_subroutine_type<callingConvention = DW_CC_program>
385#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>,
386  sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false,
387  emissionKind = Full>
388#di_module_1 = #llvm.di_module<file = #di_file, scope = #di_compile_unit, name = "mod1">
389#di_module_2 = #llvm.di_module<file = #di_file, scope = #di_compile_unit, name = "mod2">
390#di_subprogram_self_rec = #llvm.di_subprogram<recId = distinct[1]<>>
391#di_imported_entity_1 = #llvm.di_imported_entity<tag = DW_TAG_imported_module,
392  scope = #di_subprogram_self_rec, entity = #di_module_1, file = #di_file, line = 1>
393#di_imported_entity_2 = #llvm.di_imported_entity<tag = DW_TAG_imported_module,
394  scope = #di_subprogram_self_rec, entity = #di_module_2, file = #di_file, line = 1>
395#di_subprogram = #llvm.di_subprogram<id = distinct[2]<>, recId = distinct[1]<>,
396  compileUnit = #di_compile_unit, scope = #di_file, name = "imp_fn",
397  file = #di_file, subprogramFlags = Definition, type = #di_subroutine_type,
398  retainedNodes = #di_imported_entity_1, #di_imported_entity_2>
399#loc1 = loc("test.f90":12:14)
400#loc2 = loc(fused<#di_subprogram>[#loc1])
401
402// CHECK-DAG: ![[SP:[0-9]+]] = {{.*}}!DISubprogram(name: "imp_fn"{{.*}}retainedNodes: ![[NODES:[0-9]+]])
403// CHECK-DAG: ![[NODES]] = !{![[NODE1:[0-9]+]], ![[NODE2:[0-9]+]]}
404// CHECK-DAG: ![[NODE1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[SP]], entity: ![[MOD1:[0-9]+]]{{.*}})
405// CHECK-DAG: ![[NODE2]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[SP]], entity: ![[MOD2:[0-9]+]]{{.*}})
406// CHECK-DAG: ![[MOD1]] = !DIModule({{.*}}name: "mod1"{{.*}})
407// CHECK-DAG: ![[MOD2]] = !DIModule({{.*}}name: "mod2"{{.*}})
408
409// -----
410
411// Nameless and scopeless global constant.
412
413// CHECK-LABEL: @.str.1 = external constant [10 x i8]
414// CHECK-SAME: !dbg ![[GLOBAL_VAR_EXPR:.*]]
415// CHECK-DAG: ![[GLOBAL_VAR_EXPR]] = !DIGlobalVariableExpression(var: ![[GLOBAL_VAR:.*]], expr: !DIExpression())
416// CHECK-DAG: ![[GLOBAL_VAR]] = distinct !DIGlobalVariable(scope: null, file: !{{[0-9]+}}, line: 268, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
417
418#di_basic_type = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "char", sizeInBits = 8, encoding = DW_ATE_signed_char>
419#di_file = #llvm.di_file<"file.c" in "/path/to/file">
420#di_derived_type = #llvm.di_derived_type<tag = DW_TAG_const_type, baseType = #di_basic_type>
421#di_composite_type = #llvm.di_composite_type<tag = DW_TAG_array_type, baseType = #di_derived_type, sizeInBits = 80>
422#di_global_variable = #llvm.di_global_variable<file = #di_file, line = 268, type = #di_composite_type, isLocalToUnit = true, isDefined = true>
423#di_global_variable_expression = #llvm.di_global_variable_expression<var = #di_global_variable, expr = <>>
424
425llvm.mlir.global external constant @".str.1"() {addr_space = 0 : i32, dbg_exprs = [#di_global_variable_expression]} : !llvm.array<10 x i8>
426
427// -----
428
429// CHECK-DAG: ![[FILE1:.*]] = !DIFile(filename: "foo1.mlir", directory: "/test/")
430#di_file_1 = #llvm.di_file<"foo1.mlir" in "/test/">
431// CHECK-DAG: ![[FILE2:.*]] = !DIFile(filename: "foo2.mlir", directory: "/test/")
432#di_file_2 = #llvm.di_file<"foo2.mlir" in "/test/">
433// CHECK-DAG: ![[SCOPE2:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[FILE2]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: DebugDirectivesOnly)
434#di_compile_unit_1 = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file_1, producer = "MLIR", isOptimized = true, emissionKind = LineTablesOnly>
435// CHECK-DAG: ![[SCOPE1:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[FILE1]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
436#di_compile_unit_2 = #llvm.di_compile_unit<id = distinct[1]<>, sourceLanguage = DW_LANG_C, file = #di_file_2, producer = "MLIR", isOptimized = true, emissionKind = DebugDirectivesOnly>
437#di_subprogram_1 = #llvm.di_subprogram<compileUnit = #di_compile_unit_1, scope = #di_file_1, name = "func1", file = #di_file_1, subprogramFlags = "Definition|Optimized">
438#di_subprogram_2 = #llvm.di_subprogram<compileUnit = #di_compile_unit_2, scope = #di_file_2, name = "func2", file = #di_file_2, subprogramFlags = "Definition|Optimized">
439
440llvm.func @func_line_tables() {
441  llvm.return
442} loc(fused<#di_subprogram_1>["foo1.mlir":0:0])
443
444llvm.func @func_debug_directives() {
445  llvm.return
446} loc(fused<#di_subprogram_2>["foo2.mlir":0:0])
447
448// -----
449
450// Ensure recursive types with multiple external references work.
451
452// Common base nodes.
453#di_file = #llvm.di_file<"test.mlir" in "/">
454#di_null_type = #llvm.di_null_type
455#di_compile_unit = #llvm.di_compile_unit<id = distinct[1]<>, sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = None>
456
457// Recursive type itself.
458#di_struct_self = #llvm.di_composite_type<recId = distinct[0]<>, isRecSelf = true>
459#di_ptr_inner = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #di_struct_self, sizeInBits = 64>
460#di_subroutine_inner = #llvm.di_subroutine_type<types = #di_null_type, #di_ptr_inner>
461#di_subprogram_inner = #llvm.di_subprogram<
462  id = distinct[2]<>,
463  compileUnit = #di_compile_unit,
464  scope = #di_struct_self,
465  name = "class_method",
466  file = #di_file,
467  subprogramFlags = Definition,
468  type = #di_subroutine_inner>
469#di_struct = #llvm.di_composite_type<
470  tag = DW_TAG_class_type,
471  recId = distinct[0]<>,
472  name = "class_name",
473  file = #di_file,
474  line = 42,
475  flags = "TypePassByReference|NonTrivial",
476  elements = #di_subprogram_inner>
477
478// Outer types referencing the entire recursive type.
479#di_ptr_outer = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #di_struct, sizeInBits = 64>
480#di_subroutine_outer = #llvm.di_subroutine_type<types = #di_null_type, #di_ptr_outer>
481#di_subprogram_outer = #llvm.di_subprogram<
482  id = distinct[2]<>,
483  compileUnit = #di_compile_unit,
484  scope = #di_struct,
485  name = "class_method",
486  file = #di_file,
487  subprogramFlags = Definition,
488  type = #di_subroutine_outer>
489
490#loc3 = loc(fused<#di_subprogram_outer>["test.mlir":1:1])
491
492// CHECK: @class_method
493// CHECK: ret void, !dbg ![[LOC:.*]]
494
495// CHECK: ![[CU:.*]] = distinct !DICompileUnit(
496// CHECK: ![[SP:.*]] = distinct !DISubprogram(name: "class_method", scope: ![[STRUCT:.*]], file: !{{.*}}, type: ![[SUBROUTINE:.*]], spFlags: DISPFlagDefinition, unit: ![[CU]])
497// CHECK: ![[STRUCT]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "class_name", {{.*}}, elements: ![[ELEMS:.*]])
498// CHECK: ![[ELEMS]] = !{![[SP]]}
499// CHECK: ![[SUBROUTINE]] = !DISubroutineType(types: ![[SUBROUTINE_ELEMS:.*]])
500// CHECK: ![[SUBROUTINE_ELEMS]] = !{null, ![[PTR:.*]]}
501// CHECK: ![[PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[STRUCT]], size: 64)
502// CHECK: ![[LOC]] = !DILocation(line: 1, column: 1, scope: ![[SP]])
503
504llvm.func @class_method() {
505  llvm.return loc(#loc3)
506} loc(#loc3)
507
508// -----
509
510// Ensures composite types with a recursive scope work.
511
512#di_composite_type_self = #llvm.di_composite_type<recId = distinct[0]<>, isRecSelf = true>
513#di_file = #llvm.di_file<"test.mlir" in "/">
514#di_subroutine_type = #llvm.di_subroutine_type<types = #di_composite_type_self>
515#di_subprogram = #llvm.di_subprogram<scope = #di_file, file = #di_file, subprogramFlags = Optimized, type = #di_subroutine_type>
516#di_composite_type = #llvm.di_composite_type<tag = DW_TAG_class_type, recId = distinct[0]<>, scope = #di_subprogram>
517#di_global_variable = #llvm.di_global_variable<file = #di_file, line = 1, type = #di_composite_type>
518#di_global_variable_expression = #llvm.di_global_variable_expression<var = #di_global_variable>
519
520llvm.mlir.global @global_variable() {dbg_exprs = [#di_global_variable_expression]} : !llvm.struct<()>
521
522// CHECK: distinct !DIGlobalVariable({{.*}}type: ![[COMP:[0-9]+]],
523// CHECK: ![[COMP]] = distinct !DICompositeType({{.*}}scope: ![[SCOPE:[0-9]+]]
524// CHECK: ![[SCOPE]] = !DISubprogram({{.*}}type: ![[SUBROUTINE:[0-9]+]],
525// CHECK: ![[SUBROUTINE]] = !DISubroutineType(types: ![[SR_TYPES:[0-9]+]])
526// CHECK: ![[SR_TYPES]] = !{![[COMP]]}
527
528// -----
529
530// Ensures nested recursive decls work.
531// The output should be identical to if the inner composite type decl was
532// replaced with the recursive self reference.
533
534#di_file = #llvm.di_file<"test.mlir" in "/">
535#di_composite_type_self = #llvm.di_composite_type<recId = distinct[0]<>, isRecSelf = true>
536
537#di_subroutine_type_inner = #llvm.di_subroutine_type<types = #di_composite_type_self>
538#di_subprogram_inner = #llvm.di_subprogram<scope = #di_file, file = #di_file, subprogramFlags = Optimized, type = #di_subroutine_type_inner>
539#di_composite_type_inner = #llvm.di_composite_type<tag = DW_TAG_class_type, recId = distinct[0]<>, scope = #di_subprogram_inner>
540
541#di_subroutine_type = #llvm.di_subroutine_type<types = #di_composite_type_inner>
542#di_subprogram = #llvm.di_subprogram<scope = #di_file, file = #di_file, subprogramFlags = Optimized, type = #di_subroutine_type>
543#di_composite_type = #llvm.di_composite_type<tag = DW_TAG_class_type, recId = distinct[0]<>, scope = #di_subprogram>
544
545// Use the inner type standalone outside too. Ensures it's not cached wrong.
546#di_var_type = #llvm.di_subroutine_type<types = #di_composite_type, #di_composite_type_inner>
547#di_global_variable = #llvm.di_global_variable<file = #di_file, line = 1, type = #di_var_type>
548#di_global_variable_expression = #llvm.di_global_variable_expression<var = #di_global_variable>
549
550llvm.mlir.global @global_variable() {dbg_exprs = [#di_global_variable_expression]} : !llvm.struct<()>
551
552// CHECK: distinct !DIGlobalVariable({{.*}}type: ![[VAR:[0-9]+]],
553// CHECK: ![[VAR]] = !DISubroutineType(types: ![[COMPS:[0-9]+]])
554// CHECK: ![[COMPS]] = !{![[COMP:[0-9]+]],
555// CHECK: ![[COMP]] = distinct !DICompositeType({{.*}}scope: ![[SCOPE:[0-9]+]]
556// CHECK: ![[SCOPE]] = !DISubprogram({{.*}}type: ![[SUBROUTINE:[0-9]+]],
557// CHECK: ![[SUBROUTINE]] = !DISubroutineType(types: ![[SR_TYPES:[0-9]+]])
558// CHECK: ![[SR_TYPES]] = !{![[COMP]]}
559
560// -----
561
562#file = #llvm.di_file<"test.f90" in "">
563#cu = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_Fortran95,
564  file = #file, producer = "", isOptimized = false, emissionKind = Full>
565#i32 = #llvm.di_basic_type<
566  tag = DW_TAG_base_type, name = "integer",
567  sizeInBits = 32, encoding = DW_ATE_signed
568>
569#null = #llvm.di_null_type
570#alloc = #llvm.di_expression<[DW_OP_lit0, DW_OP_ne]>
571#assoc = #llvm.di_expression<[DW_OP_lit0, DW_OP_eq]>
572#rank = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(16), DW_OP_deref]>
573#datal = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_deref]>
574#array = #llvm.di_composite_type<tag = DW_TAG_array_type,
575  baseType = #i32,
576  dataLocation = #datal, rank = #rank,
577  allocated = #alloc, associated = #assoc,
578  elements = #llvm.di_subrange<lowerBound = 1, count = 5>
579>
580#spType0 = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #null, #array>
581#sp0 = #llvm.di_subprogram<
582  compileUnit = #cu, scope = #cu, name = "fn_with_composite", file = #file,
583  subprogramFlags = "Definition|Optimized", type = #spType0
584>
585llvm.func @fn_with_composite() {
586  llvm.return
587}loc(fused<#sp0>["foo.mlir":1:1])
588// CHECK-LABEL: define void @fn_with_composite()
589// CHECK: !DICompositeType(
590// CHECK-SAME: dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref)
591// CHECK-SAME: associated: !DIExpression(DW_OP_lit0, DW_OP_eq)
592// CHECK-SAME: allocated: !DIExpression(DW_OP_lit0, DW_OP_ne)
593// CHECK-SAME: rank: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref)
594
595// -----
596
597// Test that Subrange/generic_subrange works with expression and variables.
598
599#bt = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int">
600#file = #llvm.di_file<"debug-info.ll" in "/">
601#cu = #llvm.di_compile_unit<id = distinct[1]<>,
602 sourceLanguage = DW_LANG_Fortran95, file = #file, isOptimized = false,
603 emissionKind = Full>
604#exp1 =  #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(16),
605 DW_OP_deref]>
606#comp_ty1 = #llvm.di_composite_type<tag = DW_TAG_array_type,
607 name = "expr_elements", baseType = #bt, flags = Vector,
608 elements = #llvm.di_subrange<count = #exp1>>
609#exp2 =  #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(24),
610 DW_OP_deref]>
611#exp3 =  #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(32),
612 DW_OP_deref]>
613#comp_ty2 = #llvm.di_composite_type<tag = DW_TAG_array_type,
614 name = "expr_elements2", baseType = #bt, elements =
615 #llvm.di_generic_subrange<count = #exp1, lowerBound = #exp2, stride = #exp3>>
616#srty = #llvm.di_subroutine_type<types = #bt, #comp_ty1, #comp_ty2>
617#sp = #llvm.di_subprogram<compileUnit = #cu, scope = #file, name = "subranges",
618  file = #file, subprogramFlags = Definition, type = #srty>
619#lvar = #llvm.di_local_variable<scope = #sp, name = "size">
620#gv = #llvm.di_global_variable<scope = #cu, name = "gv", file = #file,
621 line = 3, type = #bt>
622#gve = #llvm.di_global_variable_expression<var = #gv, expr = <>>
623#comp_ty3 = #llvm.di_composite_type<tag = DW_TAG_array_type,
624 name = "var_elements", baseType = #bt, flags = Vector,
625 elements = #llvm.di_subrange<count = #lvar, stride = #gv>>
626#comp_ty4 = #llvm.di_composite_type<tag = DW_TAG_array_type,
627 name = "var_elements2", baseType = #bt, elements =
628 #llvm.di_generic_subrange<count = #lvar, lowerBound = #gv, stride = #gv>>
629#lvar2 = #llvm.di_local_variable<scope = #sp, name = "var", type = #comp_ty3>
630#lvar3 = #llvm.di_local_variable<scope = #sp, name = "var1", type = #comp_ty4>
631#loc1 = loc("test.f90": 1:1)
632#loc2 = loc(fused<#sp>[#loc1])
633
634llvm.mlir.global external @gv() {dbg_exprs = [#gve]} : i64
635
636llvm.func @subranges(%arg: !llvm.ptr) {
637  llvm.intr.dbg.declare #lvar2 = %arg : !llvm.ptr
638  llvm.intr.dbg.declare #lvar3 = %arg : !llvm.ptr
639  llvm.return
640} loc(#loc2)
641
642// CHECK-LABEL: define void @subranges
643// CHECK: ![[GV:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "gv"{{.*}})
644// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements"{{.*}}elements: ![[ELEMENTS1:[0-9]+]])
645// CHECK: ![[ELEMENTS1]] = !{![[ELEMENT1:[0-9]+]]}
646// CHECK: ![[ELEMENT1]] = !DISubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref))
647// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements2"{{.*}}elements: ![[GSR_ELEMS:[0-9]+]])
648// CHECK: ![[GSR_ELEMS]] = !{![[GSR_ELEM:[0-9]+]]}
649// CHECK: ![[GSR_ELEM]] = !DIGenericSubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref)
650// CHECK-SAME: lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref)
651// CHECK-SAME: stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 32, DW_OP_deref)
652
653// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "var_elements"{{.*}}elements: ![[ELEMENTS2:[0-9]+]])
654// CHECK: ![[ELEMENTS2]] = !{![[ELEMENT2:[0-9]+]]}
655// CHECK: ![[ELEMENT2]] = !DISubrange(count: ![[LV:[0-9]+]], stride: ![[GV]])
656// CHECK: ![[LV]] = !DILocalVariable(name: "size"{{.*}})
657// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "var_elements2", baseType: !{{.*}}, elements: ![[GSR_ELEMS2:[0-9]+]])
658// CHECK: ![[GSR_ELEMS2]] = !{![[GSR_ELEM2:[0-9]+]]}
659// CHECK: ![[GSR_ELEM2]] = !DIGenericSubrange(count: ![[LV]], lowerBound: ![[GV]], stride: ![[GV]])
660
661// -----
662
663#bt = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32>
664#file = #llvm.di_file<"debug-info.ll" in "/">
665#cu = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C,
666 file = #file, isOptimized = false, emissionKind = Full>
667#sp = #llvm.di_subprogram<compileUnit = #cu, scope = #file, name = "test",
668 file = #file, subprogramFlags = Definition>
669#var = #llvm.di_local_variable<scope = #sp, name = "string_size", type = #bt, flags = Artificial>
670#ty = #llvm.di_string_type<tag = DW_TAG_string_type, name = "character(*)",
671 sizeInBits = 32, alignInBits = 8, stringLength = #var,
672 stringLengthExp = <[DW_OP_push_object_address, DW_OP_plus_uconst(8)]>,
673 stringLocationExp = <[DW_OP_push_object_address, DW_OP_deref]>>
674#var1 = #llvm.di_local_variable<scope = #sp, name = "str", type = #ty>
675
676llvm.func @string_ty(%arg0: !llvm.ptr) {
677  llvm.intr.dbg.value #var1 = %arg0 : !llvm.ptr
678  llvm.intr.dbg.value #var = %arg0 : !llvm.ptr
679  llvm.return
680} loc(#loc2)
681
682#loc1 = loc("test.f90":1:1)
683#loc2 = loc(fused<#sp>[#loc1])
684
685// CHECK-DAG: !DIStringType(name: "character(*)", stringLength: ![[VAR:[0-9]+]], stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), size: 32, align: 8)
686// CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "string_size"{{.*}} flags: DIFlagArtificial)
687
688// -----
689
690// Test translation of DICommonBlockAttr.
691#bt = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32>
692#file = #llvm.di_file<"test.f90" in "">
693#cu = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C,
694 file = #file, isOptimized = false, emissionKind = Full>
695#sp = #llvm.di_subprogram<compileUnit = #cu, scope = #file, name = "test",
696 file = #file, subprogramFlags = Definition>
697#di_common_block = #llvm.di_common_block<scope = #sp, name = "block",
698 file = #file, line = 3>
699#global_var = #llvm.di_global_variable<scope = #di_common_block, name = "a",
700 file = #file, line = 2, type = #bt>
701#var_expression = #llvm.di_global_variable_expression<var = #global_var,
702 expr = <>>
703
704llvm.mlir.global common @block_(dense<0> : tensor<8xi8>)
705  {dbg_exprs = [#var_expression]} : !llvm.array<8 x i8>
706
707llvm.func @test() {
708  llvm.return
709} loc(#loc2)
710
711#loc1 = loc("test.f90":1:0)
712#loc2 = loc(fused<#sp>[#loc1])
713
714// CHECK: !DICommonBlock(scope: ![[SCOPE:[0-9]+]], declaration: null, name: "block", file: ![[FILE:[0-9]+]], line: 3)
715// CHECK: ![[SCOPE]] = {{.*}}!DISubprogram(name: "test"{{.*}})
716// CHECK: ![[FILE]] = !DIFile(filename: "test.f90"{{.*}})
717
718// -----
719
720// Test multiple DIGlobalVariableExpression on a global.
721#bt = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32>
722#file = #llvm.di_file<"test.f90" in "">
723#cu = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C,
724 file = #file, isOptimized = false, emissionKind = Full>
725#global_var = #llvm.di_global_variable<scope = #cu, name = "a",
726 file = #file, line = 2, type = #bt>
727#var_expression = #llvm.di_global_variable_expression<var = #global_var,
728 expr = <>>
729#global_var1 = #llvm.di_global_variable<scope = #cu, name = "b",
730 file = #file, line = 3, type = #bt>
731#var_expression1 = #llvm.di_global_variable_expression<var = #global_var1,
732 expr = <>>
733
734llvm.mlir.global @data() {dbg_exprs = [#var_expression, #var_expression1]} : i64
735
736// CHECK: @data = external global i64, !dbg ![[EXP1:[0-9]+]], !dbg ![[EXP2:[0-9]+]]
737// CHECK: ![[EXP1]] = !DIGlobalVariableExpression(var: ![[VAR1:[0-9]+]], expr: !DIExpression())
738// CHECK: ![[VAR1]] = {{.*}}!DIGlobalVariable(name: "a"{{.*}})
739// CHECK: ![[EXP2]] = !DIGlobalVariableExpression(var: ![[VAR2:[0-9]+]], expr: !DIExpression())
740// CHECK: ![[VAR2]] = {{.*}}!DIGlobalVariable(name: "b"{{.*}})
741