[flang-commits] [flang] [llvm] [flang][llvm][OpenMP][OpenACC] Add implicit casts to omp.atomic and acc.atomic (PR #131603)

via flang-commits flang-commits at lists.llvm.org
Tue Apr 15 07:36:12 PDT 2025


https://github.com/NimishMishra updated https://github.com/llvm/llvm-project/pull/131603

>From 30ba72b1dedd93f3a5316d14dd2465f4d723939e Mon Sep 17 00:00:00 2001
From: Nimish Mishra <neelam.nimish at gmail.com>
Date: Tue, 15 Apr 2025 20:04:46 +0530
Subject: [PATCH] [flang][llvm][OpenMP][OpenACC] Add implicit casts to
 omp.atomic and acc.atomic

---
 flang/include/flang/Lower/DirectivesCommon.h  |  28 ++---
 .../acc-atomic-capture-implicit-cast-todo.f90 |  48 ++++++++
 .../test/Lower/OpenACC/acc-atomic-capture.f90 | 115 ------------------
 flang/test/Lower/OpenACC/acc-atomic-read.f90  |   6 +-
 .../Todo/atomic-capture-implicit-cast.f90     |  48 ++++++++
 .../Lower/OpenMP/atomic-implicit-cast.f90     |  57 +++++++++
 llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp     |  31 -----
 7 files changed, 169 insertions(+), 164 deletions(-)
 create mode 100644 flang/test/Lower/OpenACC/acc-atomic-capture-implicit-cast-todo.f90
 create mode 100644 flang/test/Lower/OpenMP/Todo/atomic-capture-implicit-cast.f90
 create mode 100644 flang/test/Lower/OpenMP/atomic-implicit-cast.f90

diff --git a/flang/include/flang/Lower/DirectivesCommon.h b/flang/include/flang/Lower/DirectivesCommon.h
index 6e24343cebd3a..41502b2123a4c 100644
--- a/flang/include/flang/Lower/DirectivesCommon.h
+++ b/flang/include/flang/Lower/DirectivesCommon.h
@@ -368,24 +368,15 @@ void genOmpAccAtomicRead(Fortran::lower::AbstractConverter &converter,
     rightHandClauseList = &std::get<2>(atomicRead.t);
     leftHandClauseList = &std::get<0>(atomicRead.t);
   }
-
-  const auto &assignmentStmtExpr = std::get<Fortran::parser::Expr>(
-      std::get<Fortran::parser::Statement<Fortran::parser::AssignmentStmt>>(
-          atomicRead.t)
-          .statement.t);
-  const auto &assignmentStmtVariable = std::get<Fortran::parser::Variable>(
-      std::get<Fortran::parser::Statement<Fortran::parser::AssignmentStmt>>(
-          atomicRead.t)
-          .statement.t);
-
+ 
+  const Fortran::parser::AssignmentStmt &stmt =
+	  std::get<Fortran::parser::Statement<Fortran::parser::AssignmentStmt>>(
+			  atomicRead.t).statement;
+  const Fortran::evaluate::Assignment &assign = *stmt.typedAssignment->v;
   Fortran::lower::StatementContext stmtCtx;
-  const Fortran::semantics::SomeExpr &fromExpr =
-      *Fortran::semantics::GetExpr(assignmentStmtExpr);
-  mlir::Type elementType = converter.genType(fromExpr);
-  mlir::Value fromAddress =
-      fir::getBase(converter.genExprAddr(fromExpr, stmtCtx));
-  mlir::Value toAddress = fir::getBase(converter.genExprAddr(
-      *Fortran::semantics::GetExpr(assignmentStmtVariable), stmtCtx));
+  mlir::Value fromAddress = fir::getBase(converter.genExprAddr(assign.rhs, stmtCtx));
+  mlir::Value toAddress = fir::getBase(converter.genExprAddr(assign.lhs, stmtCtx));
+  mlir::Type elementType = fir::unwrapRefType(fromAddress.getType());
   genOmpAccAtomicCaptureStatement(converter, fromAddress, toAddress,
                                   leftHandClauseList, rightHandClauseList,
                                   elementType, loc);
@@ -481,6 +472,9 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
   mlir::Type stmt2VarType =
       fir::getBase(converter.genExprValue(assign2.lhs, stmtCtx)).getType();
 
+  // Check if implicit type is needed
+  if(stmt1VarType != stmt2VarType)
+	  TODO(loc, "atomic capture requiring implicit type casts");
   mlir::Operation *atomicCaptureOp = nullptr;
   if constexpr (std::is_same<AtomicListT,
                              Fortran::parser::OmpAtomicClauseList>()) {
diff --git a/flang/test/Lower/OpenACC/acc-atomic-capture-implicit-cast-todo.f90 b/flang/test/Lower/OpenACC/acc-atomic-capture-implicit-cast-todo.f90
new file mode 100644
index 0000000000000..14e1c21a2aae7
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-atomic-capture-implicit-cast-todo.f90
@@ -0,0 +1,48 @@
+!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenacc -o - %s 2>&1 | FileCheck %s
+
+!CHECK: not yet implemented: atomic capture requiring implicit type casts 
+subroutine capture_with_convert_f32_to_i32()
+    implicit none
+    integer :: k, v, i
+
+    k = 1
+    v = 0
+
+    !$acc atomic capture
+    v = k
+    k = (i + 1) * 3.14
+    !$acc end atomic
+end subroutine
+
+subroutine capture_with_convert_i32_to_f64()
+    real(8) :: x
+    integer :: v
+    x = 1.0
+    v = 0
+    !$acc atomic capture
+    v = x
+    x = v
+    !$acc end atomic
+end subroutine capture_with_convert_i32_to_f64
+
+subroutine capture_with_convert_f64_to_i32()
+    integer :: x
+    real(8) :: v
+    x = 1
+    v = 0
+    !$acc atomic capture
+    x = v * v
+    v = x
+    !$acc end atomic
+end subroutine capture_with_convert_f64_to_i32
+
+subroutine capture_with_convert_i32_to_f32()
+    real(4) :: x
+    integer :: v
+    x = 1.0
+    v = 0
+    !$acc atomic capture
+    v = x
+    x = x + v
+    !$acc end atomic
+end subroutine capture_with_convert_i32_to_f32
diff --git a/flang/test/Lower/OpenACC/acc-atomic-capture.f90 b/flang/test/Lower/OpenACC/acc-atomic-capture.f90
index 6cf39cde6ca0d..4aeef0be95565 100644
--- a/flang/test/Lower/OpenACC/acc-atomic-capture.f90
+++ b/flang/test/Lower/OpenACC/acc-atomic-capture.f90
@@ -96,121 +96,6 @@ subroutine pointers_in_atomic_capture()
 end subroutine
 
 
-subroutine capture_with_convert_f32_to_i32()
-  implicit none
-  integer :: k, v, i
-
-  k = 1
-  v = 0
-
-  !$acc atomic capture
-  v = k
-  k = (i + 1) * 3.14
-  !$acc end atomic
-end subroutine
-
-! CHECK-LABEL: func.func @_QPcapture_with_convert_f32_to_i32()
-! CHECK: %[[K:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFcapture_with_convert_f32_to_i32Ek"}
-! CHECK: %[[K_DECL:.*]]:2 = hlfir.declare %[[K]] {uniq_name = "_QFcapture_with_convert_f32_to_i32Ek"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_f32_to_i32Ev"}
-! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_f32_to_i32Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[CST:.*]] = arith.constant 3.140000e+00 : f32
-! CHECK: %[[MUL:.*]] = arith.mulf %{{.*}}, %[[CST]] fastmath<contract> : f32
-! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f32) -> i32
-! CHECK: acc.atomic.capture {
-! CHECK:   acc.atomic.read %[[V_DECL]]#0 = %[[K_DECL]]#0 : !fir.ref<i32>, !fir.ref<i32>, i32
-! CHECK:   acc.atomic.write %[[K_DECL]]#0 = %[[CONV]] : !fir.ref<i32>, i32
-! CHECK: }
-
-subroutine capture_with_convert_i32_to_f64()
-  real(8) :: x
-  integer :: v
-  x = 1.0
-  v = 0
-  !$acc atomic capture
-  v = x
-  x = v
-  !$acc end atomic
-end subroutine capture_with_convert_i32_to_f64
-
-! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f64()
-! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"}
-! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[X:.*]] = fir.alloca f64 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"}
-! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
-! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f64
-! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f64, !fir.ref<f64>
-! CHECK: %c0_i32 = arith.constant 0 : i32
-! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
-! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
-! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
-! CHECK: acc.atomic.capture {
-! CHECK:   acc.atomic.read %[[V_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<i32>, !fir.ref<f64>, f64
-! CHECK:   acc.atomic.write %[[X_DECL]]#0 = %[[CONV]] : !fir.ref<f64>, f64
-! CHECK: }
-
-subroutine capture_with_convert_f64_to_i32()
-  integer :: x
-  real(8) :: v
-  x = 1
-  v = 0
-  !$acc atomic capture
-  x = v * v
-  v = x
-  !$acc end atomic
-end subroutine capture_with_convert_f64_to_i32
-
-! CHECK-LABEL: func.func @_QPcapture_with_convert_f64_to_i32()
-! CHECK: %[[V:.*]] = fir.alloca f64 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"}
-! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
-! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"}
-! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %c1_i32 = arith.constant 1 : i32
-! CHECK: hlfir.assign %c1_i32 to %[[X_DECL]]#0 : i32, !fir.ref<i32>
-! CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f64
-! CHECK: hlfir.assign %[[CST]] to %[[V_DECL]]#0 : f64, !fir.ref<f64>
-! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<f64>
-! CHECK: acc.atomic.capture {
-! CHECK:   acc.atomic.update %[[X_DECL]]#0 : !fir.ref<i32> {
-! CHECK:   ^bb0(%arg0: i32):
-! CHECK:     %[[MUL:.*]] = arith.mulf %[[LOAD]], %[[LOAD]] fastmath<contract> : f64
-! CHECK:     %[[CONV:.*]] = fir.convert %[[MUL]] : (f64) -> i32
-! CHECK:     acc.yield %[[CONV]] : i32
-! CHECK:   }
-! CHECK:   acc.atomic.read %[[V_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<f64>, !fir.ref<i32>, i32
-! CHECK: }
-
-subroutine capture_with_convert_i32_to_f32()
-  real(4) :: x
-  integer :: v
-  x = 1.0
-  v = 0
-  !$acc atomic capture
-  v = x
-  x = x + v
-  !$acc end atomic
-end subroutine capture_with_convert_i32_to_f32
-
-! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f32()
-! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"}
-! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[X:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"}
-! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f32
-! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f32, !fir.ref<f32>
-! CHECK: %c0_i32 = arith.constant 0 : i32
-! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
-! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
-! CHECK: acc.atomic.capture {
-! CHECK:   acc.atomic.read %[[V_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<i32>, !fir.ref<f32>, f32
-! CHECK:   acc.atomic.update %[[X_DECL]]#0 : !fir.ref<f32> {
-! CHECK:   ^bb0(%arg0: f32):
-! CHECK:     %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f32
-! CHECK:     %[[ADD:.*]] = arith.addf %arg0, %[[CONV]] fastmath<contract> : f32
-! CHECK:     acc.yield %[[ADD]] : f32
-! CHECK:   }
-! CHECK: }
-
 subroutine array_ref_in_atomic_capture1
   integer :: x(10), v
   !$acc atomic capture
diff --git a/flang/test/Lower/OpenACC/acc-atomic-read.f90 b/flang/test/Lower/OpenACC/acc-atomic-read.f90
index 639a98051e3a2..0ac47e14d7797 100644
--- a/flang/test/Lower/OpenACC/acc-atomic-read.f90
+++ b/flang/test/Lower/OpenACC/acc-atomic-read.f90
@@ -51,8 +51,12 @@ subroutine atomic_read_with_cast()
 end
 
 ! CHECK-LABEL: func.func @_QPatomic_read_with_cast() {
+! CHECK: %[[ALLOCA:.*]] = fir.alloca i64
 ! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_read_with_castEx"}
 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_read_with_castEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
 ! CHECK: %[[Y:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFatomic_read_with_castEy"}
 ! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_read_with_castEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
-! CHECK: acc.atomic.read %[[Y_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<i64>, !fir.ref<i32>, i32
+! CHECK: %[[LOAD:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
+! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (i32) -> i64
+! CHECK: fir.store %[[CVT]] to %[[ALLOCA]] : !fir.ref<i64>
+! CHECK: acc.atomic.read %[[Y_DECL]]#0 = %[[ALLOCA]] : !fir.ref<i64>, !fir.ref<i64>, i64
diff --git a/flang/test/Lower/OpenMP/Todo/atomic-capture-implicit-cast.f90 b/flang/test/Lower/OpenMP/Todo/atomic-capture-implicit-cast.f90
new file mode 100644
index 0000000000000..5b61f1169308f
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/atomic-capture-implicit-cast.f90
@@ -0,0 +1,48 @@
+!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+!CHECK: not yet implemented: atomic capture requiring implicit type casts 
+subroutine capture_with_convert_f32_to_i32()
+    implicit none
+    integer :: k, v, i
+
+    k = 1
+    v = 0
+
+    !$omp atomic capture
+    v = k
+    k = (i + 1) * 3.14
+    !$omp end atomic
+end subroutine
+
+subroutine capture_with_convert_i32_to_f64()
+    real(8) :: x
+    integer :: v
+    x = 1.0
+    v = 0
+    !$omp atomic capture
+    v = x
+    x = v
+    !$omp end atomic
+end subroutine capture_with_convert_i32_to_f64
+
+subroutine capture_with_convert_f64_to_i32()
+    integer :: x
+    real(8) :: v
+    x = 1
+    v = 0
+    !$omp atomic capture
+    x = v
+    v = x
+    !$omp end atomic
+end subroutine capture_with_convert_f64_to_i32
+
+subroutine capture_with_convert_i32_to_f32()
+    real(4) :: x
+    integer :: v
+    x = 1.0
+    v = 0
+    !$omp atomic capture
+    v = x
+    x = x + v
+    !$omp end atomic
+end subroutine capture_with_convert_i32_to_f32
diff --git a/flang/test/Lower/OpenMP/atomic-implicit-cast.f90 b/flang/test/Lower/OpenMP/atomic-implicit-cast.f90
new file mode 100644
index 0000000000000..64fef1ad0393f
--- /dev/null
+++ b/flang/test/Lower/OpenMP/atomic-implicit-cast.f90
@@ -0,0 +1,57 @@
+! REQUIRES : openmp_runtime
+
+! RUN: %flang_fc1 -emit-hlfir %openmp_flags %s -o - | FileCheck %s
+
+! CHECK: func.func @_QPatomic_implicit_cast_read() {
+subroutine atomic_implicit_cast_read
+! CHECK: %[[ALLOCA3:.*]] = fir.alloca complex<f64>
+! CHECK: %[[ALLOCA2:.*]] = fir.alloca i32
+! CHECK: %[[ALLOCA1:.*]] = fir.alloca f64
+! CHECK: %[[ALLOCA0:.*]] = fir.alloca i32
+
+
+! CHECK: %[[M:.*]] = fir.alloca complex<f64> {bindc_name = "m", uniq_name = "_QFatomic_implicit_cast_readEm"}
+! CHECK: %[[M_DECL:.*]]:2 = hlfir.declare %[[M]] {uniq_name = "_QFatomic_implicit_cast_readEm"} : (!fir.ref<complex<f64>>) -> (!fir.ref<complex<f64>>, !fir.ref<complex<f64>>)
+! CHECK: %[[W:.*]] = fir.alloca complex<f32> {bindc_name = "w", uniq_name = "_QFatomic_implicit_cast_readEw"}
+! CHECK: %[[W_DECL:.*]]:2 = hlfir.declare %[[W]] {uniq_name = "_QFatomic_implicit_cast_readEw"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
+! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_implicit_cast_readEx"}
+! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_implicit_cast_readEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[Y:.*]] = fir.alloca f32 {bindc_name = "y", uniq_name = "_QFatomic_implicit_cast_readEy"}
+! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_implicit_cast_readEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[Z:.*]] = fir.alloca f64 {bindc_name = "z", uniq_name = "_QFatomic_implicit_cast_readEz"}
+! CHECK: %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z]] {uniq_name = "_QFatomic_implicit_cast_readEz"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+    integer :: x
+    real :: y
+    double precision :: z
+    complex :: w
+    complex(8) :: m
+
+! CHECK: %[[LOAD:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref<f32>
+! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (f32) -> i32
+! CHECK: fir.store %[[CVT]] to %[[ALLOCA0]] : !fir.ref<i32>
+! CHECK: omp.atomic.read %[[X_DECL]]#0 = %[[ALLOCA0]] : !fir.ref<i32>, !fir.ref<i32>, i32
+    !$omp atomic read
+        x = y
+
+! CHECK: %[[LOAD:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
+! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
+! CHECK: fir.store %[[CVT]] to %[[ALLOCA1]] : !fir.ref<f64>
+! CHECK: omp.atomic.read %[[Z_DECL]]#0 = %[[ALLOCA1]] : !fir.ref<f64>, !fir.ref<f64>, f64
+    !$omp atomic read
+        z = x
+
+! CHECK: %[[LOAD:.*]] = fir.load %[[W_DECL]]#0 : !fir.ref<complex<f32>>
+! CHECK: %[[EXTRACT:.*]] = fir.extract_value %[[LOAD]], [0 : index] : (complex<f32>) -> f32
+! CHECK: %[[CVT:.*]] = fir.convert %[[EXTRACT]] : (f32) -> i32
+! CHECK: fir.store %[[CVT]] to %[[ALLOCA2]] : !fir.ref<i32>
+! CHECK: omp.atomic.read %[[X_DECL]]#0 = %[[ALLOCA2]] : !fir.ref<i32>, !fir.ref<i32>, i32
+    !$omp atomic read
+        x = w
+
+! CHECK: %[[LOAD:.*]] = fir.load %[[W_DECL]]#0 : !fir.ref<complex<f32>>
+! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (complex<f32>) -> complex<f64>
+! CHECK: fir.store %[[CVT]] to %[[ALLOCA3]] : !fir.ref<complex<f64>>
+! CHECK: omp.atomic.read %[[M_DECL]]#0 = %[[ALLOCA3]] : !fir.ref<complex<f64>>, !fir.ref<complex<f64>>, complex<f64>
+    !$omp atomic read
+        m = w
+end subroutine
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 13b727d226738..fa0d82783d0fa 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -268,33 +268,6 @@ computeOpenMPScheduleType(ScheduleKind ClauseKind, bool HasChunks,
   return Result;
 }
 
-/// Emit an implicit cast to convert \p XRead to type of variable \p V
-static llvm::Value *emitImplicitCast(IRBuilder<> &Builder, llvm::Value *XRead,
-                                     llvm::Value *V) {
-  // TODO: Add this functionality to the `AtomicInfo` interface
-  llvm::Type *XReadType = XRead->getType();
-  llvm::Type *VType = V->getType();
-  if (llvm::AllocaInst *vAlloca = dyn_cast<llvm::AllocaInst>(V))
-    VType = vAlloca->getAllocatedType();
-
-  if (XReadType->isStructTy() && VType->isStructTy())
-    // No need to extract or convert. A direct
-    // `store` will suffice.
-    return XRead;
-
-  if (XReadType->isStructTy())
-    XRead = Builder.CreateExtractValue(XRead, /*Idxs=*/0);
-  if (VType->isIntegerTy() && XReadType->isFloatingPointTy())
-    XRead = Builder.CreateFPToSI(XRead, VType);
-  else if (VType->isFloatingPointTy() && XReadType->isIntegerTy())
-    XRead = Builder.CreateSIToFP(XRead, VType);
-  else if (VType->isIntegerTy() && XReadType->isIntegerTy())
-    XRead = Builder.CreateIntCast(XRead, VType, true);
-  else if (VType->isFloatingPointTy() && XReadType->isFloatingPointTy())
-    XRead = Builder.CreateFPCast(XRead, VType);
-  return XRead;
-}
-
 /// Make \p Source branch to \p Target.
 ///
 /// Handles two situations:
@@ -8683,8 +8656,6 @@ OpenMPIRBuilder::createAtomicRead(const LocationDescription &Loc,
     }
   }
   checkAndEmitFlushAfterAtomic(Loc, AO, AtomicKind::Read);
-  if (XRead->getType() != V.Var->getType())
-    XRead = emitImplicitCast(Builder, XRead, V.Var);
   Builder.CreateStore(XRead, V.Var, V.IsVolatile);
   return Builder.saveIP();
 }
@@ -8969,8 +8940,6 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createAtomicCapture(
     return AtomicResult.takeError();
   Value *CapturedVal =
       (IsPostfixUpdate ? AtomicResult->first : AtomicResult->second);
-  if (CapturedVal->getType() != V.Var->getType())
-    CapturedVal = emitImplicitCast(Builder, CapturedVal, V.Var);
   Builder.CreateStore(CapturedVal, V.Var, V.IsVolatile);
 
   checkAndEmitFlushAfterAtomic(Loc, AO, AtomicKind::Capture);



More information about the flang-commits mailing list