diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir index 3764e42939c1c..159be7a036187 100644 --- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -353,3 +353,56 @@ fir.global internal @_QFsEc : i32 { // CHECK: %[[INIT_10:.*]] = llvm.mlir.constant(10 : i32) : i32 // CHECK: llvm.return %[[INIT_10]] : i32 // CHECK: } + +func.func @_QPsb() { + %c10 = arith.constant 10 : index + %c1 = arith.constant 1 : index + %c1_i32 = arith.constant 1 : i32 + %c0_i32 = arith.constant 0 : i32 + %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"} + %1 = fir.alloca i32 {bindc_name = "li", uniq_name = "_QFsbEli"} + fir.store %c0_i32 to %1 : !fir.ref + omp.sections { + omp.section { + %2 = fir.convert %c1 : (index) -> i32 + %3:2 = fir.do_loop %arg0 = %c1 to %c10 step %c1 iter_args(%arg1 = %2) -> (index, i32) { + fir.store %arg1 to %0 : !fir.ref + %4 = fir.load %1 : !fir.ref + %5 = arith.addi %4, %c1_i32 : i32 + fir.store %5 to %1 : !fir.ref + %6 = arith.addi %arg0, %c1 : index + %7 = fir.convert %c1 : (index) -> i32 + %8 = fir.load %0 : !fir.ref + %9 = arith.addi %8, %7 : i32 + fir.result %6, %9 : index, i32 + } + fir.store %3#1 to %0 : !fir.ref + omp.terminator + } + omp.terminator + } + return +} + +// CHECK: llvm.func @_QPsb() { +// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32 +// CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i64) : i64 +// CHECK: %[[LI_REF:.*]] = llvm.alloca %6 x i32 {bindc_name = "li", in_type = i32, operand_segment_sizes = array, uniq_name = "_QFsbEli"} : (i64) -> !llvm.ptr +// CHECK: omp.sections { +// CHECK: omp.section { +// CHECK: llvm.br ^[[BB_ENTRY:.*]]({{.*}}) +// CHECK: ^[[BB_ENTRY]]({{.*}}): +// CHECK: %[[EXIT_COND:.*]] = llvm.icmp "sgt" +// CHECK: llvm.cond_br %[[EXIT_COND]], ^[[BB_LOOP_BODY:.*]], ^[[BB_EXIT:.*]] +// CHECK: ^[[BB_LOOP_BODY]]: +// CHECK: %[[LI_VAL:.*]] = llvm.load %[[LI_REF]] : !llvm.ptr +// CHECK: %[[LI_INC:.*]] = llvm.add %[[LI_VAL]], %[[ONE]] : i32 +// CHECK: llvm.store %[[LI_INC]], %[[LI_REF]] : !llvm.ptr +// CHECK: llvm.br ^[[BB_ENTRY]]({{.*}}) +// CHECK: ^[[BB_EXIT]]: +// CHECK: omp.terminator +// CHECK: } +// CHECK: omp.terminator +// CHECK: } +// CHECK: llvm.return +// CHECK: } diff --git a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp index 621600b268c0f..d2eecf2943594 100644 --- a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp +++ b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp @@ -151,10 +151,11 @@ struct LegalizeDataOpForLLVMTranslation : public ConvertOpToLLVMPattern { void mlir::configureOpenMPToLLVMConversionLegality( ConversionTarget &target, LLVMTypeConverter &typeConverter) { - target.addDynamicallyLegalOp< - mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::ParallelOp, - mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp, mlir::omp::MasterOp, - mlir::omp::SectionsOp, mlir::omp::SingleOp, mlir::omp::TaskOp>( + target.addDynamicallyLegalOp( [&](Operation *op) { return typeConverter.isLegal(&op->getRegion(0)) && typeConverter.isLegal(op->getOperandTypes()) && @@ -180,8 +181,8 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, RegionOpConversion, ReductionOpConversion, RegionOpConversion, RegionOpConversion, RegionOpConversion, RegionOpConversion, - RegionOpConversion, RegionOpConversion, - RegionOpConversion, + RegionOpConversion, RegionOpConversion, + RegionOpConversion, RegionOpConversion, RegionLessOpWithVarOperandsConversion, RegionLessOpWithVarOperandsConversion, RegionOpWithVarOperandsConversion, diff --git a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir index 74c1b19ea5102..220dd868d0e52 100644 --- a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir @@ -202,3 +202,37 @@ llvm.func @_QPomp_target_data(%a : !llvm.ptr, %b : !llvm.ptr, %c : !ll omp.target_exit_data map((from -> %a : !llvm.ptr), (from -> %b : !llvm.ptr), (release -> %c : !llvm.ptr), (always, delete -> %d : !llvm.ptr)) llvm.return } + +// ----- + +// CHECK-LABEL: @_QPsb +// CHECK: omp.sections +// CHECK: omp.section +// CHECK: llvm.br +// CHECK: llvm.icmp +// CHECK: llvm.cond_br +// CHECK: llvm.br +// CHECK: omp.terminator +// CHECK: omp.terminator +// CHECK: llvm.return + +llvm.func @_QPsb() { + %0 = llvm.mlir.constant(0 : i64) : i64 + %1 = llvm.mlir.constant(10 : i64) : i64 + %2 = llvm.mlir.constant(1 : i64) : i64 + omp.sections { + omp.section { + llvm.br ^bb1(%1 : i64) + ^bb1(%3: i64): // 2 preds: ^bb0, ^bb2 + %4 = llvm.icmp "sgt" %3, %0 : i64 + llvm.cond_br %4, ^bb2, ^bb3 + ^bb2: // pred: ^bb1 + %5 = llvm.sub %3, %2 : i64 + llvm.br ^bb1(%5 : i64) + ^bb3: // pred: ^bb1 + omp.terminator + } + omp.terminator + } + llvm.return +}