[flang-commits] [flang] [flang][hlfir] Make alias analysis trace through box designators. (PR #67353)
via flang-commits
flang-commits at lists.llvm.org
Mon Sep 25 10:26:11 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
<details>
<summary>Changes</summary>
The changes are needed to get leslie3d same performance with HLFIR
as with FIR lowering. The two module allocatable variables cannot
alias, so the optimized bufferization should be able to elide
the temporary and inline the assignment loop.
---
Patch is 20.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/67353.diff
7 Files Affected:
- (modified) flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td (+14)
- (modified) flang/lib/Optimizer/Analysis/AliasAnalysis.cpp (+25-1)
- (modified) flang/test/Analysis/AliasAnalysis/alias-analysis-6.fir (+1-1)
- (added) flang/test/Analysis/AliasAnalysis/alias-analysis-7.fir (+99)
- (modified) flang/test/Analysis/AliasAnalysis/alias-analysis-host-assoc.fir (+1-2)
- (added) flang/test/HLFIR/opt-bufferization-leslie3d.fir (+102)
- (modified) flang/test/HLFIR/opt-variable-assign.fir (+10-14)
``````````diff
diff --git a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td
index cf31fbcf37cf3d5..6405afbf1bfbc23 100644
--- a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td
+++ b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td
@@ -177,6 +177,20 @@ def fir_FortranVariableOpInterface : OpInterface<"FortranVariableOpInterface"> {
fir::FortranVariableFlagsEnum::host_assoc);
}
+ /// Is this variable a Fortran target?
+ bool isTarget() {
+ auto attrs = getFortranAttrs();
+ return attrs && bitEnumContainsAny(*attrs,
+ fir::FortranVariableFlagsEnum::target);
+ }
+
+ /// Is this variable a Fortran intent(in)?
+ bool isIntentIn() {
+ auto attrs = getFortranAttrs();
+ return attrs && bitEnumContainsAny(*attrs,
+ fir::FortranVariableFlagsEnum::intent_in);
+ }
+
/// Interface verifier imlementation for declare operations.
mlir::LogicalResult verifyDeclareLikeOpImpl(mlir::Value memRef);
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index aeb6e692784f769..850026ebf33b995 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -239,13 +239,26 @@ ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) {
return result;
}
+AliasAnalysis::Source::Attributes
+getAttrsFromVariable(fir::FortranVariableOpInterface var) {
+ AliasAnalysis::Source::Attributes attrs;
+ if (var.isTarget())
+ attrs.set(AliasAnalysis::Attribute::Target);
+ if (var.isPointer())
+ attrs.set(AliasAnalysis::Attribute::Pointer);
+ if (var.isIntentIn())
+ attrs.set(AliasAnalysis::Attribute::IntentIn);
+
+ return attrs;
+}
+
AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
auto *defOp = v.getDefiningOp();
SourceKind type{SourceKind::Unknown};
mlir::Type ty;
bool breakFromLoop{false};
bool approximateSource{false};
- bool followBoxAddr{false};
+ bool followBoxAddr{mlir::isa<fir::BaseBoxType>(v.getType())};
mlir::SymbolRefAttr global;
Source::Attributes attributes;
while (defOp && !breakFromLoop) {
@@ -334,6 +347,15 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
})
.Case<hlfir::DeclareOp, fir::DeclareOp>([&](auto op) {
auto varIf = llvm::cast<fir::FortranVariableOpInterface>(defOp);
+ // While going through a declare operation collect
+ // the variable attributes from it. Right now, some
+ // of the attributes are duplicated, e.g. a TARGET dummy
+ // argument has the target attribute both on its declare
+ // operation and on the entry block argument.
+ // In case of host associated use, the declare operation
+ // is the only carrier of the variable attributes,
+ // so we have to collect them here.
+ attributes |= getAttrsFromVariable(varIf);
if (varIf.isHostAssoc()) {
// Do not track past such DeclareOp, because it does not
// currently provide any useful information. The host associated
@@ -364,6 +386,8 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
// because of this limitation, we need to make sure we never return
// MustAlias after going through a designate operation
approximateSource = true;
+ if (mlir::isa<fir::BaseBoxType>(v.getType()))
+ followBoxAddr = true;
})
.Default([&](auto op) {
defOp = nullptr;
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-6.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-6.fir
index 82d89989c9cf726..85c780312bd47d2 100644
--- a/flang/test/Analysis/AliasAnalysis/alias-analysis-6.fir
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-6.fir
@@ -1,4 +1,4 @@
-// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))'
+// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' 2>&1 | FileCheck %s
// CHECK: test_y(1)#0 <-> test_x(1)#0: MayAlias
func.func @_QPtest(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {fir.bindc_name = "y"}) {
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-7.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-7.fir
new file mode 100644
index 000000000000000..fdf2fc4353bbb90
--- /dev/null
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-7.fir
@@ -0,0 +1,99 @@
+// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' 2>&1 | FileCheck %s
+
+// leslie3d case with two allocatable module variables
+// that cannot alias:
+// module les3d_data
+// implicit real*8 (a-h,o-z)
+// integer imax, jmax, kmax
+// double precision,allocatable,dimension(:,:,:,:,:) :: q
+// double precision,allocatable,dimension(:,:,:,:) :: du
+// end module les3d_data
+// subroutine update()
+// use les3d_data
+// implicit real*8(a-h,o-z)
+// i2 = imax - 1
+// do k = 1, kmax - 1
+// do j = 1, jmax - 1
+// q(1:i2,j,k,1,m) = (q(1:i2,j,k,1,m) + du(1:i2,j,k,1))
+// end do
+// end do
+// end subroutine update
+
+// CHECK: allocatable_mod1#0 <-> allocatable_mod2#0: NoAlias
+func.func @_QPupdate() {
+ %c1 = arith.constant 1 : index
+ %c0 = arith.constant 0 : index
+ %c1_i32 = arith.constant 1 : i32
+ %0 = fir.address_of(@_QMles3d_dataEdu) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
+ %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMles3d_dataEdu"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>)
+ %2 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QFupdateEi2"}
+ %3:2 = hlfir.declare %2 {uniq_name = "_QFupdateEi2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %4 = fir.address_of(@_QMles3d_dataEimax) : !fir.ref<i32>
+ %5:2 = hlfir.declare %4 {uniq_name = "_QMles3d_dataEimax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %6 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFupdateEj"}
+ %7:2 = hlfir.declare %6 {uniq_name = "_QFupdateEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %8 = fir.address_of(@_QMles3d_dataEjmax) : !fir.ref<i32>
+ %9:2 = hlfir.declare %8 {uniq_name = "_QMles3d_dataEjmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %10 = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFupdateEk"}
+ %11:2 = hlfir.declare %10 {uniq_name = "_QFupdateEk"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %12 = fir.address_of(@_QMles3d_dataEkmax) : !fir.ref<i32>
+ %13:2 = hlfir.declare %12 {uniq_name = "_QMles3d_dataEkmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %14 = fir.alloca i32 {bindc_name = "m", uniq_name = "_QFupdateEm"}
+ %15:2 = hlfir.declare %14 {uniq_name = "_QFupdateEm"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %16 = fir.address_of(@_QMles3d_dataEq) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
+ %17:2 = hlfir.declare %16 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMles3d_dataEq"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>)
+ %18 = fir.load %5#0 : !fir.ref<i32>
+ %19 = arith.subi %18, %c1_i32 : i32
+ hlfir.assign %19 to %3#0 : i32, !fir.ref<i32>
+ %20 = fir.load %13#0 : !fir.ref<i32>
+ %21 = arith.subi %20, %c1_i32 : i32
+ %22 = fir.convert %21 : (i32) -> index
+ %23 = fir.convert %c1 : (index) -> i32
+ %24:2 = fir.do_loop %arg0 = %c1 to %22 step %c1 iter_args(%arg1 = %23) -> (index, i32) {
+ fir.store %arg1 to %11#1 : !fir.ref<i32>
+ %25 = fir.load %9#0 : !fir.ref<i32>
+ %26 = arith.subi %25, %c1_i32 : i32
+ %27 = fir.convert %26 : (i32) -> index
+ %28:2 = fir.do_loop %arg2 = %c1 to %27 step %c1 iter_args(%arg3 = %23) -> (index, i32) {
+ fir.store %arg3 to %7#1 : !fir.ref<i32>
+ %32 = fir.load %17#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
+ %33 = fir.load %3#0 : !fir.ref<i32>
+ %34 = fir.convert %33 : (i32) -> index
+ %35 = arith.cmpi sgt, %34, %c0 : index
+ %36 = arith.select %35, %34, %c0 : index
+ %37 = fir.load %7#0 : !fir.ref<i32>
+ %38 = fir.convert %37 : (i32) -> i64
+ %39 = fir.load %11#0 : !fir.ref<i32>
+ %40 = fir.convert %39 : (i32) -> i64
+ %41 = fir.load %15#0 : !fir.ref<i32>
+ %42 = fir.convert %41 : (i32) -> i64
+ %43 = fir.shape %36 : (index) -> !fir.shape<1>
+ %44 = hlfir.designate %32 (%c1:%34:%c1, %38, %40, %c1, %42) shape %43 {test.ptr = "allocatable_mod1"} : (!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>, index, index, index, i64, i64, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf64>>
+ %45 = fir.load %1#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
+ %46 = hlfir.designate %45 (%c1:%34:%c1, %38, %40, %c1) shape %43 {test.ptr = "allocatable_mod2"} : (!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>, index, index, index, i64, i64, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf64>>
+ %47 = hlfir.elemental %43 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf64> {
+ ^bb0(%arg4: index):
+ %51 = hlfir.designate %44 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
+ %52 = hlfir.designate %46 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
+ %53 = fir.load %51 : !fir.ref<f64>
+ %54 = fir.load %52 : !fir.ref<f64>
+ %55 = arith.addf %53, %54 fastmath<fast> : f64
+ %56 = hlfir.no_reassoc %55 : f64
+ hlfir.yield_element %56 : f64
+ }
+ hlfir.assign %47 to %44 : !hlfir.expr<?xf64>, !fir.box<!fir.array<?xf64>>
+ hlfir.destroy %47 : !hlfir.expr<?xf64>
+ %48 = arith.addi %arg2, %c1 : index
+ %49 = fir.load %7#1 : !fir.ref<i32>
+ %50 = arith.addi %49, %23 : i32
+ fir.result %48, %50 : index, i32
+ }
+ fir.store %28#1 to %7#1 : !fir.ref<i32>
+ %29 = arith.addi %arg0, %c1 : index
+ %30 = fir.load %11#1 : !fir.ref<i32>
+ %31 = arith.addi %30, %23 : i32
+ fir.result %29, %31 : index, i32
+ }
+ fir.store %24#1 to %11#1 : !fir.ref<i32>
+ return
+}
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-host-assoc.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-host-assoc.fir
index 785f1b91a7d9bcd..7f90384ac99c567 100644
--- a/flang/test/Analysis/AliasAnalysis/alias-analysis-host-assoc.fir
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-host-assoc.fir
@@ -297,8 +297,7 @@ func.func @_QFtest8Pinner(%arg0: !fir.ref<tuple<!fir.box<!fir.array<10xi32>>>> {
// end subroutine inner
// end subroutine test9
-// FIXME: 'g' is classified as Indirect access leading to a conservative reply:
-// CHECK: test9_g(1)#0 <-> test9_x(1)#0: MayAlias
+// CHECK: test9_g(1)#0 <-> test9_x(1)#0: NoAlias
func.func @_QFtest9Pinner(%arg0: !fir.ref<tuple<!fir.box<!fir.array<10xi32>>>> {fir.host_assoc}) attributes {fir.internal_proc} {
%0 = fir.address_of(@_QMglobalsEg) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
%1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMglobalsEg"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
diff --git a/flang/test/HLFIR/opt-bufferization-leslie3d.fir b/flang/test/HLFIR/opt-bufferization-leslie3d.fir
new file mode 100644
index 000000000000000..351b3754cf4dbb9
--- /dev/null
+++ b/flang/test/HLFIR/opt-bufferization-leslie3d.fir
@@ -0,0 +1,102 @@
+// RUN: fir-opt --opt-bufferization %s | FileCheck %s
+
+// leslie3d case with two allocatable module variables
+// that cannot alias:
+// module les3d_data
+// implicit real*8 (a-h,o-z)
+// integer imax, jmax, kmax
+// double precision,allocatable,dimension(:,:,:,:,:) :: q
+// double precision,allocatable,dimension(:,:,:,:) :: du
+// end module les3d_data
+// subroutine update()
+// use les3d_data
+// implicit real*8(a-h,o-z)
+// i2 = imax - 1
+// do k = 1, kmax - 1
+// do j = 1, jmax - 1
+// q(1:i2,j,k,1,m) = (q(1:i2,j,k,1,m) + du(1:i2,j,k,1))
+// end do
+// end do
+// end subroutine update
+
+func.func @_QPupdate() {
+ %c1 = arith.constant 1 : index
+ %c0 = arith.constant 0 : index
+ %c1_i32 = arith.constant 1 : i32
+ %0 = fir.address_of(@_QMles3d_dataEdu) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
+ %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMles3d_dataEdu"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>)
+ %2 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QFupdateEi2"}
+ %3:2 = hlfir.declare %2 {uniq_name = "_QFupdateEi2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %4 = fir.address_of(@_QMles3d_dataEimax) : !fir.ref<i32>
+ %5:2 = hlfir.declare %4 {uniq_name = "_QMles3d_dataEimax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %6 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFupdateEj"}
+ %7:2 = hlfir.declare %6 {uniq_name = "_QFupdateEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %8 = fir.address_of(@_QMles3d_dataEjmax) : !fir.ref<i32>
+ %9:2 = hlfir.declare %8 {uniq_name = "_QMles3d_dataEjmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %10 = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFupdateEk"}
+ %11:2 = hlfir.declare %10 {uniq_name = "_QFupdateEk"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %12 = fir.address_of(@_QMles3d_dataEkmax) : !fir.ref<i32>
+ %13:2 = hlfir.declare %12 {uniq_name = "_QMles3d_dataEkmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %14 = fir.alloca i32 {bindc_name = "m", uniq_name = "_QFupdateEm"}
+ %15:2 = hlfir.declare %14 {uniq_name = "_QFupdateEm"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %16 = fir.address_of(@_QMles3d_dataEq) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
+ %17:2 = hlfir.declare %16 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMles3d_dataEq"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>)
+ %18 = fir.load %5#0 : !fir.ref<i32>
+ %19 = arith.subi %18, %c1_i32 : i32
+ hlfir.assign %19 to %3#0 : i32, !fir.ref<i32>
+ %20 = fir.load %13#0 : !fir.ref<i32>
+ %21 = arith.subi %20, %c1_i32 : i32
+ %22 = fir.convert %21 : (i32) -> index
+ %23 = fir.convert %c1 : (index) -> i32
+ %24:2 = fir.do_loop %arg0 = %c1 to %22 step %c1 iter_args(%arg1 = %23) -> (index, i32) {
+ fir.store %arg1 to %11#1 : !fir.ref<i32>
+ %25 = fir.load %9#0 : !fir.ref<i32>
+ %26 = arith.subi %25, %c1_i32 : i32
+ %27 = fir.convert %26 : (i32) -> index
+ %28:2 = fir.do_loop %arg2 = %c1 to %27 step %c1 iter_args(%arg3 = %23) -> (index, i32) {
+ fir.store %arg3 to %7#1 : !fir.ref<i32>
+ %32 = fir.load %17#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
+ %33 = fir.load %3#0 : !fir.ref<i32>
+ %34 = fir.convert %33 : (i32) -> index
+ %35 = arith.cmpi sgt, %34, %c0 : index
+ %36 = arith.select %35, %34, %c0 : index
+ %37 = fir.load %7#0 : !fir.ref<i32>
+ %38 = fir.convert %37 : (i32) -> i64
+ %39 = fir.load %11#0 : !fir.ref<i32>
+ %40 = fir.convert %39 : (i32) -> i64
+ %41 = fir.load %15#0 : !fir.ref<i32>
+ %42 = fir.convert %41 : (i32) -> i64
+ %43 = fir.shape %36 : (index) -> !fir.shape<1>
+ %44 = hlfir.designate %32 (%c1:%34:%c1, %38, %40, %c1, %42) shape %43 : (!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>, index, index, index, i64, i64, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf64>>
+ %45 = fir.load %1#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
+ %46 = hlfir.designate %45 (%c1:%34:%c1, %38, %40, %c1) shape %43 : (!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>, index, index, index, i64, i64, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf64>>
+ %47 = hlfir.elemental %43 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf64> {
+ ^bb0(%arg4: index):
+ %51 = hlfir.designate %44 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
+ %52 = hlfir.designate %46 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
+ %53 = fir.load %51 : !fir.ref<f64>
+ %54 = fir.load %52 : !fir.ref<f64>
+ %55 = arith.addf %53, %54 fastmath<fast> : f64
+ %56 = hlfir.no_reassoc %55 : f64
+ hlfir.yield_element %56 : f64
+ }
+ hlfir.assign %47 to %44 : !hlfir.expr<?xf64>, !fir.box<!fir.array<?xf64>>
+ hlfir.destroy %47 : !hlfir.expr<?xf64>
+ %48 = arith.addi %arg2, %c1 : index
+ %49 = fir.load %7#1 : !fir.ref<i32>
+ %50 = arith.addi %49, %23 : i32
+ fir.result %48, %50 : index, i32
+ }
+ fir.store %28#1 to %7#1 : !fir.ref<i32>
+ %29 = arith.addi %arg0, %c1 : index
+ %30 = fir.load %11#1 : !fir.ref<i32>
+ %31 = arith.addi %30, %23 : i32
+ fir.result %29, %31 : index, i32
+ }
+ fir.store %24#1 to %11#1 : !fir.ref<i32>
+ return
+}
+// CHECK-LABEL: func.func @_QPupdate() {
+// CHECK-NOT: hlfir.assign {{.*}}!fir.box<!fir.array<?xf64>>
+// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f64, !fir.ref<f64>
+// CHECK-NOT: hlfir.assign {{.*}}!fir.box<!fir.array<?xf64>>
diff --git a/flang/test/HLFIR/opt-variable-assign.fir b/flang/test/HLFIR/opt-variable-assign.fir
index f0a8f013f3c29c3..17124fa86af65ad 100644
--- a/flang/test/HLFIR/opt-variable-assign.fir
+++ b/flang/test/HLFIR/opt-variable-assign.fir
@@ -185,7 +185,7 @@ func.func @_QPtest4(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>> {f
// CHECK-NOT: hlfir.assign
-// TODO: LHS is a pointer, but RHS is a subroutine local,
+// LHS is a pointer, but RHS is a subroutine local,
// so they cannot alias.
func.func @_QPtest5(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fir.bindc_name = "x"}) {
%c0 = arith.constant 0 : index
@@ -220,13 +220,13 @@ func.func @_QPtest5(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fi
}
// CHECK-LABEL: func.func @_QPtest5(
// CHECK-NOT: hlfir.assign
-// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.ref<!fir.array<3x3xf32>>, !fir.box<!fir.array<?x?xf32>>
+// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
// CHECK-NOT: hlfir.assign
-// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.ref<!fir.array<3x3xf32>>, !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
+// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
// CHECK-NOT: hlfir.assign
-// TODO: RHS is a pointer, but LHS is a subroutine local,
+// RHS is a pointer, but LHS is a subroutine local,
// so they cannot alias.
func.func @_QPtest6(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fir.bindc_name = "x"}) {
%c1 = arith.constant 1 : index
@@ -261,20 +261,14 @@ func.func @_QPtest6(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fi
}
// CHECK-LABEL: func.func @_QPtest6(
// CHECK-NOT: hlfir.assign
-// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<3x3xf32>>
+// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
// CHECK-NOT: hlfir.assign
-// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.box<!fir.ptr<!fir.array<?x?xf32>>>, !fir.ref<!fir.array<3x3xf32>>
+// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
// CHECK-NOT: hlfir.assign
-// TODO: LHS and RHS do not alias, and the assignment cannot
+// LHS and RHS do not alias, and the assignment cannot
// allocate/reallocate LHS, so we should be able to optimize.
-// The box load blocks alias analysis.
-// subroutine test7(x)
-// real, allocatable :: x(:,:)
-// real :: y(3,3)
-// x(:,:) = y(:,:)
-// end subroutine test7
func.func @_QPtest7(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>> {fir.bindc_name = "x"}) {
%c0 = arith.con...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/67353
More information about the flang-commits
mailing list