[flang-commits] [flang] e1fed24 - [flang][OpenMP] Fix fir.convert in omp.atomic.update region (#138397)
via flang-commits
flang-commits at lists.llvm.org
Tue May 6 22:44:51 PDT 2025
Author: NimishMishra
Date: 2025-05-06T22:44:48-07:00
New Revision: e1fed24034fee3f45bc17252ced5ee29ab6b5408
URL: https://github.com/llvm/llvm-project/commit/e1fed24034fee3f45bc17252ced5ee29ab6b5408
DIFF: https://github.com/llvm/llvm-project/commit/e1fed24034fee3f45bc17252ced5ee29ab6b5408.diff
LOG: [flang][OpenMP] Fix fir.convert in omp.atomic.update region (#138397)
Region generation in omp.atomic.update currently emits a direct
`fir.convert`. This crashes when the RHS expression involves complex
type but the LHS variable is primitive type (say `f32`), since a
`fir.convert` from `complex<f32>` to `f32` is emitted, which is illegal.
This PR adds a conditional check to emit an additional `ExtractValueOp`
in case RHS expression has a complex type.
Fixes https://github.com/llvm/llvm-project/issues/138396
Added:
Modified:
flang/lib/Lower/OpenMP/OpenMP.cpp
flang/test/Lower/OpenMP/atomic-update.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index ca53130e5d363..49247e2e5cce4 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2858,9 +2858,23 @@ static void genAtomicUpdateStatement(
lower::StatementContext atomicStmtCtx;
mlir::Value rhsExpr = fir::getBase(converter.genExprValue(
*semantics::GetExpr(assignmentStmtExpr), atomicStmtCtx));
- mlir::Value convertResult =
- firOpBuilder.createConvert(currentLocation, varType, rhsExpr);
- firOpBuilder.create<mlir::omp::YieldOp>(currentLocation, convertResult);
+ mlir::Type exprType = fir::unwrapRefType(rhsExpr.getType());
+ if (fir::isa_complex(exprType) && !fir::isa_complex(varType)) {
+ // Emit an additional `ExtractValueOp` if the expression is of complex
+ // type
+ auto extract = firOpBuilder.create<fir::ExtractValueOp>(
+ currentLocation,
+ mlir::cast<mlir::ComplexType>(exprType).getElementType(), rhsExpr,
+ firOpBuilder.getArrayAttr(
+ firOpBuilder.getIntegerAttr(firOpBuilder.getIndexType(), 0)));
+ mlir::Value convertResult = firOpBuilder.create<fir::ConvertOp>(
+ currentLocation, varType, extract);
+ firOpBuilder.create<mlir::omp::YieldOp>(currentLocation, convertResult);
+ } else {
+ mlir::Value convertResult =
+ firOpBuilder.createConvert(currentLocation, varType, rhsExpr);
+ firOpBuilder.create<mlir::omp::YieldOp>(currentLocation, convertResult);
+ }
converter.resetExprOverrides();
}
firOpBuilder.setInsertionPointAfter(atomicUpdateOp);
diff --git a/flang/test/Lower/OpenMP/atomic-update.f90 b/flang/test/Lower/OpenMP/atomic-update.f90
index 31bf447006930..257ae8fb497ff 100644
--- a/flang/test/Lower/OpenMP/atomic-update.f90
+++ b/flang/test/Lower/OpenMP/atomic-update.f90
@@ -20,6 +20,8 @@ program OmpAtomicUpdate
!CHECK: %[[VAL_C_DECLARE:.*]]:2 = hlfir.declare %[[VAL_C_ADDRESS]] {{.*}}
!CHECK: %[[VAL_D_ADDRESS:.*]] = fir.address_of(@_QFEd) : !fir.ref<i32>
!CHECK: %[[VAL_D_DECLARE:.*]]:2 = hlfir.declare %[[VAL_D_ADDRESS]] {{.}}
+!CHECK: %[[VAL_G_ADDRESS:.*]] = fir.alloca complex<f32> {bindc_name = "g", uniq_name = "_QFEg"}
+!CHECK: %[[VAL_G_DECLARE:.*]]:2 = hlfir.declare %[[VAL_G_ADDRESS]] {uniq_name = "_QFEg"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
!CHECK: %[[VAL_i1_ALLOCA:.*]] = fir.alloca i8 {bindc_name = "i1", uniq_name = "_QFEi1"}
!CHECK: %[[VAL_i1_DECLARE:.*]]:2 = hlfir.declare %[[VAL_i1_ALLOCA]] {{.*}}
!CHECK: %[[VAL_c5:.*]] = arith.constant 5 : index
@@ -40,6 +42,7 @@ program OmpAtomicUpdate
integer, target :: c, d
integer(1) :: i1
integer, dimension(5) :: k
+ complex :: g
!CHECK: %[[EMBOX:.*]] = fir.embox %[[VAL_C_DECLARE]]#0 : (!fir.ref<i32>) -> !fir.box<!fir.ptr<i32>>
!CHECK: fir.store %[[EMBOX]] to %[[VAL_A_DECLARE]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
@@ -200,4 +203,19 @@ program OmpAtomicUpdate
!CHECK: }
!$omp atomic update
x = x + sum([ (y+2, y=1, z) ])
+
+!CHECK: %[[LOAD:.*]] = fir.load %[[VAL_G_DECLARE]]#0 : !fir.ref<complex<f32>>
+!CHECK: omp.atomic.update %[[VAL_W_DECLARE]]#0 : !fir.ref<i32> {
+!CHECK: ^bb0(%[[ARG:.*]]: i32):
+!CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (i32) -> f32
+!CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f32
+!CHECK: %[[UNDEF:.*]] = fir.undefined complex<f32>
+!CHECK: %[[IDX1:.*]] = fir.insert_value %[[UNDEF]], %[[CVT]], [0 : index] : (complex<f32>, f32) -> complex<f32>
+!CHECK: %[[IDX2:.*]] = fir.insert_value %[[IDX1]], %[[CST]], [1 : index] : (complex<f32>, f32) -> complex<f32>
+!CHECK: %[[ADD:.*]] = fir.addc %[[IDX2]], %[[LOAD]] {fastmath = #arith.fastmath<contract>} : complex<f32>
+!CHECK: %[[EXT:.*]] = fir.extract_value %[[ADD]], [0 : index] : (complex<f32>) -> f32
+!CHECK: %[[RESULT:.*]] = fir.convert %[[EXT]] : (f32) -> i32
+!CHECK: omp.yield(%[[RESULT]] : i32)
+ !$omp atomic update
+ w = w + g
end program OmpAtomicUpdate
More information about the flang-commits
mailing list