diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index 3806db3ceab25..cd3fe5705f149 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -2847,11 +2847,10 @@ convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder, llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder(); auto simdOp = cast(opInst); - // TODO: Replace this with proper composite translation support. - // Currently, simd information on composite constructs is ignored, so e.g. - // 'do/for simd' will be treated the same as a standalone 'do/for'. This is - // allowed by the spec, since it's equivalent to using a SIMD length of 1. - if (simdOp.isComposite()) { + // Ignore simd in composite constructs with unsupported clauses + // TODO: Replace this once simd + clause combinations are properly supported + if (simdOp.isComposite() && + (simdOp.getReductionByref().has_value() || simdOp.getIfExpr())) { if (failed(convertIgnoredWrapper(simdOp, moduleTranslation))) return failure(); diff --git a/mlir/test/Target/LLVMIR/openmp-parallel-do-simd.mlir b/mlir/test/Target/LLVMIR/openmp-parallel-do-simd.mlir new file mode 100644 index 0000000000000..bfa57b85245ca --- /dev/null +++ b/mlir/test/Target/LLVMIR/openmp-parallel-do-simd.mlir @@ -0,0 +1,38 @@ +// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s + +// Check that omp.simd as a leaf of a composite construct still generates +// the appropriate loop vectorization attribute. + +// CHECK-LABEL: define internal void @test_parallel_do_simd..omp_par +// CHECK: omp.par.entry: +// CHECK: omp.par.region: +// CHECK: omp_loop.header: +// CHECK: omp_loop.inc: +// CHECK-NEXT: %omp_loop.next = add nuw i32 %omp_loop.iv, 1 +// CHECK-NEXT: br label %omp_loop.header, !llvm.loop ![[LOOP_ATTR:.*]] +// CHECK: ![[LOOP_ATTR]] = distinct !{![[LOOP_ATTR]], ![[LPAR:.*]], ![[LVEC:.*]]} +// CHECK: ![[LPAR]] = !{!"llvm.loop.parallel_accesses", ![[PAR_ACC:.*]]} +// CHECK: ![[LVEC]] = !{!"llvm.loop.vectorize.enable", i1 true} + +llvm.func @test_parallel_do_simd() { + %0 = llvm.mlir.constant(1 : i64) : i64 + %1 = llvm.alloca %0 x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr + %2 = llvm.mlir.constant(1000 : i32) : i32 + %3 = llvm.mlir.constant(1 : i32) : i32 + %4 = llvm.mlir.constant(1 : i64) : i64 + omp.parallel { + %5 = llvm.mlir.constant(1 : i64) : i64 + %6 = llvm.alloca %5 x i32 {bindc_name = "i", pinned} : (i64) -> !llvm.ptr + %7 = llvm.mlir.constant(1 : i64) : i64 + omp.wsloop { + omp.simd { + omp.loop_nest (%arg0) : i32 = (%3) to (%2) inclusive step (%3) { + llvm.store %arg0, %6 : i32, !llvm.ptr + omp.yield + } + } {omp.composite} + } {omp.composite} + omp.terminator + } + llvm.return +} diff --git a/mlir/test/Target/LLVMIR/openmp-teams-distribute-parallel-do-simd.mlir b/mlir/test/Target/LLVMIR/openmp-teams-distribute-parallel-do-simd.mlir new file mode 100644 index 0000000000000..4d766cc1ac4f4 --- /dev/null +++ b/mlir/test/Target/LLVMIR/openmp-teams-distribute-parallel-do-simd.mlir @@ -0,0 +1,51 @@ +// RUN: mlir-translate --mlir-to-llvmir %s | FileCheck %s + +// Check that omp.simd as a leaf of a composite construct still generates +// the appropriate loop vectorization attribute. + +// CHECK-LABEL: define internal void @test_teams_distribute_parallel_do_simd..omp_par.2 +// CHECK: teams.body: +// CHECK: omp.teams.region: + +// CHECK-LABEL: define internal void @test_teams_distribute_parallel_do_simd..omp_par.1 +// CHECK: omp.par.entry: +// CHECK: omp.par.region: +// CHECK: distribute.exit: + +// CHECK-LABEL: define internal void @test_teams_distribute_parallel_do_simd..omp_par +// CHECK: distribute.body: +// CHECK: omp.distribute.region: +// CHECK: omp_loop.header: +// CHECK: omp_loop.inc: +// CHECK-NEXT: %omp_loop.next = add nuw i32 %omp_loop.iv, 1 +// CHECK-NEXT: br label %omp_loop.header, !llvm.loop ![[LOOP_ATTR:.*]] + +// CHECK: ![[LOOP_ATTR]] = distinct !{![[LOOP_ATTR]], ![[LPAR:.*]], ![[LVEC:.*]]} +// CHECK: ![[LPAR]] = !{!"llvm.loop.parallel_accesses", ![[PAR_ACC:.*]]} +// CHECK: ![[LVEC]] = !{!"llvm.loop.vectorize.enable", i1 true} + +omp.private {type = private} @_QFEi_private_i32 : i32 +llvm.func @test_teams_distribute_parallel_do_simd() { + %0 = llvm.mlir.constant(1 : i64) : i64 + %1 = llvm.alloca %0 x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr + %2 = llvm.mlir.constant(1000 : i32) : i32 + %3 = llvm.mlir.constant(1 : i32) : i32 + %4 = llvm.mlir.constant(1 : i64) : i64 + omp.teams { + omp.parallel { + omp.distribute { + omp.wsloop { + omp.simd private(@_QFEi_private_i32 %1 -> %arg0 : !llvm.ptr) { + omp.loop_nest (%arg1) : i32 = (%3) to (%2) inclusive step (%3) { + llvm.store %arg1, %arg0 : i32, !llvm.ptr + omp.yield + } + } {omp.composite} + } {omp.composite} + } {omp.composite} + omp.terminator + } {omp.composite} + omp.terminator + } + llvm.return +} diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir index 97608ca3b4df1..fd75d580fdf8d 100644 --- a/mlir/test/Target/LLVMIR/openmp-todo.mlir +++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir @@ -26,20 +26,6 @@ llvm.func @atomic_hint(%v : !llvm.ptr, %x : !llvm.ptr, %expr : i32) { // ----- -llvm.func @do_simd(%lb : i32, %ub : i32, %step : i32) { - omp.wsloop { - // expected-warning@below {{simd information on composite construct discarded}} - omp.simd { - omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) { - omp.yield - } - } {omp.composite} - } {omp.composite} - llvm.return -} - -// ----- - llvm.func @distribute_allocate(%lb : i32, %ub : i32, %step : i32, %x : !llvm.ptr) { // expected-error@below {{not yet implemented: Unhandled clause allocate in omp.distribute operation}} // expected-error@below {{LLVM Translation failed for operation: omp.distribute}} @@ -533,3 +519,43 @@ llvm.func @wsloop_order(%lb : i32, %ub : i32, %step : i32) { } llvm.return } + +// ----- + +llvm.func @do_simd_if(%1 : !llvm.ptr, %5 : i32, %4 : i32, %6 : i1) { + omp.wsloop { + // expected-warning@below {{simd information on composite construct discarded}} + omp.simd if(%6) { + omp.loop_nest (%arg0) : i32 = (%5) to (%4) inclusive step (%5) { + llvm.store %arg0, %1 : i32, !llvm.ptr + omp.yield + } + } {omp.composite} + } {omp.composite} + llvm.return +} + +// ----- + +omp.declare_reduction @add_reduction_i32 : i32 init { +^bb0(%arg0: i32): + %0 = llvm.mlir.constant(0 : i32) : i32 + omp.yield(%0 : i32) +} combiner { +^bb0(%arg0: i32, %arg1: i32): + %0 = llvm.add %arg0, %arg1 : i32 + omp.yield(%0 : i32) +} +llvm.func @do_simd_reduction(%1 : !llvm.ptr, %3 : !llvm.ptr, %6 : i32, %7 : i32) { + omp.wsloop reduction(@add_reduction_i32 %3 -> %arg0 : !llvm.ptr) { + // expected-warning@below {{simd information on composite construct discarded}} + omp.simd reduction(@add_reduction_i32 %arg0 -> %arg1 : !llvm.ptr) { + omp.loop_nest (%arg2) : i32 = (%7) to (%6) inclusive step (%7) { + llvm.store %arg2, %1 : i32, !llvm.ptr + %12 = llvm.load %arg1 : !llvm.ptr -> i32 + omp.yield + } + } {omp.composite} + } {omp.composite} + llvm.return +}