diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp --- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp +++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp @@ -10,6 +10,7 @@ #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/Dialect/FIROpsSupport.h" #include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/HLFIR/HLFIROps.h" #include "mlir/Analysis/AliasAnalysis.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Value.h" @@ -228,6 +229,11 @@ global = llvm::cast(op).getSymbol(); breakFromLoop = true; }) + .Case([&](auto op) { + // Track further through the operand + v = op.getMemref(); + defOp = v.getDefiningOp(); + }) .Default([&](auto op) { defOp = nullptr; breakFromLoop = true; diff --git a/flang/lib/Optimizer/Analysis/CMakeLists.txt b/flang/lib/Optimizer/Analysis/CMakeLists.txt --- a/flang/lib/Optimizer/Analysis/CMakeLists.txt +++ b/flang/lib/Optimizer/Analysis/CMakeLists.txt @@ -8,6 +8,7 @@ LINK_LIBS FIRBuilder FIRDialect + HLFIRDialect MLIRFuncDialect MLIRLLVMDialect MLIRMathTransforms diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-2.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-2.fir --- a/flang/test/Analysis/AliasAnalysis/alias-analysis-2.fir +++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-2.fir @@ -171,3 +171,90 @@ %13 = fir.box_addr %6 {test.ptr = "box.addr"} : (!fir.box>) -> !fir.ptr return } + +// ----- + +// CHECK-LABEL: Testing : "_QFPtest4" + +// Same as test3 but check that the alias analysis can follow (hl)fir.declare +// operations + +// CHECK-DAG: p#0 <-> func.region0#0: MayAlias +// CHECK-DAG: p_fir#0 <-> func.region0#0: MayAlias +// CHECK-DAG: p_hlfir#0 <-> func.region0#0: MayAlias +// CHECK-DAG: p_hlfir#1 <-> func.region0#0: MayAlias + +// CHECK-DAG: p#0 <-> func.region0#1: NoAlias +// CHECK-DAG: p_fir#0 <-> func.region0#1: NoAlias +// CHECK-DAG: p_hlfir#0 <-> func.region0#1: NoAlias +// CHECK-DAG: p_hlfir#1 <-> func.region0#1: NoAlias + +// CHECK-DAG: var2#0 <-> p#0: NoAlias +// CHECK-DAG: var2#0 <-> p_fir#0: NoAlias +// CHECK-DAG: var2#0 <-> p_hlfir#0: NoAlias +// CHECK-DAG: var2#0 <-> p_hlfir#1: NoAlias +// CHECK-DAG: var2_fir#0 <-> p#0: NoAlias +// CHECK-DAG: var2_fir#0 <-> p_fir#0: NoAlias +// CHECK-DAG: var2_fir#0 <-> p_hlfir#0: NoAlias +// CHECK-DAG: var2_fir#0 <-> p_hlfir#1: NoAlias +// CHECK-DAG: var2_hlfir#0 <-> p#0: NoAlias +// CHECK-DAG: var2_hlfir#0 <-> p_fir#0: NoAlias +// CHECK-DAG: var2_hlfir#0 <-> p_hlfir#0: NoAlias +// CHECK-DAG: var2_hlfir#0 <-> p_hlfir#1: NoAlias +// CHECK-DAG: var2_hlfir#1 <-> p#0: NoAlias +// CHECK-DAG: var2_hlfir#1 <-> p_fir#0: NoAlias +// CHECK-DAG: var2_hlfir#1 <-> p_hlfir#0: NoAlias +// CHECK-DAG: var2_hlfir#1 <-> p_hlfir#1: NoAlias + +// CHECK-DAG: var2#0 <-> func.region0#0: MayAlias +// CHECK-DAG: var2_fir#0 <-> func.region0#0: MayAlias +// CHECK-DAG: var2_hlfir#0 <-> func.region0#0: MayAlias +// CHECK-DAG: var2_hlfir#1 <-> func.region0#0: MayAlias + +// CHECK-DAG: var2#0 <-> box.addr#0: MustAlias +// CHECK-DAG: var2#0 <-> box.addr_fir#0: MustAlias +// CHECK-DAG: var2#0 <-> box.addr_hlfir#0: MustAlias +// CHECK-DAG: var2#0 <-> box.addr_hlfir#1: MustAlias +// CHECK-DAG: var2_fir#0 <-> box.addr#0: MustAlias +// CHECK-DAG: var2_fir#0 <-> box.addr_fir#0: MustAlias +// CHECK-DAG: var2_fir#0 <-> box.addr_hlfir#0: MustAlias +// CHECK-DAG: var2_fir#0 <-> box.addr_hlfir#1: MustAlias +// CHECK-DAG: var2_hlfir#0 <-> box.addr#0: MustAlias +// CHECK-DAG: var2_hlfir#0 <-> box.addr_fir#0: MustAlias +// CHECK-DAG: var2_hlfir#0 <-> box.addr_hlfir#0: MustAlias +// CHECK-DAG: var2_hlfir#0 <-> box.addr_hlfir#1: MustAlias +// CHECK-DAG: var2_hlfir#1 <-> box.addr#0: MustAlias +// CHECK-DAG: var2_hlfir#1 <-> box.addr_fir#0: MustAlias +// CHECK-DAG: var2_hlfir#1 <-> box.addr_hlfir#0: MustAlias +// CHECK-DAG: var2_hlfir#1 <-> box.addr_hlfir#1: MustAlias + +// CHECK-DAG: var2#0 <-> func.region0#1: NoAlias +// CHECK-DAG: var2_fir#0 <-> func.region0#1: NoAlias +// CHECK-DAG: var2_hlfir#0 <-> func.region0#1: NoAlias +// CHECK-DAG: var2_hlfir#1 <-> func.region0#1: NoAlias + +// CHECK-DAG: func.region0#0 <-> func.region0#1: NoAlias + +fir.global @_QMpointersEp : !fir.box> { + %0 = fir.zero_bits !fir.ptr + %1 = fir.embox %0 : (!fir.ptr) -> !fir.box> + fir.has_value %1 : !fir.box> +} + +fir.global internal @_QFEvar2 target : f32 { + %cst = arith.constant 2.000000e+00 : f32 + fir.has_value %cst : f32 +} + +func.func @_QFPtest4(%arg0: !fir.ref>> {fir.bindc_name = "p1"}, %arg1: !fir.ref) attributes {test.ptr = "func"} { + %4 = fir.address_of(@_QFEvar2) {test.ptr = "var2"} : !fir.ref + %fir_decl_var2 = fir.declare %4 {uniq_name = "var2_fir", test.ptr = "var2_fir"}: (!fir.ref) -> !fir.ref + %hlfir_decl_var2:2 = hlfir.declare %4 {uniq_name = "var2_hlfir", test.ptr = "var2_hlfir"}: (!fir.ref) -> (!fir.ref, !fir.ref) + %5 = fir.address_of(@_QMpointersEp) {test.ptr = "p"} : !fir.ref>> + %fir_decl_p = fir.declare %5 {uniq_name = "p_fir", test.ptr = "p_fir"}: (!fir.ref>>) -> !fir.ref>> + %hlfir_decl_p:2 = hlfir.declare %5 {uniq_name = "p_hlfir", test.ptr = "p_hlfir"}: (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) + %13 = fir.convert %4 {test.ptr = "box.addr"} : (!fir.ref) -> !fir.ptr + %fir_decl_convert = fir.declare %13 {uniq_name = "box_addr_fir", test.ptr = "box.addr_fir"}: (!fir.ptr) -> !fir.ptr + %hlfir_decl_convert:2 = hlfir.declare %13 {uniq_name = "box_addr_hlfir", test.ptr = "box.addr_hlfir"}: (!fir.ptr) -> (!fir.ptr, !fir.ptr) + return +}