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]; + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits