[flang-commits] [flang] [flang] Ignore subscript conversions when reassociating sums (PR #222302)

via flang-commits flang-commits at lists.llvm.org
Wed Sep 9 04:22:24 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-openacc

Author: Tom Eccles (tblah)

<details>
<summary>Changes</summary>

Implicit conversions of INTEGER(4) array indices to SubscriptInteger were treated as conversions in the surrounding floating-point sum, preventing reassociation of ordinary array-element expressions.

Stop only the conversion traversal at subscripts. Keep the independent side-effect and volatile/asynchronous checks and embedded numeric conversion restrictions unchanged.

Assisted-by: Codex

---
Full diff: https://github.com/llvm/llvm-project/pull/222302.diff


3 Files Affected:

- (modified) flang/lib/Evaluate/tools.cpp (+4) 
- (modified) flang/test/Lower/OpenACC/acc-cache.f90 (+1-1) 
- (added) flang/test/Lower/split-sum-expression-tree-subscripts.f90 (+100) 


``````````diff
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 6c8ee3da0046f..def85232cc572 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -1416,6 +1416,10 @@ struct HasConversionHelper : public AnyTraverse<HasConversionHelper> {
   using Base = AnyTraverse<HasConversionHelper>;
   HasConversionHelper() : Base{*this} {}
   using Base::operator();
+  // Subscript conversions belong to the array designator and are preserved
+  // when reassociating the surrounding numeric expression. In particular,
+  // implicit conversions to SubscriptInteger must not inhibit reassociation.
+  bool operator()(const Subscript &) const { return false; }
   template <typename TO, common::TypeCategory FROM>
   bool operator()(const Convert<TO, FROM> &) const {
     return true;
diff --git a/flang/test/Lower/OpenACC/acc-cache.f90 b/flang/test/Lower/OpenACC/acc-cache.f90
index 12bdee3833870..9bdacc17cd984 100644
--- a/flang/test/Lower/OpenACC/acc-cache.f90
+++ b/flang/test/Lower/OpenACC/acc-cache.f90
@@ -212,10 +212,10 @@ subroutine test_cache_loop_var()
 ! CHECK: fir.load
 ! CHECK: hlfir.designate %[[DECL]]#0
 ! CHECK: fir.load
-! CHECK: arith.addf
 ! CHECK: hlfir.designate %[[DECL]]#0
 ! CHECK: fir.load
 ! CHECK: arith.addf
+! CHECK: arith.addf
 ! CHECK: hlfir.assign
 ! Scope termination
 ! CHECK: acc.yield
diff --git a/flang/test/Lower/split-sum-expression-tree-subscripts.f90 b/flang/test/Lower/split-sum-expression-tree-subscripts.f90
new file mode 100644
index 0000000000000..aac09e4443465
--- /dev/null
+++ b/flang/test/Lower/split-sum-expression-tree-subscripts.f90
@@ -0,0 +1,100 @@
+! RUN: %flang_fc1 -emit-hlfir -O0 -o - %s | FileCheck %s --check-prefixes=SPLIT,GUARD
+! RUN: %flang_fc1 -emit-hlfir -O3 -o - %s | FileCheck %s --check-prefixes=SPLIT,GUARD
+! RUN: %flang_fc1 -emit-hlfir -ffp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=SPLIT,GUARD
+! RUN: %flang_fc1 -emit-hlfir -fno-fp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=ORDERED,GUARD
+! RUN: bbc -emit-hlfir -o - %s | FileCheck %s --check-prefixes=SPLIT,GUARD
+! RUN: bbc -emit-hlfir -ffp-sum-reassociation=false -o - %s | FileCheck %s --check-prefixes=ORDERED,GUARD
+
+! The implicit INTEGER(4)-to-INTEGER(8) conversions in array subscripts
+! must not prevent reassociation of the REAL(8) sum (as in SNbone).
+subroutine array_elements(i,x,a,b,c,d,e,f)
+  integer(4) :: i
+  real(8) :: x(100),a(100),b(100),c(100),d(100),e(100),f(100)
+  x(i) = x(i) + a(i)*b(i) + c(i)*d(i) + e(i)*f(i)
+end
+
+! SPLIT-LABEL: func.func @_QParray_elements
+! SPLIT: %[[CD:.*]] = arith.mulf
+! SPLIT: %[[EF:.*]] = arith.mulf
+! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
+! SPLIT: %[[AB:.*]] = arith.mulf
+! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
+! SPLIT: %[[SUM:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: hlfir.assign %[[SUM]]
+
+! ORDERED-LABEL: func.func @_QParray_elements
+! ORDERED: %[[AB:.*]] = arith.mulf
+! ORDERED: %[[XAB:.*]] = arith.addf %{{.*}}, %[[AB]]
+! ORDERED: %[[CD:.*]] = arith.mulf
+! ORDERED: %[[XABCD:.*]] = arith.addf %[[XAB]], %[[CD]]
+! ORDERED: %[[EF:.*]] = arith.mulf
+! ORDERED: %[[SUM:.*]] = arith.addf %[[XABCD]], %[[EF]]
+! ORDERED: hlfir.assign %[[SUM]]
+
+! Both levels of indexing contain integer conversions.
+subroutine nested_subscript(i,j,x,a,b,c,d,e,f)
+  integer(4) :: i,j(100)
+  real(8) :: x(100),a,b,c,d,e,f
+  x(j(i)) = x(j(i)) + a*b + c*d + e*f
+end
+
+! SPLIT-LABEL: func.func @_QPnested_subscript
+! SPLIT: %[[CD:.*]] = arith.mulf
+! SPLIT: %[[EF:.*]] = arith.mulf
+! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
+! SPLIT: %[[AB:.*]] = arith.mulf
+! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
+! SPLIT: %[[SUM:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: hlfir.assign %[[SUM]]
+
+! ORDERED-LABEL: func.func @_QPnested_subscript
+! ORDERED: %[[AB:.*]] = arith.mulf
+! ORDERED: %[[XAB:.*]] = arith.addf %{{.*}}, %[[AB]]
+! ORDERED: %[[CD:.*]] = arith.mulf
+! ORDERED: %[[XABCD:.*]] = arith.addf %[[XAB]], %[[CD]]
+! ORDERED: %[[EF:.*]] = arith.mulf
+! ORDERED: %[[SUM:.*]] = arith.addf %[[XABCD]], %[[EF]]
+! ORDERED: hlfir.assign %[[SUM]]
+
+! A conversion of a real value used only as a subscript is also preserved.
+subroutine real_subscript_conversion(r,x,a,b,c,d,e,f)
+  real(4) :: r
+  real(8) :: x(100),a,b,c,d,e,f
+  x(int(r,8)) = x(int(r,8)) + a*b + c*d + e*f
+end
+
+! SPLIT-LABEL: func.func @_QPreal_subscript_conversion
+! SPLIT: %[[CD:.*]] = arith.mulf
+! SPLIT: %[[EF:.*]] = arith.mulf
+! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
+! SPLIT: fir.convert %{{.*}} : (f32) -> i64
+! SPLIT: %[[AB:.*]] = arith.mulf
+! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
+! SPLIT: %[[SUM:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: hlfir.assign %[[SUM]]
+
+! ORDERED-LABEL: func.func @_QPreal_subscript_conversion
+! ORDERED: %[[AB:.*]] = arith.mulf
+! ORDERED: %[[XAB:.*]] = arith.addf %{{.*}}, %[[AB]]
+! ORDERED: %[[CD:.*]] = arith.mulf
+! ORDERED: %[[XABCD:.*]] = arith.addf %[[XAB]], %[[CD]]
+! ORDERED: %[[EF:.*]] = arith.mulf
+! ORDERED: %[[SUM:.*]] = arith.addf %[[XABCD]], %[[EF]]
+! ORDERED: hlfir.assign %[[SUM]]
+
+! Ignoring subscript conversions must not hide a conversion in the real sum.
+subroutine mixed_kind_array_elements(i,x,a,b,c,d,e,f)
+  integer(4) :: i
+  real(8) :: x,a(100),b(100),c(100),d(100)
+  real(4) :: e(100),f(100)
+  x = a(i)*b(i) + c(i)*d(i) + real(e(i)*f(i),8)
+end
+
+! GUARD-LABEL: func.func @_QPmixed_kind_array_elements
+! GUARD: %[[AB:.*]] = arith.mulf
+! GUARD: %[[CD:.*]] = arith.mulf
+! GUARD: %[[HEAD:.*]] = arith.addf %[[AB]], %[[CD]]
+! GUARD: %[[EF:.*]] = arith.mulf %{{.*}}, %{{.*}} {{.*}} : f32
+! GUARD: %[[CONVERT:.*]] = fir.convert %[[EF]] : (f32) -> f64
+! GUARD: %[[SUM:.*]] = arith.addf %[[HEAD]], %[[CONVERT]]
+! GUARD: hlfir.assign %[[SUM]]

``````````

</details>


https://github.com/llvm/llvm-project/pull/222302


More information about the flang-commits mailing list