Skip to content

Commit f1ea831

Browse files
authored
[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.
1 parent d994231 commit f1ea831

File tree

7 files changed

+252
-18
lines changed

7 files changed

+252
-18
lines changed

flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,20 @@ def fir_FortranVariableOpInterface : OpInterface<"FortranVariableOpInterface"> {
177177
fir::FortranVariableFlagsEnum::host_assoc);
178178
}
179179

180+
/// Is this variable a Fortran target?
181+
bool isTarget() {
182+
auto attrs = getFortranAttrs();
183+
return attrs && bitEnumContainsAny(*attrs,
184+
fir::FortranVariableFlagsEnum::target);
185+
}
186+
187+
/// Is this variable a Fortran intent(in)?
188+
bool isIntentIn() {
189+
auto attrs = getFortranAttrs();
190+
return attrs && bitEnumContainsAny(*attrs,
191+
fir::FortranVariableFlagsEnum::intent_in);
192+
}
193+
180194
/// Interface verifier imlementation for declare operations.
181195
mlir::LogicalResult verifyDeclareLikeOpImpl(mlir::Value memRef);
182196

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,26 @@ ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) {
239239
return result;
240240
}
241241

242+
AliasAnalysis::Source::Attributes
243+
getAttrsFromVariable(fir::FortranVariableOpInterface var) {
244+
AliasAnalysis::Source::Attributes attrs;
245+
if (var.isTarget())
246+
attrs.set(AliasAnalysis::Attribute::Target);
247+
if (var.isPointer())
248+
attrs.set(AliasAnalysis::Attribute::Pointer);
249+
if (var.isIntentIn())
250+
attrs.set(AliasAnalysis::Attribute::IntentIn);
251+
252+
return attrs;
253+
}
254+
242255
AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
243256
auto *defOp = v.getDefiningOp();
244257
SourceKind type{SourceKind::Unknown};
245258
mlir::Type ty;
246259
bool breakFromLoop{false};
247260
bool approximateSource{false};
248-
bool followBoxAddr{false};
261+
bool followBoxAddr{mlir::isa<fir::BaseBoxType>(v.getType())};
249262
mlir::SymbolRefAttr global;
250263
Source::Attributes attributes;
251264
while (defOp && !breakFromLoop) {
@@ -334,6 +347,15 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
334347
})
335348
.Case<hlfir::DeclareOp, fir::DeclareOp>([&](auto op) {
336349
auto varIf = llvm::cast<fir::FortranVariableOpInterface>(defOp);
350+
// While going through a declare operation collect
351+
// the variable attributes from it. Right now, some
352+
// of the attributes are duplicated, e.g. a TARGET dummy
353+
// argument has the target attribute both on its declare
354+
// operation and on the entry block argument.
355+
// In case of host associated use, the declare operation
356+
// is the only carrier of the variable attributes,
357+
// so we have to collect them here.
358+
attributes |= getAttrsFromVariable(varIf);
337359
if (varIf.isHostAssoc()) {
338360
// Do not track past such DeclareOp, because it does not
339361
// currently provide any useful information. The host associated
@@ -364,6 +386,8 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
364386
// because of this limitation, we need to make sure we never return
365387
// MustAlias after going through a designate operation
366388
approximateSource = true;
389+
if (mlir::isa<fir::BaseBoxType>(v.getType()))
390+
followBoxAddr = true;
367391
})
368392
.Default([&](auto op) {
369393
defOp = nullptr;

flang/test/Analysis/AliasAnalysis/alias-analysis-6.fir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))'
1+
// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' 2>&1 | FileCheck %s
22

33
// CHECK: test_y(1)#0 <-> test_x(1)#0: MayAlias
44
func.func @_QPtest(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {fir.bindc_name = "y"}) {
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' 2>&1 | FileCheck %s
2+
3+
// leslie3d case with two allocatable module variables
4+
// that cannot alias:
5+
// module les3d_data
6+
// implicit real*8 (a-h,o-z)
7+
// integer imax, jmax, kmax
8+
// double precision,allocatable,dimension(:,:,:,:,:) :: q
9+
// double precision,allocatable,dimension(:,:,:,:) :: du
10+
// end module les3d_data
11+
// subroutine update()
12+
// use les3d_data
13+
// implicit real*8(a-h,o-z)
14+
// i2 = imax - 1
15+
// do k = 1, kmax - 1
16+
// do j = 1, jmax - 1
17+
// q(1:i2,j,k,1,m) = (q(1:i2,j,k,1,m) + du(1:i2,j,k,1))
18+
// end do
19+
// end do
20+
// end subroutine update
21+
22+
// CHECK: allocatable_mod1#0 <-> allocatable_mod2#0: NoAlias
23+
func.func @_QPupdate() {
24+
%c1 = arith.constant 1 : index
25+
%c0 = arith.constant 0 : index
26+
%c1_i32 = arith.constant 1 : i32
27+
%0 = fir.address_of(@_QMles3d_dataEdu) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
28+
%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>>>>)
29+
%2 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QFupdateEi2"}
30+
%3:2 = hlfir.declare %2 {uniq_name = "_QFupdateEi2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
31+
%4 = fir.address_of(@_QMles3d_dataEimax) : !fir.ref<i32>
32+
%5:2 = hlfir.declare %4 {uniq_name = "_QMles3d_dataEimax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
33+
%6 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFupdateEj"}
34+
%7:2 = hlfir.declare %6 {uniq_name = "_QFupdateEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
35+
%8 = fir.address_of(@_QMles3d_dataEjmax) : !fir.ref<i32>
36+
%9:2 = hlfir.declare %8 {uniq_name = "_QMles3d_dataEjmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
37+
%10 = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFupdateEk"}
38+
%11:2 = hlfir.declare %10 {uniq_name = "_QFupdateEk"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
39+
%12 = fir.address_of(@_QMles3d_dataEkmax) : !fir.ref<i32>
40+
%13:2 = hlfir.declare %12 {uniq_name = "_QMles3d_dataEkmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
41+
%14 = fir.alloca i32 {bindc_name = "m", uniq_name = "_QFupdateEm"}
42+
%15:2 = hlfir.declare %14 {uniq_name = "_QFupdateEm"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
43+
%16 = fir.address_of(@_QMles3d_dataEq) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
44+
%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>>>>)
45+
%18 = fir.load %5#0 : !fir.ref<i32>
46+
%19 = arith.subi %18, %c1_i32 : i32
47+
hlfir.assign %19 to %3#0 : i32, !fir.ref<i32>
48+
%20 = fir.load %13#0 : !fir.ref<i32>
49+
%21 = arith.subi %20, %c1_i32 : i32
50+
%22 = fir.convert %21 : (i32) -> index
51+
%23 = fir.convert %c1 : (index) -> i32
52+
%24:2 = fir.do_loop %arg0 = %c1 to %22 step %c1 iter_args(%arg1 = %23) -> (index, i32) {
53+
fir.store %arg1 to %11#1 : !fir.ref<i32>
54+
%25 = fir.load %9#0 : !fir.ref<i32>
55+
%26 = arith.subi %25, %c1_i32 : i32
56+
%27 = fir.convert %26 : (i32) -> index
57+
%28:2 = fir.do_loop %arg2 = %c1 to %27 step %c1 iter_args(%arg3 = %23) -> (index, i32) {
58+
fir.store %arg3 to %7#1 : !fir.ref<i32>
59+
%32 = fir.load %17#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
60+
%33 = fir.load %3#0 : !fir.ref<i32>
61+
%34 = fir.convert %33 : (i32) -> index
62+
%35 = arith.cmpi sgt, %34, %c0 : index
63+
%36 = arith.select %35, %34, %c0 : index
64+
%37 = fir.load %7#0 : !fir.ref<i32>
65+
%38 = fir.convert %37 : (i32) -> i64
66+
%39 = fir.load %11#0 : !fir.ref<i32>
67+
%40 = fir.convert %39 : (i32) -> i64
68+
%41 = fir.load %15#0 : !fir.ref<i32>
69+
%42 = fir.convert %41 : (i32) -> i64
70+
%43 = fir.shape %36 : (index) -> !fir.shape<1>
71+
%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>>
72+
%45 = fir.load %1#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
73+
%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>>
74+
%47 = hlfir.elemental %43 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf64> {
75+
^bb0(%arg4: index):
76+
%51 = hlfir.designate %44 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
77+
%52 = hlfir.designate %46 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
78+
%53 = fir.load %51 : !fir.ref<f64>
79+
%54 = fir.load %52 : !fir.ref<f64>
80+
%55 = arith.addf %53, %54 fastmath<fast> : f64
81+
%56 = hlfir.no_reassoc %55 : f64
82+
hlfir.yield_element %56 : f64
83+
}
84+
hlfir.assign %47 to %44 : !hlfir.expr<?xf64>, !fir.box<!fir.array<?xf64>>
85+
hlfir.destroy %47 : !hlfir.expr<?xf64>
86+
%48 = arith.addi %arg2, %c1 : index
87+
%49 = fir.load %7#1 : !fir.ref<i32>
88+
%50 = arith.addi %49, %23 : i32
89+
fir.result %48, %50 : index, i32
90+
}
91+
fir.store %28#1 to %7#1 : !fir.ref<i32>
92+
%29 = arith.addi %arg0, %c1 : index
93+
%30 = fir.load %11#1 : !fir.ref<i32>
94+
%31 = arith.addi %30, %23 : i32
95+
fir.result %29, %31 : index, i32
96+
}
97+
fir.store %24#1 to %11#1 : !fir.ref<i32>
98+
return
99+
}

flang/test/Analysis/AliasAnalysis/alias-analysis-host-assoc.fir

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,7 @@ func.func @_QFtest8Pinner(%arg0: !fir.ref<tuple<!fir.box<!fir.array<10xi32>>>> {
297297
// end subroutine inner
298298
// end subroutine test9
299299

300-
// FIXME: 'g' is classified as Indirect access leading to a conservative reply:
301-
// CHECK: test9_g(1)#0 <-> test9_x(1)#0: MayAlias
300+
// CHECK: test9_g(1)#0 <-> test9_x(1)#0: NoAlias
302301
func.func @_QFtest9Pinner(%arg0: !fir.ref<tuple<!fir.box<!fir.array<10xi32>>>> {fir.host_assoc}) attributes {fir.internal_proc} {
303302
%0 = fir.address_of(@_QMglobalsEg) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
304303
%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>>>>)
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// RUN: fir-opt --opt-bufferization %s | FileCheck %s
2+
3+
// leslie3d case with two allocatable module variables
4+
// that cannot alias:
5+
// module les3d_data
6+
// implicit real*8 (a-h,o-z)
7+
// integer imax, jmax, kmax
8+
// double precision,allocatable,dimension(:,:,:,:,:) :: q
9+
// double precision,allocatable,dimension(:,:,:,:) :: du
10+
// end module les3d_data
11+
// subroutine update()
12+
// use les3d_data
13+
// implicit real*8(a-h,o-z)
14+
// i2 = imax - 1
15+
// do k = 1, kmax - 1
16+
// do j = 1, jmax - 1
17+
// q(1:i2,j,k,1,m) = (q(1:i2,j,k,1,m) + du(1:i2,j,k,1))
18+
// end do
19+
// end do
20+
// end subroutine update
21+
22+
func.func @_QPupdate() {
23+
%c1 = arith.constant 1 : index
24+
%c0 = arith.constant 0 : index
25+
%c1_i32 = arith.constant 1 : i32
26+
%0 = fir.address_of(@_QMles3d_dataEdu) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
27+
%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>>>>)
28+
%2 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QFupdateEi2"}
29+
%3:2 = hlfir.declare %2 {uniq_name = "_QFupdateEi2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
30+
%4 = fir.address_of(@_QMles3d_dataEimax) : !fir.ref<i32>
31+
%5:2 = hlfir.declare %4 {uniq_name = "_QMles3d_dataEimax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
32+
%6 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFupdateEj"}
33+
%7:2 = hlfir.declare %6 {uniq_name = "_QFupdateEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
34+
%8 = fir.address_of(@_QMles3d_dataEjmax) : !fir.ref<i32>
35+
%9:2 = hlfir.declare %8 {uniq_name = "_QMles3d_dataEjmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
36+
%10 = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFupdateEk"}
37+
%11:2 = hlfir.declare %10 {uniq_name = "_QFupdateEk"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
38+
%12 = fir.address_of(@_QMles3d_dataEkmax) : !fir.ref<i32>
39+
%13:2 = hlfir.declare %12 {uniq_name = "_QMles3d_dataEkmax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
40+
%14 = fir.alloca i32 {bindc_name = "m", uniq_name = "_QFupdateEm"}
41+
%15:2 = hlfir.declare %14 {uniq_name = "_QFupdateEm"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
42+
%16 = fir.address_of(@_QMles3d_dataEq) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
43+
%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>>>>)
44+
%18 = fir.load %5#0 : !fir.ref<i32>
45+
%19 = arith.subi %18, %c1_i32 : i32
46+
hlfir.assign %19 to %3#0 : i32, !fir.ref<i32>
47+
%20 = fir.load %13#0 : !fir.ref<i32>
48+
%21 = arith.subi %20, %c1_i32 : i32
49+
%22 = fir.convert %21 : (i32) -> index
50+
%23 = fir.convert %c1 : (index) -> i32
51+
%24:2 = fir.do_loop %arg0 = %c1 to %22 step %c1 iter_args(%arg1 = %23) -> (index, i32) {
52+
fir.store %arg1 to %11#1 : !fir.ref<i32>
53+
%25 = fir.load %9#0 : !fir.ref<i32>
54+
%26 = arith.subi %25, %c1_i32 : i32
55+
%27 = fir.convert %26 : (i32) -> index
56+
%28:2 = fir.do_loop %arg2 = %c1 to %27 step %c1 iter_args(%arg3 = %23) -> (index, i32) {
57+
fir.store %arg3 to %7#1 : !fir.ref<i32>
58+
%32 = fir.load %17#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>>
59+
%33 = fir.load %3#0 : !fir.ref<i32>
60+
%34 = fir.convert %33 : (i32) -> index
61+
%35 = arith.cmpi sgt, %34, %c0 : index
62+
%36 = arith.select %35, %34, %c0 : index
63+
%37 = fir.load %7#0 : !fir.ref<i32>
64+
%38 = fir.convert %37 : (i32) -> i64
65+
%39 = fir.load %11#0 : !fir.ref<i32>
66+
%40 = fir.convert %39 : (i32) -> i64
67+
%41 = fir.load %15#0 : !fir.ref<i32>
68+
%42 = fir.convert %41 : (i32) -> i64
69+
%43 = fir.shape %36 : (index) -> !fir.shape<1>
70+
%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>>
71+
%45 = fir.load %1#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?x?xf64>>>>
72+
%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>>
73+
%47 = hlfir.elemental %43 unordered : (!fir.shape<1>) -> !hlfir.expr<?xf64> {
74+
^bb0(%arg4: index):
75+
%51 = hlfir.designate %44 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
76+
%52 = hlfir.designate %46 (%arg4) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
77+
%53 = fir.load %51 : !fir.ref<f64>
78+
%54 = fir.load %52 : !fir.ref<f64>
79+
%55 = arith.addf %53, %54 fastmath<fast> : f64
80+
%56 = hlfir.no_reassoc %55 : f64
81+
hlfir.yield_element %56 : f64
82+
}
83+
hlfir.assign %47 to %44 : !hlfir.expr<?xf64>, !fir.box<!fir.array<?xf64>>
84+
hlfir.destroy %47 : !hlfir.expr<?xf64>
85+
%48 = arith.addi %arg2, %c1 : index
86+
%49 = fir.load %7#1 : !fir.ref<i32>
87+
%50 = arith.addi %49, %23 : i32
88+
fir.result %48, %50 : index, i32
89+
}
90+
fir.store %28#1 to %7#1 : !fir.ref<i32>
91+
%29 = arith.addi %arg0, %c1 : index
92+
%30 = fir.load %11#1 : !fir.ref<i32>
93+
%31 = arith.addi %30, %23 : i32
94+
fir.result %29, %31 : index, i32
95+
}
96+
fir.store %24#1 to %11#1 : !fir.ref<i32>
97+
return
98+
}
99+
// CHECK-LABEL: func.func @_QPupdate() {
100+
// CHECK-NOT: hlfir.assign {{.*}}!fir.box<!fir.array<?xf64>>
101+
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f64, !fir.ref<f64>
102+
// CHECK-NOT: hlfir.assign {{.*}}!fir.box<!fir.array<?xf64>>

flang/test/HLFIR/opt-variable-assign.fir

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func.func @_QPtest4(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>> {f
185185
// CHECK-NOT: hlfir.assign
186186

187187

188-
// TODO: LHS is a pointer, but RHS is a subroutine local,
188+
// LHS is a pointer, but RHS is a subroutine local,
189189
// so they cannot alias.
190190
func.func @_QPtest5(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fir.bindc_name = "x"}) {
191191
%c0 = arith.constant 0 : index
@@ -220,13 +220,13 @@ func.func @_QPtest5(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fi
220220
}
221221
// CHECK-LABEL: func.func @_QPtest5(
222222
// CHECK-NOT: hlfir.assign
223-
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.ref<!fir.array<3x3xf32>>, !fir.box<!fir.array<?x?xf32>>
223+
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
224224
// CHECK-NOT: hlfir.assign
225-
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.ref<!fir.array<3x3xf32>>, !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
225+
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
226226
// CHECK-NOT: hlfir.assign
227227

228228

229-
// TODO: RHS is a pointer, but LHS is a subroutine local,
229+
// RHS is a pointer, but LHS is a subroutine local,
230230
// so they cannot alias.
231231
func.func @_QPtest6(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fir.bindc_name = "x"}) {
232232
%c1 = arith.constant 1 : index
@@ -261,20 +261,14 @@ func.func @_QPtest6(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fi
261261
}
262262
// CHECK-LABEL: func.func @_QPtest6(
263263
// CHECK-NOT: hlfir.assign
264-
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<3x3xf32>>
264+
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
265265
// CHECK-NOT: hlfir.assign
266-
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.box<!fir.ptr<!fir.array<?x?xf32>>>, !fir.ref<!fir.array<3x3xf32>>
266+
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
267267
// CHECK-NOT: hlfir.assign
268268

269269

270-
// TODO: LHS and RHS do not alias, and the assignment cannot
270+
// LHS and RHS do not alias, and the assignment cannot
271271
// allocate/reallocate LHS, so we should be able to optimize.
272-
// The box load blocks alias analysis.
273-
// subroutine test7(x)
274-
// real, allocatable :: x(:,:)
275-
// real :: y(3,3)
276-
// x(:,:) = y(:,:)
277-
// end subroutine test7
278272
func.func @_QPtest7(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>> {fir.bindc_name = "x"}) {
279273
%c0 = arith.constant 0 : index
280274
%c1 = arith.constant 1 : index
@@ -305,4 +299,6 @@ func.func @_QPtest7(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>> {f
305299
return
306300
}
307301
// CHECK-LABEL: func.func @_QPtest7(
308-
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : !fir.ref<!fir.array<3x3xf32>>, !fir.box<!fir.array<?x?xf32>>
302+
// CHECK-NOT: hlfir.assign
303+
// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32>
304+
// CHECK-NOT: hlfir.assign

0 commit comments

Comments
 (0)