diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1722,9 +1722,13 @@ std::get(std::get<3>(atomicRead.t).statement.t); const auto &assignmentStmtVariable = std::get( std::get<3>(atomicRead.t).statement.t); + Fortran::lower::StatementContext stmtCtx; - mlir::Value from_address = fir::getBase(converter.genExprAddr( - *Fortran::semantics::GetExpr(assignmentStmtExpr), stmtCtx)); + const Fortran::semantics::SomeExpr &fromExpr = + *Fortran::semantics::GetExpr(assignmentStmtExpr); + mlir::Type elementType = converter.genType(fromExpr); + mlir::Value from_address = + fir::getBase(converter.genExprAddr(fromExpr, stmtCtx)); mlir::Value to_address = fir::getBase(converter.genExprAddr( *Fortran::semantics::GetExpr(assignmentStmtVariable), stmtCtx)); // If no hint clause is specified, the effect is as if @@ -1735,8 +1739,9 @@ memory_order); genOmpAtomicHintAndMemoryOrderClauses(converter, rightHandClauseList, hint, memory_order); - firOpBuilder.create(currentLocation, from_address, - to_address, hint, memory_order); + firOpBuilder.create( + currentLocation, from_address, to_address, + mlir::TypeAttr::get(elementType), hint, memory_order); } static void diff --git a/flang/test/Lower/OpenMP/atomic-read.f90 b/flang/test/Lower/OpenMP/atomic-read.f90 --- a/flang/test/Lower/OpenMP/atomic-read.f90 +++ b/flang/test/Lower/OpenMP/atomic-read.f90 @@ -13,12 +13,12 @@ !CHECK: %[[VAR_H:.*]] = fir.alloca f32 {bindc_name = "h", uniq_name = "_QFEh"} !CHECK: %[[VAR_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"} !CHECK: %[[VAR_Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"} -!CHECK: omp.atomic.read %[[VAR_X]] = %[[VAR_Y]] memory_order(acquire) hint(uncontended) : !fir.ref -!CHECK: omp.atomic.read %[[VAR_A]] = %[[VAR_B]] memory_order(relaxed) hint(none) : !fir.ref> -!CHECK: omp.atomic.read %[[VAR_C]] = %[[VAR_D]] memory_order(seq_cst) hint(contended) : !fir.ref> -!CHECK: omp.atomic.read %[[VAR_E]] = %[[VAR_F]] hint(speculative) : !fir.ref> -!CHECK: omp.atomic.read %[[VAR_G]] = %[[VAR_H]] hint(nonspeculative) : !fir.ref -!CHECK: omp.atomic.read %[[VAR_G]] = %[[VAR_H]] : !fir.ref +!CHECK: omp.atomic.read %[[VAR_X]] = %[[VAR_Y]] memory_order(acquire) hint(uncontended) : !fir.ref, i32 +!CHECK: omp.atomic.read %[[VAR_A]] = %[[VAR_B]] memory_order(relaxed) hint(none) : !fir.ref>, !fir.char<1> +!CHECK: omp.atomic.read %[[VAR_C]] = %[[VAR_D]] memory_order(seq_cst) hint(contended) : !fir.ref>, !fir.logical<4> +!CHECK: omp.atomic.read %[[VAR_E]] = %[[VAR_F]] hint(speculative) : !fir.ref>, !fir.char<1,8> +!CHECK: omp.atomic.read %[[VAR_G]] = %[[VAR_H]] hint(nonspeculative) : !fir.ref, f32 +!CHECK: omp.atomic.read %[[VAR_G]] = %[[VAR_H]] : !fir.ref, f32 !CHECK: return !CHECK: } @@ -59,7 +59,7 @@ !CHECK: fir.store %[[VAL_5]] to %[[VAL_4]] : !fir.ref> !CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_1]] : !fir.ref> !CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_4]] : !fir.ref> -!CHECK: omp.atomic.read %[[VAL_7]] = %[[VAL_6]] : !fir.ptr +!CHECK: omp.atomic.read %[[VAL_7]] = %[[VAL_6]] : !fir.ptr, i32 !CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_4]] : !fir.ref> !CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ptr !CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_1]] : !fir.ref> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 @@ -57,7 +57,7 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C100]]) inclusive step (%[[C1_2]]) !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : i32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -86,7 +86,7 @@ !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_i32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_f32:.*]] = fir.convert %[[I_PVT_VAL_i32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : f32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -114,7 +114,7 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C100]]) inclusive step (%[[C1_2]]) !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : i32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -143,7 +143,7 @@ !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_i32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_f32:.*]] = fir.convert %[[I_PVT_VAL_i32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : f32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -168,11 +168,11 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref, @[[RED_I32_NAME]] -> %[[YREF]] : !fir.ref, @[[RED_I32_NAME]] -> %[[ZREF]] : !fir.ref) for (%[[IVAL]]) : i32 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL1]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL1]], %[[XREF]] : i32, !fir.ref !CHECK: %[[I_PVT_VAL2:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL2]], %[[YREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL2]], %[[YREF]] : i32, !fir.ref !CHECK: %[[I_PVT_VAL3:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL3]], %[[ZREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL3]], %[[ZREF]] : i32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -202,13 +202,13 @@ !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1_F32:.*]] = fir.convert %[[I_PVT_VAL1_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL1_F32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL1_F32]], %[[XREF]] : f32, !fir.ref !CHECK: %[[I_PVT_VAL2_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL2_F32:.*]] = fir.convert %[[I_PVT_VAL2_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL2_F32]], %[[YREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL2_F32]], %[[YREF]] : f32, !fir.ref !CHECK: %[[I_PVT_VAL3_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL3_F32:.*]] = fir.convert %[[I_PVT_VAL3_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : f32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -238,16 +238,16 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref, @[[RED_I64_NAME]] -> %[[YREF]] : !fir.ref, @[[RED_F32_NAME]] -> %[[ZREF]] : !fir.ref, @[[RED_F64_NAME]] -> %[[WREF]] : !fir.ref) for (%[[IVAL:.*]]) : i32 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL1_I32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL1_I32]], %[[XREF]] : i32, !fir.ref !CHECK: %[[I_PVT_VAL2_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL2_I64:.*]] = fir.convert %[[I_PVT_VAL2_I32]] : (i32) -> i64 -!CHECK: omp.reduction %[[I_PVT_VAL2_I64]], %[[YREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL2_I64]], %[[YREF]] : i64, !fir.ref !CHECK: %[[I_PVT_VAL3_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL3_F32:.*]] = fir.convert %[[I_PVT_VAL3_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : f32, !fir.ref !CHECK: %[[I_PVT_VAL4_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL4_F64:.*]] = fir.convert %[[I_PVT_VAL4_I32]] : (i32) -> f64 -!CHECK: omp.reduction %[[I_PVT_VAL4_F64]], %[[WREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL4_F64]], %[[WREF]] : f64, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 @@ -29,7 +29,7 @@ !CHECK: %[[SUBI:.*]] = arith.subi %[[CONVI_64]], %[[C1_64]] : i64 !CHECK: %[[Y_PVT_REF:.*]] = fir.coordinate_of %[[ARRAY]], %[[SUBI]] : (!fir.ref>>, i64) -> !fir.ref> !CHECK: %[[YVAL:.*]] = fir.load %[[Y_PVT_REF]] : !fir.ref> -!CHECK: omp.reduction %[[YVAL]], %[[XREF]] : !fir.ref> +!CHECK: omp.reduction %[[YVAL]], %[[XREF]] : !fir.logical<4>, !fir.ref> !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -62,7 +62,7 @@ !CHECK: %[[SUBI:.*]] = arith.subi %[[CONVI_64]], %[[C1_64]] : i64 !CHECK: %[[Y_PVT_REF:.*]] = fir.coordinate_of %[[ARRAY]], %[[SUBI]] : (!fir.ref>>, i64) -> !fir.ref> !CHECK: %[[YVAL:.*]] = fir.load %[[Y_PVT_REF]] : !fir.ref> -!CHECK: omp.reduction %[[YVAL]], %[[XREF]] : !fir.ref> +!CHECK: omp.reduction %[[YVAL]], %[[XREF]] : !fir.logical<4>, !fir.ref> !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -97,21 +97,21 @@ !CHECK: %[[SUBI_1:.*]] = arith.subi %[[CONVI_64_1]], %[[C1_64]] : i64 !CHECK: %[[W_PVT_REF_1:.*]] = fir.coordinate_of %[[ARRAY]], %[[SUBI_1]] : (!fir.ref>>, i64) -> !fir.ref> !CHECK: %[[WVAL:.*]] = fir.load %[[W_PVT_REF_1]] : !fir.ref> -!CHECK: omp.reduction %[[WVAL]], %[[XREF]] : !fir.ref> +!CHECK: omp.reduction %[[WVAL]], %[[XREF]] : !fir.logical<4>, !fir.ref> !CHECK: %[[I_PVT_VAL2:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[CONVI_64_2:.*]] = fir.convert %[[I_PVT_VAL2]] : (i32) -> i64 !CHECK: %[[C1_64:.*]] = arith.constant 1 : i64 !CHECK: %[[SUBI_2:.*]] = arith.subi %[[CONVI_64_2]], %[[C1_64]] : i64 !CHECK: %[[W_PVT_REF_2:.*]] = fir.coordinate_of %[[ARRAY]], %[[SUBI_2]] : (!fir.ref>>, i64) -> !fir.ref> !CHECK: %[[WVAL:.*]] = fir.load %[[W_PVT_REF_2]] : !fir.ref> -!CHECK: omp.reduction %[[WVAL]], %[[YREF]] : !fir.ref> +!CHECK: omp.reduction %[[WVAL]], %[[YREF]] : !fir.logical<4>, !fir.ref> !CHECK: %[[I_PVT_VAL3:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[CONVI_64_3:.*]] = fir.convert %[[I_PVT_VAL3]] : (i32) -> i64 !CHECK: %[[C1_64:.*]] = arith.constant 1 : i64 !CHECK: %[[SUBI_3:.*]] = arith.subi %[[CONVI_64_3]], %[[C1_64]] : i64 !CHECK: %[[W_PVT_REF_3:.*]] = fir.coordinate_of %[[ARRAY]], %[[SUBI_3]] : (!fir.ref>>, i64) -> !fir.ref> !CHECK: %[[WVAL:.*]] = fir.load %[[W_PVT_REF_3]] : !fir.ref> -!CHECK: omp.reduction %[[WVAL]], %[[ZREF]] : !fir.ref> +!CHECK: omp.reduction %[[WVAL]], %[[ZREF]] : !fir.logical<4>, !fir.ref> !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 --- a/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 @@ -57,7 +57,7 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C10]]) inclusive step (%[[C1_2]]) !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : i32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -87,7 +87,7 @@ !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_i32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_f32:.*]] = fir.convert %[[I_PVT_VAL_i32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : f32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -115,7 +115,7 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref) for (%[[IVAL:.*]]) : i32 = (%[[C1_1]]) to (%[[C10]]) inclusive step (%[[C1_2]]) !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL]], %[[XREF]] : i32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -144,7 +144,7 @@ !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_i32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL_f32:.*]] = fir.convert %[[I_PVT_VAL_i32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL_f32]], %[[XREF]] : f32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -169,11 +169,11 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %[[XREF]] : !fir.ref, @[[RED_I32_NAME]] -> %[[YREF]] : !fir.ref, @[[RED_I32_NAME]] -> %[[ZREF]] : !fir.ref) for (%[[IVAL]]) : i32 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL1]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL1]], %[[XREF]] : i32, !fir.ref !CHECK: %[[I_PVT_VAL2:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL2]], %[[YREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL2]], %[[YREF]] : i32, !fir.ref !CHECK: %[[I_PVT_VAL3:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL3]], %[[ZREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL3]], %[[ZREF]] : i32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -203,13 +203,13 @@ !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1_F32:.*]] = fir.convert %[[I_PVT_VAL1_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL1_F32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL1_F32]], %[[XREF]] : f32, !fir.ref !CHECK: %[[I_PVT_VAL2_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL2_F32:.*]] = fir.convert %[[I_PVT_VAL2_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL2_F32]], %[[YREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL2_F32]], %[[YREF]] : f32, !fir.ref !CHECK: %[[I_PVT_VAL3_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL3_F32:.*]] = fir.convert %[[I_PVT_VAL3_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : f32, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return @@ -239,16 +239,16 @@ !CHECK: omp.wsloop reduction(@[[RED_I32_NAME]] -> %2 : !fir.ref, @[[RED_I64_NAME]] -> %3 : !fir.ref, @[[RED_F32_NAME]] -> %4 : !fir.ref, @[[RED_F64_NAME]] -> %1 : !fir.ref) for (%[[IVAL:.*]]) : i32 !CHECK: fir.store %[[IVAL]] to %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL1_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref -!CHECK: omp.reduction %[[I_PVT_VAL1_I32]], %[[XREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL1_I32]], %[[XREF]] : i32, !fir.ref !CHECK: %[[I_PVT_VAL2_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL2_I64:.*]] = fir.convert %[[I_PVT_VAL2_I32]] : (i32) -> i64 -!CHECK: omp.reduction %[[I_PVT_VAL2_I64]], %[[YREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL2_I64]], %[[YREF]] : i64, !fir.ref !CHECK: %[[I_PVT_VAL3_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL3_F32:.*]] = fir.convert %[[I_PVT_VAL3_I32]] : (i32) -> f32 -!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL3_F32]], %[[ZREF]] : f32, !fir.ref !CHECK: %[[I_PVT_VAL4_I32:.*]] = fir.load %[[I_PVT_REF]] : !fir.ref !CHECK: %[[I_PVT_VAL4_F64:.*]] = fir.convert %[[I_PVT_VAL4_I32]] : (i32) -> f64 -!CHECK: omp.reduction %[[I_PVT_VAL4_F64]], %[[WREF]] : !fir.ref +!CHECK: omp.reduction %[[I_PVT_VAL4_F64]], %[[WREF]] : f64, !fir.ref !CHECK: omp.yield !CHECK: omp.terminator !CHECK: return diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -1194,13 +1194,14 @@ let arguments = (ins OpenMP_PointerLikeType:$x, OpenMP_PointerLikeType:$v, + TypeAttr:$element_type, DefaultValuedOptionalAttr:$hint_val, OptionalAttr:$memory_order_val); let assemblyFormat = [{ $v `=` $x oilist( `memory_order` `(` custom($memory_order_val) `)` | `hint` `(` custom($hint_val) `)`) - `:` type($x) attr-dict + `:` type($x) `,` $element_type attr-dict }]; let hasVerifier = 1; let extraClassDeclaration = [{ @@ -1535,11 +1536,7 @@ // 2.19.5.4 reduction clause //===----------------------------------------------------------------------===// -def ReductionOp : OpenMP_Op<"reduction", [ - TypesMatchWith<"value types matches accumulator element type", - "accumulator", "operand", - "$_self.cast<::mlir::omp::PointerLikeType>().getElementType()"> - ]> { +def ReductionOp : OpenMP_Op<"reduction"> { let summary = "reduction construct"; let description = [{ Indicates the value that is produced by the current reduction-participating @@ -1549,8 +1546,9 @@ }]; let arguments= (ins AnyType:$operand, OpenMP_PointerLikeType:$accumulator); - let assemblyFormat = - "$operand `,` $accumulator attr-dict `:` type($accumulator)"; + let assemblyFormat = [{ + $operand `,` $accumulator attr-dict `:` type($operand) `,` type($accumulator) + }]; let hasVerifier = 1; } diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPTypeInterfaces.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPTypeInterfaces.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPTypeInterfaces.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPTypeInterfaces.td @@ -21,7 +21,9 @@ let methods = [ InterfaceMethod< - /*description=*/"Returns the pointee type.", + /*description=*/[{ + Returns the pointee type or null if the pointer has no pointee type + }], /*retTy=*/"::mlir::Type", /*methodName=*/"getElementType" >, diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -446,7 +446,7 @@ if (!accumulators.insert(accum).second) return op->emitOpError() << "accumulator variable used more than once"; - Type varType = accum.getType().cast(); + Type varType = accum.getType(); auto symbolRef = std::get<1>(args).cast(); auto decl = SymbolTable::lookupNearestSymbolFrom(op, symbolRef); @@ -932,7 +932,8 @@ "arguments of the same type"; auto ptrType = atomicReductionEntryBlock.getArgumentTypes()[0] .dyn_cast(); - if (!ptrType || ptrType.getElementType() != getType()) + if (!ptrType || + (ptrType.getElementType() && ptrType.getElementType() != getType())) return emitOpError() << "expects atomic reduction region arguments to " "be accumulators containing the reduction type"; return success(); @@ -1115,8 +1116,9 @@ "memory-order must not be acq_rel or acquire for atomic writes"); } } - if (getAddress().getType().cast().getElementType() != - getValue().getType()) + Type elementType = + getAddress().getType().cast().getElementType(); + if (elementType && elementType != getValue().getType()) return emitError("address must dereference to value type"); return verifySynchronizationHint(*this, getHintVal()); } @@ -1166,8 +1168,8 @@ if (getRegion().getNumArguments() != 1) return emitError("the region must accept exactly one argument"); - if (getX().getType().cast().getElementType() != - getRegion().getArgument(0).getType()) { + Type elementType = getX().getType().cast().getElementType(); + if (elementType && elementType != getRegion().getArgument(0).getType()) { return emitError("the type of the operand must be a pointer type whose " "element type is the same as that of the region argument"); } diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -759,10 +759,8 @@ llvm::IRBuilderBase::InsertPointGuard guard(builder); builder.restoreIP(allocaIP); for (unsigned i = 0; i < numReductions; ++i) { - auto reductionType = - loop.getReductionVars()[i].getType().cast(); llvm::Value *var = builder.CreateAlloca( - moduleTranslation.convertType(reductionType.getElementType())); + moduleTranslation.convertType(reductionDecls[i].getType())); privateReductionVariables.push_back(var); reductionVariableMap.try_emplace(loop.getReductionVars()[i], var); } @@ -893,14 +891,11 @@ llvm::OpenMPIRBuilder::AtomicReductionGenTy atomicGen = nullptr; if (owningAtomicReductionGens[i]) atomicGen = owningAtomicReductionGens[i]; - auto reductionType = - loop.getReductionVars()[i].getType().cast(); llvm::Value *variable = moduleTranslation.lookupValue(loop.getReductionVars()[i]); reductionInfos.push_back( - {moduleTranslation.convertType(reductionType.getElementType()), - variable, privateReductionVariables[i], owningReductionGens[i], - atomicGen}); + {moduleTranslation.convertType(reductionDecls[i].getType()), variable, + privateReductionVariables[i], owningReductionGens[i], atomicGen}); } // The call to createReductions below expects the block to have a @@ -1041,15 +1036,13 @@ llvm::AtomicOrdering AO = convertAtomicOrdering(readOp.getMemoryOrderVal()); llvm::Value *x = moduleTranslation.lookupValue(readOp.getX()); - Type xTy = - readOp.getX().getType().cast().getElementType(); llvm::Value *v = moduleTranslation.lookupValue(readOp.getV()); - Type vTy = - readOp.getV().getType().cast().getElementType(); - llvm::OpenMPIRBuilder::AtomicOpValue V = { - v, moduleTranslation.convertType(vTy), false, false}; - llvm::OpenMPIRBuilder::AtomicOpValue X = { - x, moduleTranslation.convertType(xTy), false, false}; + + llvm::Type *elementType = + moduleTranslation.convertType(readOp.getElementType()); + + llvm::OpenMPIRBuilder::AtomicOpValue V = {v, elementType, false, false}; + llvm::OpenMPIRBuilder::AtomicOpValue X = {x, elementType, false, false}; builder.restoreIP(ompBuilder->createAtomicRead(ompLoc, X, V, AO)); return success(); } @@ -1120,10 +1113,8 @@ : innerUpdateOp.getOperand(0)); llvm::Value *llvmExpr = moduleTranslation.lookupValue(mlirExpr); llvm::Value *llvmX = moduleTranslation.lookupValue(opInst.getX()); - LLVM::LLVMPointerType mlirXType = - opInst.getX().getType().cast(); - llvm::Type *llvmXElementType = - moduleTranslation.convertType(mlirXType.getElementType()); + llvm::Type *llvmXElementType = moduleTranslation.convertType( + opInst.getRegion().getArgument(0).getType()); llvm::OpenMPIRBuilder::AtomicOpValue llvmAtomicX = {llvmX, llvmXElementType, /*isSigned=*/false, /*isVolatile=*/false}; @@ -1208,12 +1199,8 @@ moduleTranslation.lookupValue(atomicCaptureOp.getAtomicReadOp().getX()); llvm::Value *llvmV = moduleTranslation.lookupValue(atomicCaptureOp.getAtomicReadOp().getV()); - auto mlirXType = atomicCaptureOp.getAtomicReadOp() - .getX() - .getType() - .cast(); - llvm::Type *llvmXElementType = - moduleTranslation.convertType(mlirXType.getElementType()); + llvm::Type *llvmXElementType = moduleTranslation.convertType( + atomicCaptureOp.getAtomicReadOp().getElementType()); llvm::OpenMPIRBuilder::AtomicOpValue llvmAtomicX = {llvmX, llvmXElementType, /*isSigned=*/false, /*isVolatile=*/false}; 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 @@ -103,7 +103,7 @@ // CHECK: (%[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr) // CHECK: omp.atomic.read %[[ARG1]] = %[[ARG0]] memory_order(acquire) hint(contended) : !llvm.ptr func.func @atomic_read(%a: !llvm.ptr, %b: !llvm.ptr) -> () { - omp.atomic.read %b = %a memory_order(acquire) hint(contended) : !llvm.ptr + omp.atomic.read %b = %a memory_order(acquire) hint(contended) : !llvm.ptr, i32 return } diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir --- a/mlir/test/Dialect/OpenMP/invalid.mlir +++ b/mlir/test/Dialect/OpenMP/invalid.mlir @@ -457,7 +457,7 @@ for (%iv) : index = (%lb) to (%ub) step (%step) { %2 = arith.constant 2.0 : f32 // expected-error @below {{accumulator is not used by the parent}} - omp.reduction %2, %1 : !llvm.ptr + omp.reduction %2, %1 : f32, !llvm.ptr omp.yield } return @@ -474,7 +474,7 @@ omp.wsloop reduction(@foo -> %0 : !llvm.ptr) for (%iv) : index = (%lb) to (%ub) step (%step) { %2 = arith.constant 2.0 : f32 - omp.reduction %2, %1 : !llvm.ptr + omp.reduction %2, %1 : f32, !llvm.ptr omp.yield } return @@ -502,7 +502,7 @@ omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr, @add_f32 -> %0 : !llvm.ptr) for (%iv) : index = (%lb) to (%ub) step (%step) { %2 = arith.constant 2.0 : f32 - omp.reduction %2, %0 : !llvm.ptr + omp.reduction %2, %0 : f32, !llvm.ptr omp.yield } return @@ -535,7 +535,7 @@ omp.wsloop reduction(@add_f32 -> %mem : memref<1xf32>) for (%iv) : index = (%lb) to (%ub) step (%step) { %2 = arith.constant 2.0 : f32 - omp.reduction %2, %mem : memref<1xf32> + omp.reduction %2, %mem : f32, memref<1xf32> omp.yield } return @@ -630,7 +630,7 @@ func.func @omp_atomic_read1(%x: memref, %v: memref) { // expected-error @below {{the hints omp_sync_hint_nonspeculative and omp_sync_hint_speculative cannot be combined.}} - omp.atomic.read %v = %x hint(speculative, nonspeculative) : memref + omp.atomic.read %v = %x hint(speculative, nonspeculative) : memref, i32 return } @@ -638,7 +638,7 @@ func.func @omp_atomic_read2(%x: memref, %v: memref) { // expected-error @below {{invalid clause value: 'xyz'}} - omp.atomic.read %v = %x memory_order(xyz) : memref + omp.atomic.read %v = %x memory_order(xyz) : memref, i32 return } @@ -646,7 +646,7 @@ func.func @omp_atomic_read3(%x: memref, %v: memref) { // expected-error @below {{memory-order must not be acq_rel or release for atomic reads}} - omp.atomic.read %v = %x memory_order(acq_rel) : memref + omp.atomic.read %v = %x memory_order(acq_rel) : memref, i32 return } @@ -654,7 +654,7 @@ func.func @omp_atomic_read4(%x: memref, %v: memref) { // expected-error @below {{memory-order must not be acq_rel or release for atomic reads}} - omp.atomic.read %v = %x memory_order(release) : memref + omp.atomic.read %v = %x memory_order(release) : memref, i32 return } @@ -662,7 +662,7 @@ func.func @omp_atomic_read5(%x: memref, %v: memref) { // expected-error @below {{`memory_order` clause can appear at most once in the expansion of the oilist directive}} - omp.atomic.read %v = %x memory_order(acquire) memory_order(relaxed) : memref + omp.atomic.read %v = %x memory_order(acquire) memory_order(relaxed) : memref, i32 return } @@ -670,7 +670,7 @@ func.func @omp_atomic_read6(%x: memref, %v: memref) { // expected-error @below {{`hint` clause can appear at most once in the expansion of the oilist directive}} - omp.atomic.read %v = %x hint(speculative) hint(contended) : memref + omp.atomic.read %v = %x hint(speculative) hint(contended) : memref, i32 return } @@ -678,7 +678,7 @@ func.func @omp_atomic_read6(%x: memref, %v: memref) { // expected-error @below {{read and write must not be to the same location for atomic reads}} - omp.atomic.read %x = %x hint(speculative) : memref + omp.atomic.read %x = %x hint(speculative) : memref, i32 return } @@ -876,7 +876,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { // expected-error @below {{expected three operations in omp.atomic.capture region}} omp.atomic.capture { - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 omp.terminator } return @@ -887,8 +887,8 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { omp.atomic.capture { // expected-error @below {{invalid sequence of operations in the capture region}} - omp.atomic.read %v = %x : memref - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 + omp.atomic.read %v = %x : memref, i32 omp.terminator } return @@ -964,7 +964,7 @@ omp.atomic.capture { // expected-error @below {{invalid sequence of operations in the capture region}} omp.atomic.write %x = %expr : memref, i32 - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 omp.terminator } return @@ -980,7 +980,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) } - omp.atomic.read %v = %y : memref + omp.atomic.read %v = %y : memref, i32 omp.terminator } } @@ -990,7 +990,7 @@ func.func @omp_atomic_capture(%x: memref, %y: memref, %v: memref, %expr: i32) { omp.atomic.capture { // expected-error @below {{captured variable in omp.atomic.read must be updated in second operation}} - omp.atomic.read %v = %y : memref + omp.atomic.read %v = %y : memref, i32 omp.atomic.update %x : memref { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -1005,7 +1005,7 @@ func.func @omp_atomic_capture(%x: memref, %y: memref, %v: memref, %expr: i32) { omp.atomic.capture { // expected-error @below {{captured variable in omp.atomic.read must be updated in second operation}} - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 omp.atomic.write %y = %expr : memref, i32 omp.terminator } @@ -1021,7 +1021,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } return } @@ -1036,7 +1036,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } return } @@ -1051,7 +1051,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } return } @@ -1066,7 +1066,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } return } @@ -1081,7 +1081,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } return } @@ -1096,7 +1096,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x memory_order(seq_cst) : memref + omp.atomic.read %v = %x memory_order(seq_cst) : memref, i32 } return } diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir --- a/mlir/test/Dialect/OpenMP/ops.mlir +++ b/mlir/test/Dialect/OpenMP/ops.mlir @@ -569,7 +569,7 @@ for (%iv) : index = (%lb) to (%ub) step (%step) { %1 = arith.constant 2.0 : f32 // CHECK: omp.reduction %{{.+}}, %{{.+}} - omp.reduction %1, %0 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr omp.yield } return @@ -583,7 +583,7 @@ omp.parallel reduction(@add_f32 -> %0 : !llvm.ptr) { %1 = arith.constant 2.0 : f32 // CHECK: omp.reduction %{{.+}}, %{{.+}} - omp.reduction %1, %0 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr omp.terminator } return @@ -598,8 +598,8 @@ // CHECK: omp.wsloop for (%{{.+}}) : index = (%{{.+}}) to (%{{.+}}) step (%{{.+}}) omp.wsloop for (%iv) : index = (%lb) to (%ub) step (%step) { %1 = arith.constant 2.0 : f32 - // CHECK: omp.reduction %{{.+}}, %{{.+}} : !llvm.ptr - omp.reduction %1, %0 : !llvm.ptr + // CHECK: omp.reduction %{{.+}}, %{{.+}} : f32, !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr // CHECK: omp.yield omp.yield } @@ -619,14 +619,14 @@ omp.section { %1 = arith.constant 2.0 : f32 // CHECK: omp.reduction %{{.+}}, %{{.+}} - omp.reduction %1, %0 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr omp.terminator } // CHECK: omp.section omp.section { %1 = arith.constant 3.0 : f32 // CHECK: omp.reduction %{{.+}}, %{{.+}} - omp.reduction %1, %0 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr omp.terminator } omp.terminator @@ -659,7 +659,7 @@ for (%iv) : index = (%lb) to (%ub) step (%step) { %1 = arith.constant 2.0 : f32 // CHECK: omp.reduction - omp.reduction %1, %0 : memref<1xf32> + omp.reduction %1, %0 : f32, memref<1xf32> omp.yield } return @@ -672,7 +672,7 @@ omp.parallel reduction(@add2_f32 -> %0 : memref<1xf32>) { %1 = arith.constant 2.0 : f32 // CHECK: omp.reduction - omp.reduction %1, %0 : memref<1xf32> + omp.reduction %1, %0 : f32, memref<1xf32> omp.terminator } return @@ -687,8 +687,8 @@ // CHECK: omp.wsloop for (%{{.+}}) : index = (%{{.+}}) to (%{{.+}}) step (%{{.+}}) omp.wsloop for (%iv) : index = (%lb) to (%ub) step (%step) { %1 = arith.constant 2.0 : f32 - // CHECK: omp.reduction %{{.+}}, %{{.+}} : !llvm.ptr - omp.reduction %1, %0 : !llvm.ptr + // CHECK: omp.reduction %{{.+}}, %{{.+}} : f32, !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr // CHECK: omp.yield omp.yield } @@ -706,13 +706,13 @@ omp.section { %1 = arith.constant 2.0 : f32 // CHECK: omp.reduction - omp.reduction %1, %0 : memref<1xf32> + omp.reduction %1, %0 : f32, memref<1xf32> omp.terminator } omp.section { %1 = arith.constant 2.0 : f32 // CHECK: omp.reduction - omp.reduction %1, %0 : memref<1xf32> + omp.reduction %1, %0 : f32, memref<1xf32> omp.terminator } omp.terminator @@ -802,20 +802,20 @@ // CHECK-LABEL: omp_atomic_read // CHECK-SAME: (%[[v:.*]]: memref, %[[x:.*]]: memref) func.func @omp_atomic_read(%v: memref, %x: memref) { - // CHECK: omp.atomic.read %[[v]] = %[[x]] : memref - omp.atomic.read %v = %x : memref - // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) : memref - omp.atomic.read %v = %x memory_order(seq_cst) : memref - // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(acquire) : memref - omp.atomic.read %v = %x memory_order(acquire) : memref - // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(relaxed) : memref - omp.atomic.read %v = %x memory_order(relaxed) : memref - // CHECK: omp.atomic.read %[[v]] = %[[x]] hint(contended, nonspeculative) : memref - omp.atomic.read %v = %x hint(nonspeculative, contended) : memref - // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(contended, speculative) : memref - omp.atomic.read %v = %x hint(speculative, contended) memory_order(seq_cst) : memref - // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(none) : memref - omp.atomic.read %v = %x hint(none) memory_order(seq_cst) : memref + // CHECK: omp.atomic.read %[[v]] = %[[x]] : memref, i32 + omp.atomic.read %v = %x : memref, i32 + // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) : memref, i32 + omp.atomic.read %v = %x memory_order(seq_cst) : memref, i32 + // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(acquire) : memref, i32 + omp.atomic.read %v = %x memory_order(acquire) : memref, i32 + // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(relaxed) : memref, i32 + omp.atomic.read %v = %x memory_order(relaxed) : memref, i32 + // CHECK: omp.atomic.read %[[v]] = %[[x]] hint(contended, nonspeculative) : memref, i32 + omp.atomic.read %v = %x hint(nonspeculative, contended) : memref, i32 + // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(contended, speculative) : memref, i32 + omp.atomic.read %v = %x hint(speculative, contended) memory_order(seq_cst) : memref, i32 + // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(none) : memref, i32 + omp.atomic.read %v = %x hint(none) memory_order(seq_cst) : memref, i32 return } @@ -1051,7 +1051,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture{ omp.atomic.update %x : memref { @@ -1059,10 +1059,10 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture { - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: omp.atomic.update %[[x]] : memref // CHECK-NEXT: (%[[xval:.*]]: i32): // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 @@ -1070,7 +1070,7 @@ // CHECK-NEXT: } // CHECK-NEXT: } omp.atomic.capture{ - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 omp.atomic.update %x : memref { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -1078,11 +1078,11 @@ } } // CHECK: omp.atomic.capture { - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: omp.atomic.write %[[x]] = %[[expr]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture{ - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 omp.atomic.write %x = %expr : memref, i32 } @@ -1092,7 +1092,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(none) { omp.atomic.update %x : memref { @@ -1100,7 +1100,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(uncontended) { @@ -1109,7 +1109,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(uncontended) { omp.atomic.update %x : memref { @@ -1117,7 +1117,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(contended) { @@ -1126,7 +1126,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(contended) { omp.atomic.update %x : memref { @@ -1134,7 +1134,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(nonspeculative) { @@ -1143,7 +1143,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(nonspeculative) { omp.atomic.update %x : memref { @@ -1151,7 +1151,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(speculative) { @@ -1160,7 +1160,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(speculative) { omp.atomic.update %x : memref { @@ -1168,7 +1168,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(uncontended, nonspeculative) { @@ -1177,7 +1177,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(uncontended, nonspeculative) { omp.atomic.update %x : memref { @@ -1185,7 +1185,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(contended, nonspeculative) { @@ -1194,7 +1194,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(contended, nonspeculative) { omp.atomic.update %x : memref { @@ -1202,7 +1202,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(uncontended, speculative) { @@ -1211,7 +1211,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(uncontended, speculative) { omp.atomic.update %x : memref { @@ -1219,7 +1219,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture hint(contended, speculative) { @@ -1236,7 +1236,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture memory_order(seq_cst) { @@ -1253,7 +1253,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture memory_order(acq_rel) { @@ -1270,7 +1270,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture memory_order(acquire) { @@ -1279,7 +1279,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(acquire) { omp.atomic.update %x : memref { @@ -1287,7 +1287,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture memory_order(release) { @@ -1296,7 +1296,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(release) { omp.atomic.update %x : memref { @@ -1304,7 +1304,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture memory_order(relaxed) { @@ -1313,7 +1313,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(relaxed) { omp.atomic.update %x : memref { @@ -1321,7 +1321,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } // CHECK: omp.atomic.capture memory_order(seq_cst) hint(contended, speculative) { @@ -1330,7 +1330,7 @@ // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 // CHECK-NEXT: omp.yield(%[[newval]] : i32) // CHECK-NEXT: } - // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(contended, speculative) memory_order(seq_cst) { omp.atomic.update %x : memref { @@ -1338,7 +1338,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : memref + omp.atomic.read %v = %x : memref, i32 } return @@ -1860,3 +1860,46 @@ // CHECK: return return } + +// ----- + +// CHECK-LABEL: @opaque_pointers_atomic_rwu +// CHECK-SAME: (%[[v:.*]]: !llvm.ptr, %[[x:.*]]: !llvm.ptr) +func.func @opaque_pointers_atomic_rwu(%v: !llvm.ptr, %x: !llvm.ptr) { + // CHECK: omp.atomic.read %[[v]] = %[[x]] : !llvm.ptr, i32 + // CHECK: %[[VAL:.*]] = llvm.load %[[x]] : !llvm.ptr -> i32 + // CHECK: omp.atomic.write %[[v]] = %[[VAL]] : !llvm.ptr, i32 + // CHECK: omp.atomic.update %[[x]] : !llvm.ptr { + // CHECK-NEXT: ^{{[[:alnum:]]+}}(%[[XVAL:.*]]: i32): + // CHECK-NEXT: omp.yield(%[[XVAL]] : i32) + // CHECK-NEXT: } + omp.atomic.read %v = %x : !llvm.ptr, i32 + %val = llvm.load %x : !llvm.ptr -> i32 + omp.atomic.write %v = %val : !llvm.ptr, i32 + omp.atomic.update %x : !llvm.ptr { + ^bb0(%xval: i32): + omp.yield(%xval : i32) + } + return +} + +// CHECK-LABEL: @opaque_pointers_reduction +// CHECK: atomic { +// CHECK-NEXT: ^{{[[:alnum:]]+}}(%{{.*}}: !llvm.ptr, %{{.*}}: !llvm.ptr): +omp.reduction.declare @opaque_pointers_reduction : f32 +init { +^bb0(%arg: f32): + %0 = arith.constant 0.0 : f32 + omp.yield (%0 : f32) +} +combiner { +^bb1(%arg0: f32, %arg1: f32): + %1 = arith.addf %arg0, %arg1 : f32 + omp.yield (%1 : f32) +} +atomic { +^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): + %2 = llvm.load %arg3 : !llvm.ptr -> f32 + llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 + omp.yield +} diff --git a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir --- a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir +++ b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir @@ -37,7 +37,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %v: !llvm.ptr, %expr: i32) { // expected-error @+1 {{LLVM Translation failed for operation: omp.atomic.capture}} omp.atomic.capture memory_order(seq_cst) { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 // expected-error @+1 {{the update operation inside the region must be a binary operation and that update operation must have the region argument as an operand}} omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): @@ -55,7 +55,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %v: !llvm.ptr, %expr: i32) { // expected-error @+1 {{LLVM Translation failed for operation: omp.atomic.capture}} omp.atomic.capture memory_order(seq_cst) { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 // expected-error @+1 {{exactly two operations are allowed inside an atomic update region while lowering to LLVM IR}} omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir --- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir +++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir @@ -1245,21 +1245,21 @@ // CHECK: %[[X1:.*]] = load atomic i32, ptr %[[ARG0]] monotonic, align 4 // CHECK: store i32 %[[X1]], ptr %[[ARG1]], align 4 - omp.atomic.read %arg1 = %arg0 : !llvm.ptr + omp.atomic.read %arg1 = %arg0 : !llvm.ptr, i32 // CHECK: %[[X2:.*]] = load atomic i32, ptr %[[ARG0]] seq_cst, align 4 // CHECK: call void @__kmpc_flush(ptr @{{.*}}) // CHECK: store i32 %[[X2]], ptr %[[ARG1]], align 4 - omp.atomic.read %arg1 = %arg0 memory_order(seq_cst) : !llvm.ptr + omp.atomic.read %arg1 = %arg0 memory_order(seq_cst) : !llvm.ptr, i32 // CHECK: %[[X3:.*]] = load atomic i32, ptr %[[ARG0]] acquire, align 4 // CHECK: call void @__kmpc_flush(ptr @{{.*}}) // CHECK: store i32 %[[X3]], ptr %[[ARG1]], align 4 - omp.atomic.read %arg1 = %arg0 memory_order(acquire) : !llvm.ptr + omp.atomic.read %arg1 = %arg0 memory_order(acquire) : !llvm.ptr, i32 // CHECK: %[[X4:.*]] = load atomic i32, ptr %[[ARG0]] monotonic, align 4 // CHECK: store i32 %[[X4]], ptr %[[ARG1]], align 4 - omp.atomic.read %arg1 = %arg0 memory_order(relaxed) : !llvm.ptr + omp.atomic.read %arg1 = %arg0 memory_order(relaxed) : !llvm.ptr, i32 llvm.return } @@ -1385,7 +1385,7 @@ %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[res:.*]] = atomicrmw sub ptr %[[x]], i32 %[[expr]] monotonic @@ -1397,7 +1397,7 @@ %newval = llvm.sub %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[res:.*]] = atomicrmw and ptr %[[x]], i32 %[[expr]] monotonic @@ -1409,7 +1409,7 @@ %newval = llvm.and %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[res:.*]] = atomicrmw or ptr %[[x]], i32 %[[expr]] monotonic @@ -1421,7 +1421,7 @@ %newval = llvm.or %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[res:.*]] = atomicrmw xor ptr %[[x]], i32 %[[expr]] monotonic @@ -1433,7 +1433,7 @@ %newval = llvm.xor %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1448,7 +1448,7 @@ %newval = llvm.mul %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1463,7 +1463,7 @@ %newval = llvm.sdiv %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1478,7 +1478,7 @@ %newval = llvm.udiv %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1493,7 +1493,7 @@ %newval = llvm.shl %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1508,7 +1508,7 @@ %newval = llvm.lshr %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1523,7 +1523,7 @@ %newval = llvm.ashr %xval, %expr : i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1538,7 +1538,7 @@ %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1553,7 +1553,7 @@ %newval = "llvm.intr.smin"(%xval, %expr) : (i32, i32) -> i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1568,7 +1568,7 @@ %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1583,7 +1583,7 @@ %newval = "llvm.intr.umin"(%xval, %expr) : (i32, i32) -> i32 omp.yield(%newval : i32) } - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1598,7 +1598,7 @@ %newval = llvm.fadd %xval, %exprf : f32 omp.yield(%newval : f32) } - omp.atomic.read %vf = %xf : !llvm.ptr + omp.atomic.read %vf = %xf : !llvm.ptr, f32 } // CHECK: %[[xval:.*]] = phi i32 @@ -1613,7 +1613,7 @@ %newval = llvm.fsub %xval, %exprf : f32 omp.yield(%newval : f32) } - omp.atomic.read %vf = %xf : !llvm.ptr + omp.atomic.read %vf = %xf : !llvm.ptr, f32 } llvm.return @@ -1629,7 +1629,7 @@ // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] monotonic // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -1640,7 +1640,7 @@ // CHECK: %[[res:.*]] = atomicrmw sub ptr %[[x]], i32 %[[expr]] monotonic // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.sub %xval, %expr : i32 @@ -1651,7 +1651,7 @@ // CHECK: %[[res:.*]] = atomicrmw and ptr %[[x]], i32 %[[expr]] monotonic // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.and %xval, %expr : i32 @@ -1662,7 +1662,7 @@ // CHECK: %[[res:.*]] = atomicrmw or ptr %[[x]], i32 %[[expr]] monotonic // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.or %xval, %expr : i32 @@ -1673,7 +1673,7 @@ // CHECK: %[[res:.*]] = atomicrmw xor ptr %[[x]], i32 %[[expr]] monotonic // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.xor %xval, %expr : i32 @@ -1688,7 +1688,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.mul %xval, %expr : i32 @@ -1703,7 +1703,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.sdiv %xval, %expr : i32 @@ -1718,7 +1718,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.udiv %xval, %expr : i32 @@ -1733,7 +1733,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.shl %xval, %expr : i32 @@ -1748,7 +1748,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.lshr %xval, %expr : i32 @@ -1763,7 +1763,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.ashr %xval, %expr : i32 @@ -1778,7 +1778,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32 @@ -1793,7 +1793,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = "llvm.intr.smin"(%xval, %expr) : (i32, i32) -> i32 @@ -1808,7 +1808,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32 @@ -1823,7 +1823,7 @@ // CHECK-NEXT: %{{.*}} = cmpxchg ptr %[[x]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = "llvm.intr.umin"(%xval, %expr) : (i32, i32) -> i32 @@ -1839,7 +1839,7 @@ // CHECK: %{{.*}} = cmpxchg ptr %[[xf]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store float %[[xvalf]], ptr %[[vf]] omp.atomic.capture { - omp.atomic.read %vf = %xf : !llvm.ptr + omp.atomic.read %vf = %xf : !llvm.ptr, f32 omp.atomic.update %xf : !llvm.ptr { ^bb0(%xval: f32): %newval = llvm.fadd %xval, %exprf : f32 @@ -1855,7 +1855,7 @@ // CHECK: %{{.*}} = cmpxchg ptr %[[xf]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store float %[[xvalf]], ptr %[[vf]] omp.atomic.capture { - omp.atomic.read %vf = %xf : !llvm.ptr + omp.atomic.read %vf = %xf : !llvm.ptr, f32 omp.atomic.update %xf : !llvm.ptr { ^bb0(%xval: f32): %newval = llvm.fsub %xval, %exprf : f32 @@ -1875,7 +1875,7 @@ // CHECK: %[[xval:.*]] = atomicrmw xchg ptr %[[x]], i32 %[[expr]] monotonic // CHECK: store i32 %[[xval]], ptr %[[v]] omp.atomic.capture{ - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.write %x = %expr : !llvm.ptr, i32 } @@ -1886,14 +1886,14 @@ // CHECK: %{{.*}} = cmpxchg ptr %[[xf]], i32 %[[xval]], i32 %[[newval_]] monotonic monotonic // CHECK: store float %[[xvalf]], ptr %[[vf]] omp.atomic.capture{ - omp.atomic.read %vf = %xf : !llvm.ptr + omp.atomic.read %vf = %xf : !llvm.ptr, f32 omp.atomic.write %xf = %exprf : !llvm.ptr, f32 } // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] seq_cst // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture memory_order(seq_cst) { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -1904,7 +1904,7 @@ // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] acquire // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture memory_order(acquire) { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -1915,7 +1915,7 @@ // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] release // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture memory_order(release) { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -1926,7 +1926,7 @@ // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] monotonic // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture memory_order(relaxed) { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -1937,7 +1937,7 @@ // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] acq_rel // CHECK: store i32 %[[res]], ptr %[[v]] omp.atomic.capture memory_order(acq_rel) { - omp.atomic.read %v = %x : !llvm.ptr + omp.atomic.read %v = %x : !llvm.ptr, i32 omp.atomic.update %x : !llvm.ptr { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 @@ -2383,3 +2383,25 @@ // CHECK: call void @__kmpc_end_taskgroup(ptr @{{.+}}, i32 %[[omp_global_thread_num]]) // CHECK: ret void // CHECK: } + +// ----- + +// CHECK-LABEL: @omp_opaque_pointers +// CHECK-SAME: (ptr %[[ARG0:.*]], ptr %[[ARG1:.*]], i32 %[[EXPR:.*]]) +llvm.func @omp_opaque_pointers(%arg0 : !llvm.ptr, %arg1: !llvm.ptr, %expr: i32) -> () { + // CHECK: %[[X1:.*]] = load atomic i32, ptr %[[ARG0]] monotonic, align 4 + // CHECK: store i32 %[[X1]], ptr %[[ARG1]], align 4 + omp.atomic.read %arg1 = %arg0 : !llvm.ptr, i32 + + // CHECK: %[[RES:.*]] = atomicrmw add ptr %[[ARG1]], i32 %[[EXPR]] acq_rel + // CHECK: store i32 %[[RES]], ptr %[[ARG0]] + omp.atomic.capture memory_order(acq_rel) { + omp.atomic.read %arg0 = %arg1 : !llvm.ptr, i32 + omp.atomic.update %arg1 : !llvm.ptr { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + } + llvm.return +} diff --git a/mlir/test/Target/LLVMIR/openmp-reduction-typed-pointers.mlir b/mlir/test/Target/LLVMIR/openmp-reduction-typed-pointers.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Target/LLVMIR/openmp-reduction-typed-pointers.mlir @@ -0,0 +1,75 @@ +// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s + +// Only check the overall shape of the code and the presence of relevant +// runtime calls. Actual IR checking is done at the OpenMPIRBuilder level. + +omp.reduction.declare @add_f32 : f32 +init { +^bb0(%arg: f32): + %0 = llvm.mlir.constant(0.0 : f32) : f32 + omp.yield (%0 : f32) +} +combiner { +^bb1(%arg0: f32, %arg1: f32): + %1 = llvm.fadd %arg0, %arg1 : f32 + omp.yield (%1 : f32) +} +atomic { +^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): + %2 = llvm.load %arg3 : !llvm.ptr + llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 + omp.yield +} + +// CHECK-LABEL: @simple_reduction +llvm.func @simple_reduction(%lb : i64, %ub : i64, %step : i64) { + %c1 = llvm.mlir.constant(1 : i32) : i32 + %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + omp.parallel { + omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr) + for (%iv) : i64 = (%lb) to (%ub) step (%step) { + %1 = llvm.mlir.constant(2.0 : f32) : f32 + omp.reduction %1, %0 : f32, !llvm.ptr + omp.yield + } + omp.terminator + } + llvm.return +} + +// Call to the outlined function. +// CHECK: call void {{.*}} @__kmpc_fork_call +// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]] + +// Outlined function. +// CHECK: define internal void @[[OUTLINED]] + +// Private reduction variable and its initialization. +// CHECK: %[[PRIVATE:.+]] = alloca float +// CHECK: store float 0.000000e+00, ptr %[[PRIVATE]] + +// Call to the reduction function. +// CHECK: call i32 @__kmpc_reduce +// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]] + +// Atomic reduction. +// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]] +// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]] + +// Non-atomic reduction: +// CHECK: fadd float +// CHECK: call void @__kmpc_end_reduce +// CHECK: br label %[[FINALIZE:.+]] + +// CHECK: [[FINALIZE]]: +// CHECK: call void @__kmpc_barrier + +// Update of the private variable using the reduction region +// (the body block currently comes after all the other blocks). +// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]] +// CHECK: %[[UPDATED:.+]] = fadd float %[[PARTIAL]], 2.000000e+00 +// CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]] + +// Reduction function. +// CHECK: define internal void @[[REDFUNC]] +// CHECK: fadd float diff --git a/mlir/test/Target/LLVMIR/openmp-reduction.mlir b/mlir/test/Target/LLVMIR/openmp-reduction.mlir --- a/mlir/test/Target/LLVMIR/openmp-reduction.mlir +++ b/mlir/test/Target/LLVMIR/openmp-reduction.mlir @@ -15,21 +15,21 @@ omp.yield (%1 : f32) } atomic { -^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): - %2 = llvm.load %arg3 : !llvm.ptr - llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 +^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): + %2 = llvm.load %arg3 : !llvm.ptr -> f32 + llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 omp.yield } // CHECK-LABEL: @simple_reduction llvm.func @simple_reduction(%lb : i64, %ub : i64, %step : i64) { %c1 = llvm.mlir.constant(1 : i32) : i32 - %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr omp.parallel { - omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr) + omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr) for (%iv) : i64 = (%lb) to (%ub) step (%step) { %1 = llvm.mlir.constant(2.0 : f32) : f32 - omp.reduction %1, %0 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr omp.yield } omp.terminator @@ -88,9 +88,9 @@ omp.yield (%1 : f32) } atomic { -^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): - %2 = llvm.load %arg3 : !llvm.ptr - llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 +^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): + %2 = llvm.load %arg3 : !llvm.ptr -> f32 + llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 omp.yield } @@ -100,14 +100,14 @@ // CHECK-LABEL: @reuse_declaration llvm.func @reuse_declaration(%lb : i64, %ub : i64, %step : i64) { %c1 = llvm.mlir.constant(1 : i32) : i32 - %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr - %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr omp.parallel { - omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr, @add_f32 -> %2 : !llvm.ptr) + omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr, @add_f32 -> %2 : !llvm.ptr) for (%iv) : i64 = (%lb) to (%ub) step (%step) { %1 = llvm.mlir.constant(2.0 : f32) : f32 - omp.reduction %1, %0 : !llvm.ptr - omp.reduction %1, %2 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr + omp.reduction %1, %2 : f32, !llvm.ptr omp.yield } omp.terminator @@ -176,9 +176,9 @@ omp.yield (%1 : f32) } atomic { -^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): - %2 = llvm.load %arg3 : !llvm.ptr - llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 +^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): + %2 = llvm.load %arg3 : !llvm.ptr -> f32 + llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 omp.yield } @@ -186,13 +186,13 @@ // CHECK-LABEL: @missing_omp_reduction llvm.func @missing_omp_reduction(%lb : i64, %ub : i64, %step : i64) { %c1 = llvm.mlir.constant(1 : i32) : i32 - %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr - %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr omp.parallel { - omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr, @add_f32 -> %2 : !llvm.ptr) + omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr, @add_f32 -> %2 : !llvm.ptr) for (%iv) : i64 = (%lb) to (%ub) step (%step) { %1 = llvm.mlir.constant(2.0 : f32) : f32 - omp.reduction %1, %0 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr omp.yield } omp.terminator @@ -259,9 +259,9 @@ omp.yield (%1 : f32) } atomic { -^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): - %2 = llvm.load %arg3 : !llvm.ptr - llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 +^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): + %2 = llvm.load %arg3 : !llvm.ptr -> f32 + llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 omp.yield } @@ -270,13 +270,13 @@ // CHECK-LABEL: @double_reference llvm.func @double_reference(%lb : i64, %ub : i64, %step : i64) { %c1 = llvm.mlir.constant(1 : i32) : i32 - %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr omp.parallel { - omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr) + omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr) for (%iv) : i64 = (%lb) to (%ub) step (%step) { %1 = llvm.mlir.constant(2.0 : f32) : f32 - omp.reduction %1, %0 : !llvm.ptr - omp.reduction %1, %0 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr omp.yield } omp.terminator @@ -338,9 +338,9 @@ omp.yield (%1 : f32) } atomic { -^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): - %2 = llvm.load %arg3 : !llvm.ptr - llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 +^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr): + %2 = llvm.load %arg3 : !llvm.ptr -> f32 + llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32 omp.yield } @@ -359,14 +359,14 @@ // CHECK-LABEL: @no_atomic llvm.func @no_atomic(%lb : i64, %ub : i64, %step : i64) { %c1 = llvm.mlir.constant(1 : i32) : i32 - %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr - %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr omp.parallel { - omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr, @mul_f32 -> %2 : !llvm.ptr) + omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr, @mul_f32 -> %2 : !llvm.ptr) for (%iv) : i64 = (%lb) to (%ub) step (%step) { %1 = llvm.mlir.constant(2.0 : f32) : f32 - omp.reduction %1, %0 : !llvm.ptr - omp.reduction %1, %2 : !llvm.ptr + omp.reduction %1, %0 : f32, !llvm.ptr + omp.reduction %1, %2 : f32, !llvm.ptr omp.yield } omp.terminator