[clang] ac2c5af - [OPENMP] Fix mixture of omp and clang pragmas

KAWASHIMA Takahiro via cfe-commits cfe-commits at lists.llvm.org
Thu May 21 20:55:08 PDT 2020


Author: ISHIGURO, Hiroshi
Date: 2020-05-22T12:53:37+09:00
New Revision: ac2c5af67f036ec810556372b16548ae9b663f36

URL: https://github.com/llvm/llvm-project/commit/ac2c5af67f036ec810556372b16548ae9b663f36
DIFF: https://github.com/llvm/llvm-project/commit/ac2c5af67f036ec810556372b16548ae9b663f36.diff

LOG: [OPENMP] Fix mixture of omp and clang pragmas

Fixes PR45753

When a program that contains a loop to which both `omp parallel for`
pragma and `clang loop` pragma are associated is compiled with the
-fopenmp option, `clang loop` pragma did not take effect. The example
below should not be vectorized by the `clang loop` pragma but it was
actually vectorized. The cause is that `llvm.loop.vectorize.width`
was not output to the IR when -fopenmp is specified.

The fix attaches attributes if they exist for the loop.

[example.c]

```
int a[100], b[100];
void foo() {
  #pragma omp parallel for
  #pragma clang loop vectorize(disable)
  for (int i = 0; i < 100; i++)
    a[i] += b[i] * i;
}
```

[compile]

```
$ clang -O2 -fopenmp example.c -c -Rpass=vect
example.c:3:11: remark: vectorized loop (vectorization width: 4, interleaved count: 2) [-Rpass=loop-vectorize]
  #pragma omp parallel for
          ^
```

[IR with -fopenmp]

```
$ clang -O2 exmaple.c -S -emit-llvm -mllvm -disable-llvm-optzns -o - -fopenmp | grep 'vectorize\.width'
```

[IR with -fno-openmp]

```
$ clang -O2 example.c -S -emit-llvm -mllvm -disable-llvm-optzns -o - -fno-openmp | grep 'vectorize\.width'
!7 = !{!"llvm.loop.vectorize.width", i32 1}
```

Differential Revision: https://reviews.llvm.org/D79921

Added: 
    clang/test/OpenMP/omp_with_loop_pragma.c

Modified: 
    clang/lib/CodeGen/CGStmtOpenMP.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index b6d45f026bbf..d12aa65af0ba 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1730,8 +1730,19 @@ void CodeGenFunction::EmitOMPInnerLoop(
   auto CondBlock = createBasicBlock("omp.inner.for.cond");
   EmitBlock(CondBlock);
   const SourceRange R = S.getSourceRange();
-  LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
-                 SourceLocToDebugLoc(R.getEnd()));
+
+  // If attributes are attached, push to the basic block with them.
+  const auto &OMPED = cast<OMPExecutableDirective>(S);
+  const CapturedStmt *ICS = OMPED.getInnermostCapturedStmt();
+  const Stmt *SS = ICS->getCapturedStmt();
+  const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(SS);
+  if (AS)
+    LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(),
+                   AS->getAttrs(), SourceLocToDebugLoc(R.getBegin()),
+                   SourceLocToDebugLoc(R.getEnd()));
+  else
+    LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
+                   SourceLocToDebugLoc(R.getEnd()));
 
   // If there are any cleanups between here and the loop-exit scope,
   // create a block to stage a loop exit along.

diff  --git a/clang/test/OpenMP/omp_with_loop_pragma.c b/clang/test/OpenMP/omp_with_loop_pragma.c
new file mode 100644
index 000000000000..c1536afa9901
--- /dev/null
+++ b/clang/test/OpenMP/omp_with_loop_pragma.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c -emit-llvm %s -triple x86_64-unknown-linux -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -verify -x c -emit-llvm %s -triple x86_64-unknown-linux -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
+// expected-no-diagnostics
+
+// CHECK: !{{[0-9]+}} = !{!"llvm.loop.vectorize.width", i32 1}
+void sub(double *restrict a, double *restrict b, int n) {
+  int i;
+
+#pragma omp parallel for
+#pragma clang loop vectorize(disable)
+  for (i = 0; i < n; i++) {
+    a[i] = a[i] + b[i];
+  }
+}


        


More information about the cfe-commits mailing list