Skip to content

Commit cfe8ae3

Browse files
authored
[flang] TBAA for memory accesses of derived type values. (llvm#68047)
Since HLFIR bufferization can introduce shallow copies of derived type values we have to be careful not to treat these load/store operations as data-only-accesses. If a derived type has descriptor members, we attach any-access tag now.
1 parent f857bef commit cfe8ae3

File tree

5 files changed

+66
-2
lines changed

5 files changed

+66
-2
lines changed

flang/include/flang/Optimizer/CodeGen/TBAABuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ class TBAABuilder {
188188
// Returns TBAATagAttr representing access tag:
189189
// < <any data access>, <any data access>, 0 >
190190
mlir::LLVM::TBAATagAttr getAnyDataAccessTag();
191+
// Returns TBAATagAttr representing access tag:
192+
// < <any access>, <any access>, 0 >
193+
mlir::LLVM::TBAATagAttr getAnyAccessTag();
191194

192195
// Returns TBAATagAttr representing access tag described by the base and
193196
// access FIR types and the LLVM::GepOp representing the access in terms of

flang/include/flang/Optimizer/Dialect/FIRType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ mlir::Type unwrapInnerType(mlir::Type ty);
349349
/// Return true iff `ty` is a RecordType with members that are allocatable.
350350
bool isRecordWithAllocatableMember(mlir::Type ty);
351351

352+
/// Return true iff `ty` is a scalar/array of RecordType
353+
/// with members that are descriptors.
354+
bool isRecordWithDescriptorMember(mlir::Type ty);
355+
352356
/// Return true iff `ty` is a RecordType with type parameters.
353357
inline bool isRecordWithTypeParameters(mlir::Type ty) {
354358
if (auto recTy = ty.dyn_cast_or_null<fir::RecordType>())

flang/lib/Optimizer/CodeGen/TBAABuilder.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ TBAATagAttr TBAABuilder::getDataAccessTag(Type baseFIRType, Type accessFIRType,
9292
return getAnyDataAccessTag();
9393
}
9494

95+
TBAATagAttr TBAABuilder::getAnyAccessTag() {
96+
return getAccessTag(anyAccessTypeDesc, anyAccessTypeDesc, /*offset=*/0);
97+
}
98+
9599
void TBAABuilder::attachTBAATag(AliasAnalysisOpInterface op, Type baseFIRType,
96100
Type accessFIRType, GEPOp gep) {
97101
if (!enableTBAA)
@@ -106,10 +110,17 @@ void TBAABuilder::attachTBAATag(AliasAnalysisOpInterface op, Type baseFIRType,
106110
<< "\n");
107111

108112
TBAATagAttr tbaaTagSym;
109-
if (baseFIRType.isa<fir::BaseBoxType>())
113+
if (fir::isRecordWithDescriptorMember(baseFIRType)) {
114+
// A memory access that addresses an aggregate that contains
115+
// a mix of data members and descriptor members may alias
116+
// with both data and descriptor accesses.
117+
// Conservatively set any-access tag if there is any descriptor member.
118+
tbaaTagSym = getAnyAccessTag();
119+
} else if (baseFIRType.isa<fir::BaseBoxType>()) {
110120
tbaaTagSym = getBoxAccessTag(baseFIRType, accessFIRType, gep);
111-
else
121+
} else {
112122
tbaaTagSym = getDataAccessTag(baseFIRType, accessFIRType, gep);
123+
}
113124

114125
if (!tbaaTagSym)
115126
return;

flang/lib/Optimizer/Dialect/FIRType.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,18 @@ bool isRecordWithAllocatableMember(mlir::Type ty) {
360360
return false;
361361
}
362362

363+
bool isRecordWithDescriptorMember(mlir::Type ty) {
364+
ty = unwrapSequenceType(ty);
365+
if (auto recTy = ty.dyn_cast<fir::RecordType>())
366+
for (auto [field, memTy] : recTy.getTypeList()) {
367+
if (mlir::isa<fir::BaseBoxType>(memTy))
368+
return true;
369+
if (memTy.isa<fir::RecordType>() && isRecordWithDescriptorMember(memTy))
370+
return true;
371+
}
372+
return false;
373+
}
374+
363375
mlir::Type unwrapAllRefAndSeqType(mlir::Type ty) {
364376
while (true) {
365377
mlir::Type nt = unwrapSequenceType(unwrapRefType(ty));

flang/test/Fir/tbaa.fir

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,37 @@ func.func @tbaa(%arg0: !fir.box<!fir.array<?xi32>>) {
351351
// CHECK: %[[VAL_14:.*]] = llvm.bitcast %[[VAL_13]] : !llvm.ptr<i8> to !llvm.ptr<i32>
352352
// CHECK: llvm.return
353353
// CHECK: }
354+
355+
// -----
356+
357+
// Check that the scalar aggregate load/store with a descriptor member
358+
// is mapped to any-access.
359+
// CHECK-DAG: #[[ROOT:.*]] = #llvm.tbaa_root<id = "Flang Type TBAA Root">
360+
// CHECK-DAG: #[[ANYACC:.*]] = #llvm.tbaa_type_desc<id = "any access", members = {<#[[ROOT]], 0>}>
361+
// CHECK-DAG: #[[$ANYT:.*]] = #llvm.tbaa_tag<base_type = #[[ANYACC]], access_type = #[[ANYACC]], offset = 0>
362+
363+
func.func @tbaa(%arg0: !fir.ref<!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>, %arg1: !fir.ref<!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>) {
364+
%0 = fir.load %arg0 : !fir.ref<!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>
365+
fir.store %0 to %arg1 : !fir.ref<!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>
366+
return
367+
}
368+
// CHECK-LABEL: llvm.func @tbaa(
369+
// CHECK: llvm.load{{.*}}{tbaa = [#[[$ANYT]]]}
370+
// CHECK: llvm.store{{.*}}{tbaa = [#[[$ANYT]]]}
371+
372+
// -----
373+
374+
// Check that the array aggregate load/store with a descriptor member
375+
// is mapped to any-access.
376+
// CHECK-DAG: #[[ROOT:.*]] = #llvm.tbaa_root<id = "Flang Type TBAA Root">
377+
// CHECK-DAG: #[[ANYACC:.*]] = #llvm.tbaa_type_desc<id = "any access", members = {<#[[ROOT]], 0>}>
378+
// CHECK-DAG: #[[$ANYT:.*]] = #llvm.tbaa_tag<base_type = #[[ANYACC]], access_type = #[[ANYACC]], offset = 0>
379+
380+
func.func @tbaa(%arg0: !fir.ref<!fir.array<2x!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>>, %arg1: !fir.ref<!fir.array<2x!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>>) {
381+
%0 = fir.load %arg0 : !fir.ref<!fir.array<2x!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>>
382+
fir.store %0 to %arg1 : !fir.ref<!fir.array<2x!fir.type<_QMtypesTt{x:!fir.box<!fir.heap<f32>>}>>>
383+
return
384+
}
385+
// CHECK-LABEL: llvm.func @tbaa(
386+
// CHECK: llvm.load{{.*}}{tbaa = [#[[$ANYT]]]}
387+
// CHECK: llvm.store{{.*}}{tbaa = [#[[$ANYT]]]}

0 commit comments

Comments
 (0)