[flang-commits] [flang] 172fe17 - [MLIR][OpenMP] Add support for safelen clause
Prabhdeep Singh Soni via flang-commits
flang-commits at lists.llvm.org
Wed Aug 24 09:25:37 PDT 2022
Author: Prabhdeep Singh Soni
Date: 2022-08-24T12:23:31-04:00
New Revision: 172fe1706d83832a330170f43fe52aab1b75e7de
URL: https://github.com/llvm/llvm-project/commit/172fe1706d83832a330170f43fe52aab1b75e7de
DIFF: https://github.com/llvm/llvm-project/commit/172fe1706d83832a330170f43fe52aab1b75e7de.diff
LOG: [MLIR][OpenMP] Add support for safelen clause
This supports translation from MLIR to LLVM IR using OMPIRBuilder for
OpenMP safelen clause in SIMD construct.
Added:
Modified:
flang/lib/Lower/OpenMP.cpp
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
mlir/test/Dialect/OpenMP/invalid.mlir
mlir/test/Dialect/OpenMP/ops.mlir
mlir/test/Target/LLVMIR/openmp-llvm.mlir
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 77a952614d161..523edc0a75900 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -1150,7 +1150,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
TypeRange resultType;
auto SimdLoopOp = firOpBuilder.create<mlir::omp::SimdLoopOp>(
currentLocation, resultType, lowerBound, upperBound, step,
- ifClauseOperand, simdlenClauseOperand,
+ ifClauseOperand, simdlenClauseOperand, nullptr,
/*inclusive=*/firOpBuilder.getUnitAttr());
createBodyOfOp<omp::SimdLoopOp>(SimdLoopOp, converter, currentLocation,
eval, &loopOpClauseList, iv);
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 1ddb5ea31d397..cb130563412d6 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -421,6 +421,10 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
When a simdlen clause is present, the preferred number of iterations to be
executed concurrently is the value provided to the simdlen clause.
+
+ The safelen clause specifies that no two concurrent iterations within a
+ SIMD chunk can have a distance in the logical iteration space that is
+ greater than or equal to the value given in the clause.
```
omp.simdloop <clauses>
for (%i1, %i2) : index = (%c0, %c0) to (%c10, %c10) step (%c1, %c1) {
@@ -436,6 +440,7 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
Variadic<IntLikeType>:$step,
Optional<I1>:$if_expr,
ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$simdlen,
+ ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$safelen,
UnitAttr:$inclusive
);
@@ -443,6 +448,7 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
let assemblyFormat = [{
oilist(`if` `(` $if_expr `)`
|`simdlen` `(` $simdlen `)`
+ |`safelen` `(` $safelen `)`
) `for` custom<LoopControl>($region, $lowerBound, $upperBound, $step,
type($step), $inclusive) attr-dict
}];
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 0e709de347a11..b4e05c58bb019 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -578,6 +578,13 @@ LogicalResult SimdLoopOp::verify() {
if (this->lowerBound().empty()) {
return emitOpError() << "empty lowerbound for simd loop operation";
}
+ if (this->simdlen().has_value() && this->safelen().has_value() &&
+ this->simdlen().value() > this->safelen().value()) {
+ return emitOpError()
+ << "simdlen clause and safelen clause are both present, but the "
+ "simdlen value is not less than or equal to safelen value";
+ }
+
return success();
}
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 76bbb2824d5e3..d390eae680419 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -970,10 +970,14 @@ convertOmpSimdLoop(Operation &opInst, llvm::IRBuilderBase &builder,
if (llvm::Optional<uint64_t> simdlenVar = loop.simdlen())
simdlen = builder.getInt64(simdlenVar.value());
+ llvm::ConstantInt *safelen = nullptr;
+ if (llvm::Optional<uint64_t> safelenVar = loop.safelen())
+ safelen = builder.getInt64(safelenVar.value());
+
ompBuilder->applySimd(
loopInfo,
loop.if_expr() ? moduleTranslation.lookupValue(loop.if_expr()) : nullptr,
- simdlen, nullptr);
+ simdlen, safelen);
builder.restoreIP(afterIP);
return success();
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index c833bdd0f44a6..ef0fc9d0057a8 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -215,6 +215,26 @@ func.func @omp_simdloop_pretty_simdlen(%lb : index, %ub : index, %step : index)
// -----
+func.func @omp_simdloop_pretty_safelen(%lb : index, %ub : index, %step : index) -> () {
+ // expected-error @below {{op attribute 'safelen' failed to satisfy constraint: 64-bit signless integer attribute whose value is positive}}
+ omp.simdloop safelen(0) for (%iv): index = (%lb) to (%ub) step (%step) {
+ omp.yield
+ }
+ return
+}
+
+// -----
+
+func.func @omp_simdloop_pretty_simdlen_safelen(%lb : index, %ub : index, %step : index) -> () {
+ // expected-error @below {{'omp.simdloop' op simdlen clause and safelen clause are both present, but the simdlen value is not less than or equal to safelen value}}
+ omp.simdloop simdlen(2) safelen(1) for (%iv): index = (%lb) to (%ub) step (%step) {
+ omp.yield
+ }
+ return
+}
+
+// -----
+
// expected-error @below {{op expects initializer region with one argument of the reduction type}}
omp.reduction.declare @add_f32 : f64
init {
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 99c35fcb76616..4cc8fd51804c2 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -366,6 +366,15 @@ func.func @omp_simdloop_pretty_simdlen(%lb : index, %ub : index, %step : index)
return
}
+// CHECK-LABEL: omp_simdloop_pretty_safelen
+func.func @omp_simdloop_pretty_safelen(%lb : index, %ub : index, %step : index) -> () {
+ // CHECK: omp.simdloop safelen(2) for (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}})
+ omp.simdloop safelen(2) for (%iv): index = (%lb) to (%ub) step (%step) {
+ omp.yield
+ }
+ return
+}
+
// CHECK-LABEL: omp_simdloop_pretty_multiple
func.func @omp_simdloop_pretty_multiple(%lb1 : index, %ub1 : index, %step1 : index, %lb2 : index, %ub2 : index, %step2 : index) -> () {
// CHECK: omp.simdloop for (%{{.*}}, %{{.*}}) : index = (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}})
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index e827c0c2ad5b4..787575aca6dd9 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -765,6 +765,40 @@ llvm.func @simdloop_simple_multiple_simdlen(%lb1 : i64, %ub1 : i64, %step1 : i64
// -----
+// CHECK-LABEL: @simdloop_simple_multiple_safelen
+llvm.func @simdloop_simple_multiple_safelen(%lb1 : i64, %ub1 : i64, %step1 : i64, %lb2 : i64, %ub2 : i64, %step2 : i64, %arg0: !llvm.ptr<f32>, %arg1: !llvm.ptr<f32>) {
+ omp.simdloop safelen(2) for (%iv1, %iv2) : i64 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) {
+ %3 = llvm.mlir.constant(2.000000e+00 : f32) : f32
+ %4 = llvm.getelementptr %arg0[%iv1] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
+ %5 = llvm.getelementptr %arg1[%iv2] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
+ llvm.store %3, %4 : !llvm.ptr<f32>
+ llvm.store %3, %5 : !llvm.ptr<f32>
+ omp.yield
+ }
+ llvm.return
+}
+// CHECK: llvm.loop.vectorize.enable
+// CHECK-NEXT: llvm.loop.vectorize.width{{.*}}i64 2
+
+// -----
+
+// CHECK-LABEL: @simdloop_simple_multiple_simdlen_safelen
+llvm.func @simdloop_simple_multiple_simdlen_safelen(%lb1 : i64, %ub1 : i64, %step1 : i64, %lb2 : i64, %ub2 : i64, %step2 : i64, %arg0: !llvm.ptr<f32>, %arg1: !llvm.ptr<f32>) {
+ omp.simdloop simdlen(1) safelen(2) for (%iv1, %iv2) : i64 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) {
+ %3 = llvm.mlir.constant(2.000000e+00 : f32) : f32
+ %4 = llvm.getelementptr %arg0[%iv1] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
+ %5 = llvm.getelementptr %arg1[%iv2] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
+ llvm.store %3, %4 : !llvm.ptr<f32>
+ llvm.store %3, %5 : !llvm.ptr<f32>
+ omp.yield
+ }
+ llvm.return
+}
+// CHECK: llvm.loop.vectorize.enable
+// CHECK-NEXT: llvm.loop.vectorize.width{{.*}}i64 1
+
+// -----
+
// CHECK-LABEL: @simdloop_if
llvm.func @simdloop_if(%arg0: !llvm.ptr<i32> {fir.bindc_name = "n"}, %arg1: !llvm.ptr<i32> {fir.bindc_name = "threshold"}) {
%0 = llvm.mlir.constant(1 : i64) : i64
More information about the flang-commits
mailing list