diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir --- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -242,6 +242,80 @@ // CHECK: llvm.return // CHECK: } +func.func @_QPopenmp_target_data_region() { + %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFopenmp_target_data_regionEa"} + %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFopenmp_target_data_regionEi"} + omp.target_data map((tofrom -> %0 : !fir.ref>)) { + %c1_i32 = arith.constant 1 : i32 + %2 = fir.convert %c1_i32 : (i32) -> index + %c1024_i32 = arith.constant 1024 : i32 + %3 = fir.convert %c1024_i32 : (i32) -> index + %c1 = arith.constant 1 : index + %4 = fir.convert %2 : (index) -> i32 + %5:2 = fir.do_loop %arg0 = %2 to %3 step %c1 iter_args(%arg1 = %4) -> (index, i32) { + fir.store %arg1 to %1 : !fir.ref + %6 = fir.load %1 : !fir.ref + %7 = fir.load %1 : !fir.ref + %8 = fir.convert %7 : (i32) -> i64 + %c1_i64 = arith.constant 1 : i64 + %9 = arith.subi %8, %c1_i64 : i64 + %10 = fir.coordinate_of %0, %9 : (!fir.ref>, i64) -> !fir.ref + fir.store %6 to %10 : !fir.ref + %11 = arith.addi %arg0, %c1 : index + %12 = fir.convert %c1 : (index) -> i32 + %13 = fir.load %1 : !fir.ref + %14 = arith.addi %13, %12 : i32 + fir.result %11, %14 : index, i32 + } + fir.store %5#1 to %1 : !fir.ref + omp.terminator + } + return +} + +// CHECK-LABEL: llvm.func @_QPopenmp_target_data_region() { +// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64 +// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<1024 x i32> {bindc_name = "a", in_type = !fir.array<1024xi32>, operand_segment_sizes = array, uniq_name = "_QFopenmp_target_data_regionEa"} : (i64) -> !llvm.ptr> +// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(1 : i64) : i64 +// CHECK: %[[VAL_3:.*]] = llvm.alloca %[[VAL_2]] x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array, uniq_name = "_QFopenmp_target_data_regionEi"} : (i64) -> !llvm.ptr +// CHECK: omp.target_data map((tofrom -> %[[VAL_1]] : !llvm.ptr>)) { +// CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i32) : i32 +// CHECK: %[[VAL_5:.*]] = llvm.sext %[[VAL_4]] : i32 to i64 +// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1024 : i32) : i32 +// CHECK: %[[VAL_7:.*]] = llvm.sext %[[VAL_6]] : i32 to i64 +// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(1 : index) : i64 +// CHECK: %[[VAL_9:.*]] = llvm.trunc %[[VAL_5]] : i64 to i32 +// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_7]], %[[VAL_5]] : i64 +// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_10]], %[[VAL_8]] : i64 +// CHECK: llvm.br ^bb1(%[[VAL_5]], %[[VAL_9]], %[[VAL_11]] : i64, i32, i64) +// CHECK: ^bb1(%[[VAL_12:.*]]: i64, %[[VAL_13:.*]]: i32, %[[VAL_14:.*]]: i64): +// CHECK: %[[VAL_15:.*]] = llvm.mlir.constant(0 : index) : i64 +// CHECK: %[[VAL_16:.*]] = llvm.icmp "sgt" %[[VAL_14]], %[[VAL_15]] : i64 +// CHECK: llvm.cond_br %[[VAL_16]], ^bb2, ^bb3 +// CHECK: ^bb2: +// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : !llvm.ptr +// CHECK: %[[VAL_17:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr +// CHECK: %[[VAL_18:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr +// CHECK: %[[VAL_19:.*]] = llvm.sext %[[VAL_18]] : i32 to i64 +// CHECK: %[[VAL_20:.*]] = llvm.mlir.constant(1 : i64) : i64 +// CHECK: %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]] : i64 +// CHECK: %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr>, i64) -> !llvm.ptr +// CHECK: llvm.store %[[VAL_17]], %[[VAL_22]] : !llvm.ptr +// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32 +// CHECK: %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr +// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] : i32 +// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64 +// CHECK: %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]] : i64 +// CHECK: llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64) +// CHECK: ^bb3: +// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : !llvm.ptr +// CHECK: omp.terminator +// CHECK: } +// CHECK: llvm.return +// CHECK: } + func.func @_QPsimdloop_with_nested_loop() { %0 = fir.alloca i32 {adapt.valuebyref} %1 = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFsimdloop_with_nested_loopEa"} diff --git a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp --- a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp +++ b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp @@ -116,19 +116,20 @@ target.addDynamicallyLegalOp< mlir::omp::CriticalOp, mlir::omp::ParallelOp, mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp, mlir::omp::MasterOp, mlir::omp::SectionsOp, - mlir::omp::SingleOp, mlir::omp::TaskOp>([&](Operation *op) { - return typeConverter.isLegal(&op->getRegion(0)) && - typeConverter.isLegal(op->getOperandTypes()) && - typeConverter.isLegal(op->getResultTypes()); - }); - target.addDynamicallyLegalOp( + mlir::omp::SingleOp, mlir::omp::TaskOp, mlir::omp::DataOp>( [&](Operation *op) { - return typeConverter.isLegal(op->getOperandTypes()) && + return typeConverter.isLegal(&op->getRegion(0)) && + typeConverter.isLegal(op->getOperandTypes()) && typeConverter.isLegal(op->getResultTypes()); }); + target + .addDynamicallyLegalOp( + [&](Operation *op) { + return typeConverter.isLegal(op->getOperandTypes()) && + typeConverter.isLegal(op->getResultTypes()); + }); target.addDynamicallyLegalOp([&](Operation *op) { return typeConverter.isLegal(op->getOperandTypes()); }); @@ -137,19 +138,19 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns) { patterns.add< - ReductionOpConversion, RegionOpConversion, - RegionOpConversion, ReductionOpConversion, - RegionOpConversion, RegionOpConversion, - RegionOpConversion, RegionOpConversion, - RegionOpConversion, RegionOpConversion, - RegionOpConversion, + LegalizeDataOpForLLVMTranslation, + LegalizeDataOpForLLVMTranslation, + LegalizeDataOpForLLVMTranslation, ReductionOpConversion, + RegionOpConversion, RegionOpConversion, + ReductionOpConversion, RegionOpConversion, + RegionOpConversion, RegionOpConversion, + RegionOpConversion, RegionOpConversion, + RegionOpConversion, RegionOpConversion, + RegionOpConversion, RegionLessOpWithVarOperandsConversion, RegionLessOpWithVarOperandsConversion, RegionLessOpWithVarOperandsConversion, - RegionLessOpWithVarOperandsConversion, - LegalizeDataOpForLLVMTranslation, - LegalizeDataOpForLLVMTranslation, - LegalizeDataOpForLLVMTranslation>(converter); + RegionLessOpWithVarOperandsConversion>(converter); } namespace { diff --git a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir --- a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir @@ -176,3 +176,23 @@ 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: @_QPomp_target_data_region +// CHECK: (%[[ARG0:.*]]: !llvm.ptr>, %[[ARG1:.*]]: !llvm.ptr) { +// CHECK: omp.target_data map((tofrom -> %[[ARG0]] : !llvm.ptr>)) { +// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(10 : i32) : i32 +// CHECK: llvm.store %[[VAL_1]], %[[ARG1]] : !llvm.ptr +// CHECK: omp.terminator +// CHECK: } +// CHECK: llvm.return + +llvm.func @_QPomp_target_data_region(%a : !llvm.ptr>, %i : !llvm.ptr) { + omp.target_data map((tofrom -> %a : !llvm.ptr>)) { + %1 = llvm.mlir.constant(10 : i32) : i32 + llvm.store %1, %i : !llvm.ptr + omp.terminator + } + llvm.return +}