Skip to content

Commit b8055c5

Browse files
committed
[MLIR][OpenMP] Add support for safelen clause
This supports translation from MLIR to LLVM IR using OMPIRBuilder for OpenMP safelen clause in SIMD construct. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D132245
1 parent 4fce38c commit b8055c5

File tree

7 files changed

+82
-2
lines changed

7 files changed

+82
-2
lines changed

flang/lib/Lower/OpenMP.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
11501150
TypeRange resultType;
11511151
auto SimdLoopOp = firOpBuilder.create<mlir::omp::SimdLoopOp>(
11521152
currentLocation, resultType, lowerBound, upperBound, step,
1153-
ifClauseOperand, simdlenClauseOperand,
1153+
ifClauseOperand, simdlenClauseOperand, nullptr,
11541154
/*inclusive=*/firOpBuilder.getUnitAttr());
11551155
createBodyOfOp<omp::SimdLoopOp>(SimdLoopOp, converter, currentLocation,
11561156
eval, &loopOpClauseList, iv);

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
421421

422422
When a simdlen clause is present, the preferred number of iterations to be
423423
executed concurrently is the value provided to the simdlen clause.
424+
425+
The safelen clause specifies that no two concurrent iterations within a
426+
SIMD chunk can have a distance in the logical iteration space that is
427+
greater than or equal to the value given in the clause.
424428
```
425429
omp.simdloop <clauses>
426430
for (%i1, %i2) : index = (%c0, %c0) to (%c10, %c10) step (%c1, %c1) {
@@ -436,13 +440,15 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
436440
Variadic<IntLikeType>:$step,
437441
Optional<I1>:$if_expr,
438442
ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$simdlen,
443+
ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$safelen,
439444
UnitAttr:$inclusive
440445
);
441446

442447
let regions = (region AnyRegion:$region);
443448
let assemblyFormat = [{
444449
oilist(`if` `(` $if_expr `)`
445450
|`simdlen` `(` $simdlen `)`
451+
|`safelen` `(` $safelen `)`
446452
) `for` custom<LoopControl>($region, $lowerBound, $upperBound, $step,
447453
type($step), $inclusive) attr-dict
448454
}];

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,13 @@ LogicalResult SimdLoopOp::verify() {
578578
if (this->lowerBound().empty()) {
579579
return emitOpError() << "empty lowerbound for simd loop operation";
580580
}
581+
if (this->simdlen().has_value() && this->safelen().has_value() &&
582+
this->simdlen().value() > this->safelen().value()) {
583+
return emitOpError()
584+
<< "simdlen clause and safelen clause are both present, but the "
585+
"simdlen value is not less than or equal to safelen value";
586+
}
587+
581588
return success();
582589
}
583590

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,10 +970,14 @@ convertOmpSimdLoop(Operation &opInst, llvm::IRBuilderBase &builder,
970970
if (llvm::Optional<uint64_t> simdlenVar = loop.simdlen())
971971
simdlen = builder.getInt64(simdlenVar.value());
972972

973+
llvm::ConstantInt *safelen = nullptr;
974+
if (llvm::Optional<uint64_t> safelenVar = loop.safelen())
975+
safelen = builder.getInt64(safelenVar.value());
976+
973977
ompBuilder->applySimd(
974978
loopInfo,
975979
loop.if_expr() ? moduleTranslation.lookupValue(loop.if_expr()) : nullptr,
976-
simdlen, nullptr);
980+
simdlen, safelen);
977981

978982
builder.restoreIP(afterIP);
979983
return success();

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,26 @@ func.func @omp_simdloop_pretty_simdlen(%lb : index, %ub : index, %step : index)
215215

216216
// -----
217217

218+
func.func @omp_simdloop_pretty_safelen(%lb : index, %ub : index, %step : index) -> () {
219+
// expected-error @below {{op attribute 'safelen' failed to satisfy constraint: 64-bit signless integer attribute whose value is positive}}
220+
omp.simdloop safelen(0) for (%iv): index = (%lb) to (%ub) step (%step) {
221+
omp.yield
222+
}
223+
return
224+
}
225+
226+
// -----
227+
228+
func.func @omp_simdloop_pretty_simdlen_safelen(%lb : index, %ub : index, %step : index) -> () {
229+
// 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}}
230+
omp.simdloop simdlen(2) safelen(1) for (%iv): index = (%lb) to (%ub) step (%step) {
231+
omp.yield
232+
}
233+
return
234+
}
235+
236+
// -----
237+
218238
// expected-error @below {{op expects initializer region with one argument of the reduction type}}
219239
omp.reduction.declare @add_f32 : f64
220240
init {

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,15 @@ func.func @omp_simdloop_pretty_simdlen(%lb : index, %ub : index, %step : index)
366366
return
367367
}
368368

369+
// CHECK-LABEL: omp_simdloop_pretty_safelen
370+
func.func @omp_simdloop_pretty_safelen(%lb : index, %ub : index, %step : index) -> () {
371+
// CHECK: omp.simdloop safelen(2) for (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}})
372+
omp.simdloop safelen(2) for (%iv): index = (%lb) to (%ub) step (%step) {
373+
omp.yield
374+
}
375+
return
376+
}
377+
369378
// CHECK-LABEL: omp_simdloop_pretty_multiple
370379
func.func @omp_simdloop_pretty_multiple(%lb1 : index, %ub1 : index, %step1 : index, %lb2 : index, %ub2 : index, %step2 : index) -> () {
371380
// CHECK: omp.simdloop for (%{{.*}}, %{{.*}}) : index = (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}})

mlir/test/Target/LLVMIR/openmp-llvm.mlir

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,40 @@ llvm.func @simdloop_simple_multiple_simdlen(%lb1 : i64, %ub1 : i64, %step1 : i64
765765

766766
// -----
767767

768+
// CHECK-LABEL: @simdloop_simple_multiple_safelen
769+
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>) {
770+
omp.simdloop safelen(2) for (%iv1, %iv2) : i64 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) {
771+
%3 = llvm.mlir.constant(2.000000e+00 : f32) : f32
772+
%4 = llvm.getelementptr %arg0[%iv1] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
773+
%5 = llvm.getelementptr %arg1[%iv2] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
774+
llvm.store %3, %4 : !llvm.ptr<f32>
775+
llvm.store %3, %5 : !llvm.ptr<f32>
776+
omp.yield
777+
}
778+
llvm.return
779+
}
780+
// CHECK: llvm.loop.vectorize.enable
781+
// CHECK-NEXT: llvm.loop.vectorize.width{{.*}}i64 2
782+
783+
// -----
784+
785+
// CHECK-LABEL: @simdloop_simple_multiple_simdlen_safelen
786+
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>) {
787+
omp.simdloop simdlen(1) safelen(2) for (%iv1, %iv2) : i64 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) {
788+
%3 = llvm.mlir.constant(2.000000e+00 : f32) : f32
789+
%4 = llvm.getelementptr %arg0[%iv1] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
790+
%5 = llvm.getelementptr %arg1[%iv2] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
791+
llvm.store %3, %4 : !llvm.ptr<f32>
792+
llvm.store %3, %5 : !llvm.ptr<f32>
793+
omp.yield
794+
}
795+
llvm.return
796+
}
797+
// CHECK: llvm.loop.vectorize.enable
798+
// CHECK-NEXT: llvm.loop.vectorize.width{{.*}}i64 1
799+
800+
// -----
801+
768802
// CHECK-LABEL: @simdloop_if
769803
llvm.func @simdloop_if(%arg0: !llvm.ptr<i32> {fir.bindc_name = "n"}, %arg1: !llvm.ptr<i32> {fir.bindc_name = "threshold"}) {
770804
%0 = llvm.mlir.constant(1 : i64) : i64

0 commit comments

Comments
 (0)