Skip to content

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

@jprotze

Description

@jprotze

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;
  }

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions