-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][OpenMP] Support reduction of variables in EQUIVALENCE #130607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
These previously crashed the compiler because !fir.ptr (not wrapped inside of a box) was not supported. Real POINTER variables are supported as !fir.box<!fir.ptr<>>. The version for EQUIVALENCE doesn't need to do anything different to !fir.ref<>.
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-openmp Author: Tom Eccles (tblah) ChangesThese previously crashed the compiler because !fir.ptr (not wrapped inside of a box) was not supported. Real POINTER variables are supported as !fir.box<!fir.ptr<>>. The version for EQUIVALENCE doesn't need to do anything different to !fir.ref<>. Full diff: https://github.com/llvm/llvm-project/pull/130607.diff 2 Files Affected:
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<fir::ReferenceType>(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<!fir.array<4xi8>>, index) -> !fir.ref<i8>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<i8>) -> !fir.ptr<i32>
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFreduction_equivalenceEva"} : (!fir.ptr<i32>) -> (!fir.ptr<i32>, !fir.ptr<i32>)
+! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_6:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_5]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
+! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<i8>) -> !fir.ptr<f32>
+! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFreduction_equivalenceEvva"} : (!fir.ptr<f32>) -> (!fir.ptr<f32>, !fir.ptr<f32>)
+! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32
+! CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_4]]#0 : i32, !fir.ptr<i32>
+! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ptr<i32>) -> !fir.ref<i32>
+! CHECK: omp.parallel reduction(@add_reduction_i32 %[[VAL_10]] -> %[[VAL_11:.*]] : !fir.ref<i32>) {
+! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QFreduction_equivalenceEva"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32
+! CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_12]]#0 : i32, !fir.ref<i32>
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG.
These previously crashed the compiler because !fir.ptr (not wrapped inside of a box) was not supported.
Real POINTER variables are supported as !fir.box<!fir.ptr<>>. The version for EQUIVALENCE doesn't need to do anything different to !fir.ref<>.