Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DW_AT_NAME is incorrect for Fortran functions compiled by flang #92391

Open
DavidSpickett opened this issue May 16, 2024 · 6 comments
Open

DW_AT_NAME is incorrect for Fortran functions compiled by flang #92391

DavidSpickett opened this issue May 16, 2024 · 6 comments
Assignees

Comments

@DavidSpickett
Copy link
Collaborator

I compiled this example:

integer function my_square(x)
    implicit none
    integer, intent(in) :: x

    my_square = x * x
end function my_square

program hello
  print *, my_square(2)
end program hello

Because I wanted to see what lldb would think of it, but it couldn't break on my_square when I compiled it with flang, but it could when I used gfortran.

Looking at the DWARF, the DW_AT_NAME for flang includes an _ on the end.

Gfortran 9.4.0:

0x000000bc:   DW_TAG_subprogram
                DW_AT_external  (true)
                DW_AT_name      ("my_square")
                DW_AT_decl_file ("/tmp/test.f90")
                DW_AT_decl_line (1)
                DW_AT_linkage_name      ("my_square_")
                DW_AT_type      (0x0000006d "integer(kind=4)")
                DW_AT_low_pc    (0x000000000000091c)
                DW_AT_high_pc   (0x0000000000000948)
                DW_AT_frame_base        (DW_OP_call_frame_cfa)
                DW_AT_GNU_all_call_sites        (true)

Flang (built from 7d81062):

0x0000002a:   DW_TAG_subprogram
                DW_AT_low_pc    (0x0000000000001fa4)
                DW_AT_high_pc   (0x0000000000001fc0)
                DW_AT_frame_base        (DW_OP_reg31 WSP)
                DW_AT_linkage_name      ("my_square_")
                DW_AT_name      ("my_square_")
                DW_AT_decl_file ("/tmp/test.f90")
                DW_AT_decl_line (1)
                DW_AT_type      (0x0000009c "integer")
                DW_AT_external  (true)

I think flang is mistakenly using the DW_AT_linkage_name for DW_AT_name.

The workaround is to break on my_square_.

@DavidSpickett
Copy link
Collaborator Author

lldb has zero support for fortran beyond knowing what the DWARF language tag is, but this doesn't seem to be a fortran quirk as it confuses gdb as well:

(gdb) b my_square
Function "my_square" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b my_square_
Breakpoint 1 at 0x1f98: file /tmp/test.f90, line 5.

@DavidSpickett
Copy link
Collaborator Author

DavidSpickett commented May 16, 2024

define i32 @my_square_(ptr %0) #0 !dbg !3 {
  %2 = alloca i32, i64 1, align 4, !dbg !8
  tail call void @llvm.dbg.declare(metadata ptr %2, metadata !9, metadata !DIExpression()), !dbg !8
  tail call void @llvm.dbg.declare(metadata ptr %0, metadata !10, metadata !DIExpression()), !dbg !11
  %3 = load i32, ptr %0, align 4, !dbg !12
  %4 = mul i32 %3, %3, !dbg !12
  store i32 %4, ptr %2, align 4, !dbg !12
  %5 = load i32, ptr %2, align 4, !dbg !13
  ret i32 %5, !dbg !13
}

!3 = distinct !DISubprogram(name: "my_square_", linkageName: "my_square_", scope: !2, file: !4, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !1)

By the time we get to llvm IR, the names have already been set.

In hlfir I do see the original name:

  func.func @_QPmy_square(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}) -> i32 {
    %0 = fir.dummy_scope : !fir.dscope
    %1 = fir.alloca i32 {bindc_name = "my_square", uniq_name = "_QFmy_squareEmy_square"}
    %2:2 = hlfir.declare %1 {uniq_name = "_QFmy_squareEmy_square"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
    %3:2 = hlfir.declare %arg0 dummy_scope %0 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFmy_squareEx"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
    %4 = fir.load %3#0 : !fir.ref<i32>
    %5 = fir.load %3#0 : !fir.ref<i32>
    %6 = arith.muli %4, %5 : i32
    hlfir.assign %6 to %2#0 : i32, !fir.ref<i32>
    %7 = fir.load %2#1 : !fir.ref<i32>
    return %7 : i32
  }

bindc_name = "my_square", but maybe this is the name of the allocation for the implicit return variable.

@DavidSpickett
Copy link
Collaborator Author

Perhaps @abidh is already aware of this?

@abidh abidh self-assigned this May 16, 2024
@abidh
Copy link
Contributor

abidh commented May 16, 2024

The ExternalNameConversion pass converts my_square to my_square_. By the time, it reaches AddDebugInfo, the change of name has already happened. But an attribute is added to the op that contains the original name so it is possible to use that.

@llvmbot
Copy link
Collaborator

llvmbot commented May 16, 2024

@llvm/issue-subscribers-flang-ir

Author: David Spickett (DavidSpickett)

I compiled this example: ``` integer function my_square(x) implicit none integer, intent(in) :: x
my_square = x * x

end function my_square

program hello
print *, my_square(2)
end program hello


Because I wanted to see what lldb would think of it, but it couldn't break on `my_square` when I compiled it with flang, but it could when I used gfortran.

Looking at the DWARF, the DW_AT_NAME for flang includes an `_` on the end.

Gfortran 9.4.0:

0x000000bc: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("my_square")
DW_AT_decl_file ("/tmp/test.f90")
DW_AT_decl_line (1)
DW_AT_linkage_name ("my_square_")
DW_AT_type (0x0000006d "integer(kind=4)")
DW_AT_low_pc (0x000000000000091c)
DW_AT_high_pc (0x0000000000000948)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_GNU_all_call_sites (true)


Flang (built from 7d81062352f75cf328d91d4900af52c1842b950e):

0x0000002a: DW_TAG_subprogram
DW_AT_low_pc (0x0000000000001fa4)
DW_AT_high_pc (0x0000000000001fc0)
DW_AT_frame_base (DW_OP_reg31 WSP)
DW_AT_linkage_name ("my_square_")
DW_AT_name ("my_square_")
DW_AT_decl_file ("/tmp/test.f90")
DW_AT_decl_line (1)
DW_AT_type (0x0000009c "integer")
DW_AT_external (true)


I think flang is mistakenly using the DW_AT_linkage_name for DW_AT_name.

The workaround is to break on `my_square_`.
</details>

@llvmbot
Copy link
Collaborator

llvmbot commented May 16, 2024

@llvm/issue-subscribers-debuginfo

Author: David Spickett (DavidSpickett)

I compiled this example: ``` integer function my_square(x) implicit none integer, intent(in) :: x
my_square = x * x

end function my_square

program hello
print *, my_square(2)
end program hello


Because I wanted to see what lldb would think of it, but it couldn't break on `my_square` when I compiled it with flang, but it could when I used gfortran.

Looking at the DWARF, the DW_AT_NAME for flang includes an `_` on the end.

Gfortran 9.4.0:

0x000000bc: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("my_square")
DW_AT_decl_file ("/tmp/test.f90")
DW_AT_decl_line (1)
DW_AT_linkage_name ("my_square_")
DW_AT_type (0x0000006d "integer(kind=4)")
DW_AT_low_pc (0x000000000000091c)
DW_AT_high_pc (0x0000000000000948)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_GNU_all_call_sites (true)


Flang (built from 7d81062352f75cf328d91d4900af52c1842b950e):

0x0000002a: DW_TAG_subprogram
DW_AT_low_pc (0x0000000000001fa4)
DW_AT_high_pc (0x0000000000001fc0)
DW_AT_frame_base (DW_OP_reg31 WSP)
DW_AT_linkage_name ("my_square_")
DW_AT_name ("my_square_")
DW_AT_decl_file ("/tmp/test.f90")
DW_AT_decl_line (1)
DW_AT_type (0x0000009c "integer")
DW_AT_external (true)


I think flang is mistakenly using the DW_AT_linkage_name for DW_AT_name.

The workaround is to break on `my_square_`.
</details>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants