Skip to content

Iteration variable in OpenMP work-sharing loops is wrong based on DWARF #110700

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

Open
jprotze opened this issue Oct 1, 2024 · 2 comments · May be fixed by #122047
Open

Iteration variable in OpenMP work-sharing loops is wrong based on DWARF #110700

jprotze opened this issue Oct 1, 2024 · 2 comments · May be fixed by #122047
Assignees
Labels
clang:openmp OpenMP related changes to Clang debuginfo wrong-debug

Comments

@jprotze
Copy link
Collaborator

jprotze commented Oct 1, 2024

This issue is related to #107125.

Based on a code like:

#include <omp.h>
#include <stdio.h>

int main(int argc, char **argv) {
  const int n = 100 * argc;
  double a[n], total=42., c = .3;
#pragma omp parallel for reduction(+ : total) 
  for (int i = 0; i < n; i++) {
    total += a[i] = i * c;
  }
  printf("total=%lf, expected:%lf, a[50]=%lf\n", total, c * n * (n - 1) / 2, a[50]);
}

compiled as:

clang -g -fopenmp test-dwarf.c
llvm-dwarfdump

Produces something like:

0x000000f6:       DW_TAG_variable
                    DW_AT_location      (DW_OP_fbreg -52)
                    DW_AT_name  (".omp.iv")
                    DW_AT_type  (0x000001ad "int")
                    DW_AT_artificial    (true)

0x00000108:       DW_TAG_variable
                    DW_AT_location      (DW_OP_fbreg -68)
                    DW_AT_name  ("i")
                    DW_AT_type  (0x000001ad "int")
                    DW_AT_artificial    (true)

Since i points to a location that never changes it's value, it's difficult to find the right value of i. From a users perspective, i should just point to the location of .omp.iv, which seem to represent the local value of i. When trying to print a[i] using a[.omp.iv], gdb emits a parsing error, because dot is not a valid character in a symbol name.

At line 11, gdb (focused on the second of four threads) prints these local variables, and i never changes:

(gdb) info locals
.omp.iv = 25
.capture_expr. = 100
i = 0
.omp.ub = 49
.omp.stride = 100
.omp.lb = 25
.omp.is_last = 0
total = 0

The reason might be generated code that looks like:

  for (int .omp.iv = .omp.lb; .omp.iv <= .omp.ub; .omp.iv++) {
    total += a[.omp.iv] = .omp.iv * c;
  }
@jprotze jprotze added wrong-debug debuginfo clang:openmp OpenMP related changes to Clang and removed new issue labels Oct 1, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 1, 2024

@llvm/issue-subscribers-debuginfo

Author: Joachim (jprotze)

This issue is related to #107125.

Based on a code like:

#include &lt;omp.h&gt;
#include &lt;stdio.h&gt;

int main(int argc, char **argv) {
  const int n = 100 * argc;
  double a[n], total=42., c = .3;
#pragma omp parallel for reduction(+ : total) 
  for (int i = 0; i &lt; n; i++) {
    total += a[i] = i * c;
  }
  printf("total=%lf, expected:%lf, a[50]=%lf\n", total, c * n * (n - 1) / 2, a[50]);
}

compiled as:

clang -g -fopenmp test-dwarf.c
llvm-dwarfdump

Produces something like:

0x000000f6:       DW_TAG_variable
                    DW_AT_location      (DW_OP_fbreg -52)
                    DW_AT_name  (".omp.iv")
                    DW_AT_type  (0x000001ad "int")
                    DW_AT_artificial    (true)

0x00000108:       DW_TAG_variable
                    DW_AT_location      (DW_OP_fbreg -68)
                    DW_AT_name  ("i")
                    DW_AT_type  (0x000001ad "int")
                    DW_AT_artificial    (true)

Since i points to a location that never changes, it's difficult to find the right value of i. From a users perspective, i should just point to the location of .omp.iv, which seem to represent the local value of i. When trying to print a[i] using a[.omp.iv], gdb emits a parsing error, because dot is not a valid character in a symbol name.

At line 11, gdb (focused on the second of four threads) prints these local variables, and i never changes:

(gdb) info locals
.omp.iv = 25
.capture_expr. = 100
i = 0
.omp.ub = 49
.omp.stride = 100
.omp.lb = 25
.omp.is_last = 0
total = 0

@Meinersbur
Copy link
Member

So war we neglected generating correct debug information for OpenMP. What I think what happens here (take the following just as conjecture) is that the DWARF for i refers to the i outside the OpenMP region1. It should be shadowed by the private i variable within the loop, but there is no DWARF telling the debugger.

What Clang should do is to emit #dbg_value/#dbg_declare on the llvm::Value/alloca for .omp.iv informing the DWARF generator that within the OpenMP .omp.iv is representing the value of i.

.omp.iv does not have #dbg_value/#dbg_declare telling the DWARF generator what variable it represents, so I think the DWARF emitter falls back to emit it as an artificial variable. Once it is annotated, it should not even show up anymore in the debugger.

Footnotes

  1. i is declared inline here, but internally it should just be an implicit declaration of i before the OpenMP region. This might explain why it is marked as artificial. Again, because CGStmtOpenMP does not attach a #dbg_declare when emitting it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:openmp OpenMP related changes to Clang debuginfo wrong-debug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants