diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp index f83079eb68688..aa1187669ca8b 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp @@ -617,10 +617,13 @@ void ReductionProcessor::processReductionArguments( // this isn't the same as the by-val and by-ref passing later in the // pipeline. Both styles assume that the variable is a reference at // this point - assert(mlir::isa(symVal.getType()) && - "reduction input var is a reference"); + assert(fir::isa_ref_type(symVal.getType()) && + "reduction input var is passed by reference"); + mlir::Type elementType = fir::dyn_cast_ptrEleTy(symVal.getType()); + mlir::Type refTy = fir::ReferenceType::get(elementType); - reductionVars.push_back(symVal); + reductionVars.push_back( + builder.createConvert(currentLocation, refTy, symVal)); reduceVarByRef.push_back(doReductionByRef(symVal)); } diff --git a/flang/test/Lower/OpenMP/reduction-equivalence.f90 b/flang/test/Lower/OpenMP/reduction-equivalence.f90 new file mode 100644 index 0000000000000..f46e148ac61cd --- /dev/null +++ b/flang/test/Lower/OpenMP/reduction-equivalence.f90 @@ -0,0 +1,48 @@ +! RUN: bbc -emit-hlfir -fopenmp -o - %s | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s | FileCheck %s + +! Test that we can reduce variables used in an equivalence statement. +! Unlike POINTER variables these are lowered to an unboxed !fir.ptr<>. + +subroutine reduction_equivalence() + integer::va + equivalence (va,vva) + va=1 + +!$omp parallel reduction(+:va) + va=1 +!$omp end parallel +end subroutine reduction_equivalence + + +! CHECK-LABEL: omp.declare_reduction @add_reduction_i32 : i32 init { +! CHECK: ^bb0(%[[VAL_0:.*]]: i32): +! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 +! CHECK: omp.yield(%[[VAL_1]] : i32) +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32): +! CHECK: %[[VAL_2:.*]] = arith.addi %[[VAL_0]], %[[VAL_1]] : i32 +! CHECK: omp.yield(%[[VAL_2]] : i32) +! CHECK: } + +! CHECK-LABEL: func.func @_QPreduction_equivalence() { +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<4xi8> {uniq_name = "_QFreduction_equivalenceEva"} +! CHECK: %[[VAL_1:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref) -> !fir.ptr +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFreduction_equivalenceEva"} : (!fir.ptr) -> (!fir.ptr, !fir.ptr) +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_6:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_5]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref) -> !fir.ptr +! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFreduction_equivalenceEvva"} : (!fir.ptr) -> (!fir.ptr, !fir.ptr) +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 +! CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_4]]#0 : i32, !fir.ptr +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ptr) -> !fir.ref +! CHECK: omp.parallel reduction(@add_reduction_i32 %[[VAL_10]] -> %[[VAL_11:.*]] : !fir.ref) { +! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QFreduction_equivalenceEva"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 +! CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_12]]#0 : i32, !fir.ref +! CHECK: omp.terminator +! CHECK: } +! CHECK: return +! CHECK: }