Skip to content

Commit e72e5fe

Browse files
jdenny-ornlYutongZhuu
authored andcommitted
[flang] AliasAnalysis: Handle fir.load on fir.alloca (llvm#117785)
For example, determine that the address in p below cannot alias the address of v: ``` subroutine test() real, pointer :: p real, target :: t real :: v p => t v = p end subroutine test ```
1 parent 64bfec9 commit e72e5fe

File tree

3 files changed

+441
-17
lines changed

3 files changed

+441
-17
lines changed

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

+20-11
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,22 @@ static bool hasGlobalOpTargetAttr(mlir::Value v, fir::AddrOfOp op) {
5151
v, fir::GlobalOp::getTargetAttrName(globalOpName));
5252
}
5353

54-
static mlir::Value getOriginalDef(mlir::Value v) {
54+
static mlir::Value
55+
getOriginalDef(mlir::Value v,
56+
fir::AliasAnalysis::Source::Attributes &attributes,
57+
bool &isCapturedInInternalProcedure) {
5558
mlir::Operation *defOp;
5659
bool breakFromLoop = false;
5760
while (!breakFromLoop && (defOp = v.getDefiningOp())) {
5861
llvm::TypeSwitch<Operation *>(defOp)
5962
.Case<fir::ConvertOp>([&](fir::ConvertOp op) { v = op.getValue(); })
60-
.Case<fir::DeclareOp, hlfir::DeclareOp>(
61-
[&](auto op) { v = op.getMemref(); })
63+
.Case<fir::DeclareOp, hlfir::DeclareOp>([&](auto op) {
64+
v = op.getMemref();
65+
auto varIf = llvm::cast<fir::FortranVariableOpInterface>(defOp);
66+
attributes |= getAttrsFromVariable(varIf);
67+
isCapturedInInternalProcedure |=
68+
varIf.isCapturedInInternalProcedure();
69+
})
6270
.Default([&](auto op) { breakFromLoop = true; });
6371
}
6472
return v;
@@ -600,7 +608,8 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
600608
if (mlir::isa<fir::PointerType>(boxTy.getEleTy()))
601609
attributes.set(Attribute::Pointer);
602610

603-
auto def = getOriginalDef(op.getMemref());
611+
auto def = getOriginalDef(op.getMemref(), attributes,
612+
isCapturedInInternalProcedure);
604613
if (auto addrOfOp = def.template getDefiningOp<fir::AddrOfOp>()) {
605614
global = addrOfOp.getSymbol();
606615

@@ -609,13 +618,13 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
609618

610619
type = SourceKind::Global;
611620
}
612-
613-
// TODO: Add support to fir.alloca and fir.allocmem
614-
// if (auto allocOp = def.template getDefiningOp<fir::AllocaOp>()) {
615-
// ...
616-
// }
617-
618-
if (isDummyArgument(def)) {
621+
// TODO: Add support to fir.allocmem
622+
else if (auto allocOp =
623+
def.template getDefiningOp<fir::AllocaOp>()) {
624+
v = def;
625+
defOp = v.getDefiningOp();
626+
type = SourceKind::Allocate;
627+
} else if (isDummyArgument(def)) {
619628
defOp = nullptr;
620629
v = def;
621630
}

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

+9-6
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
// They cannot physically alias
99
// CHECK-DAG: p1.addr#0 <-> p2.addr#0: NoAlias
1010

11-
// p1.addr and p2.addr could both be wrapped inside boxes
12-
// CHECK-DAG: p1.addr#0 <-> boxp1.addr#0: MayAlias
13-
// CHECK-DAG: p2.addr#0 <-> boxp1.addr#0: MayAlias
11+
// p1.addr is the address returned by an alloca. It does not have a target
12+
// attribute, and it is not the address retrieved from a pointer. It cannot
13+
// alias anything. Likewise for p2.addr.
14+
// CHECK-DAG: p1.addr#0 <-> boxp1.addr#0: NoAlias
15+
// CHECK-DAG: p2.addr#0 <-> boxp1.addr#0: NoAlias
1416

1517
// TODO: To really see aliasing, we should be looking at a load of p1.addr
1618
// p1.addr is just a local address holding the address to the data
@@ -27,10 +29,11 @@
2729
// CHECK-DAG: p2.addr#0 <-> func.region0#2: NoAlias
2830

2931
// All arguments are either pointers or targets
30-
// A pointer in a box may alias with both
32+
// The address *in* a local pointer may alias the address of a target
33+
// argument, but it does not alias the address *of* a pointer argument.
3134
// CHECK-DAG: boxp1.addr#0 <-> func.region0#0: MayAlias
3235
// CHECK-DAG: boxp1.addr#0 <-> func.region0#1: MayAlias
33-
// CHECK-DAG: boxp1.addr#0 <-> func.region0#2: MayAlias
36+
// CHECK-DAG: boxp1.addr#0 <-> func.region0#2: NoAlias
3437

3538
// A target dummy may alias with another target
3639
// CHECK-DAG: func.region0#0 <-> func.region0#1: MayAlias
@@ -54,7 +57,7 @@
5457

5558
// The addresses stored in two different pointers can alias, even if one has no
5659
// box. In this program, they happen to be the same address.
57-
// T4:
60+
// T4 from <https://github.com/llvm/llvm-project/pull/117785#discussion_r1924348480>.
5861
// CHECK-DAG: p1.tgt#0 <-> boxp1.addr#0: MayAlias
5962

6063
func.func @_QFPtest(%arg0: !fir.ref<f32> {fir.bindc_name = "v1", fir.target}, %arg1: !fir.ref<f32> {fir.bindc_name = "v2", fir.target}, %arg2: !fir.ref<!fir.box<!fir.ptr<f32>>> ) attributes {test.ptr = "func"} {

0 commit comments

Comments
 (0)