[flang-commits] [flang] 4f1eec1 - [flang] Fix crash in folding of DPROD() with non-scalar arguments

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Aug 1 09:39:01 PDT 2023


Author: Peter Klausler
Date: 2023-08-01T09:26:34-07:00
New Revision: 4f1eec1fc643d3a6b7ff32e13fa49b3418e29264

URL: https://github.com/llvm/llvm-project/commit/4f1eec1fc643d3a6b7ff32e13fa49b3418e29264
DIFF: https://github.com/llvm/llvm-project/commit/4f1eec1fc643d3a6b7ff32e13fa49b3418e29264.diff

LOG: [flang] Fix crash in folding of DPROD() with non-scalar arguments

DPROD(x,y) is defined as DBLE(x)*DBLE(y) and that's exactly how
the implementation of its rewriting and possible folding should
be implemented, instead of the current code that only works when
both arguments are scalar and crashes otherwise.

Fixes https://github.com/llvm/llvm-project/issues/63991.

Differential Revision: https://reviews.llvm.org/D156754

Added: 
    flang/test/Evaluate/fold-dprod.f90

Modified: 
    flang/lib/Evaluate/fold-real.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp
index 038ec95a332b82..01a97951b0412a 100644
--- a/flang/lib/Evaluate/fold-real.cpp
+++ b/flang/lib/Evaluate/fold-real.cpp
@@ -149,10 +149,15 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
   } else if (name == "dot_product") {
     return FoldDotProduct<T>(context, std::move(funcRef));
   } else if (name == "dprod") {
-    if (auto scalars{GetScalarConstantArguments<T, T>(context, args)}) {
-      return Fold(context,
-          Expr<T>{Multiply<T>{
-              Expr<T>{std::get<0>(*scalars)}, Expr<T>{std::get<1>(*scalars)}}});
+    // Rewrite DPROD(x,y) -> DBLE(x)*DBLE(y)
+    if (args.at(0) && args.at(1)) {
+      const auto *xExpr{args[0]->UnwrapExpr()};
+      const auto *yExpr{args[1]->UnwrapExpr()};
+      if (xExpr && yExpr) {
+        return Fold(context,
+            ToReal<T::kind>(context, common::Clone(*xExpr)) *
+                ToReal<T::kind>(context, common::Clone(*yExpr)));
+      }
     }
   } else if (name == "epsilon") {
     return Expr<T>{Scalar<T>::EPSILON()};

diff  --git a/flang/test/Evaluate/fold-dprod.f90 b/flang/test/Evaluate/fold-dprod.f90
new file mode 100644
index 00000000000000..8b926b999e5535
--- /dev/null
+++ b/flang/test/Evaluate/fold-dprod.f90
@@ -0,0 +1,8 @@
+! RUN: %python %S/test_folding.py %s %flang_fc1
+! Tests folding of DPROD()
+module m
+  logical, parameter :: test_kind = kind(dprod(2., 3.)) == kind(0.d0)
+  logical, parameter :: test_ss = dprod(2., 3.) == 6.d0
+  logical, parameter :: test_sv = all(dprod(2., [3.,4.]) == [6.d0,8.d0])
+  logical, parameter :: test_vv = all(dprod([2.,3.], [4.,5.]) == [8.d0,15.0d0])
+end


        


More information about the flang-commits mailing list