[flang][hlfir] Make alias analysis trace through box designators. (#67353)
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.
This commit is contained in:
parent
d9942319d7
commit
f1ea831dbc
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"}) {
|
||||
|
99
flang/test/Analysis/AliasAnalysis/alias-analysis-7.fir
Normal file
99
flang/test/Analysis/AliasAnalysis/alias-analysis-7.fir
Normal file
@ -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
|
||||
}
|
@ -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>>>>)
|
||||
|
102
flang/test/HLFIR/opt-bufferization-leslie3d.fir
Normal file
102
flang/test/HLFIR/opt-bufferization-leslie3d.fir
Normal file
@ -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>>
|
@ -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.constant 0 : index
|
||||
%c1 = arith.constant 1 : index
|
||||
@ -305,4 +299,6 @@ func.func @_QPtest7(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>> {f
|
||||
return
|
||||
}
|
||||
// CHECK-LABEL: func.func @_QPtest7(
|
||||
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.ref<!fir.array<3x3xf32>>, !fir.box<!fir.array<?x?xf32>>
|
||||
// CHECK-NOT: hlfir.assign
|
||||
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
|
||||
// CHECK-NOT: hlfir.assign
|
||||
|
Loading…
x
Reference in New Issue
Block a user