Skip to content

Commit df5a2fe

Browse files
committed
[flang][TBAA] understand common blocks containing TARGET
TARGET variables inside of a common block will be added under the TARGET tree instead of the global tree so that they alias with all pointers. This means that the common block root cannot be used to alias with the whole common block, but I don't think that is used anywhere.
1 parent 9a1a6ae commit df5a2fe

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

flang/lib/Optimizer/Transforms/AddAliasTags.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -717,18 +717,10 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
717717
LLVM_DEBUG(llvm::dbgs().indent(2)
718718
<< "Found reference to global " << globalName.str() << " at "
719719
<< *op << "\n");
720-
if (source.isPointer()) {
721-
// Pointers can alias with any pointer or target.
722-
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
723-
} else if (source.isTarget()) {
724-
// Targets could alias with any pointer but not with each other.
725-
tag = state.getFuncTreeWithScope(func, scopeOp)
726-
.targetDataTree.getTag(globalName);
727-
} else {
728-
// In general, place the tags under the "global data" root.
729-
fir::TBAATree::SubtreeState *subTree =
730-
&state.getMutableFuncTreeWithScope(func, scopeOp).globalDataTree;
731720

721+
// Add a named tag inside the given subtree, disambiguating members of a
722+
// common block
723+
auto addTagUsingStorageDesc = [&](fir::TBAATree::SubtreeState *subTree) {
732724
mlir::Operation *instantiationPoint = source.origin.instantiationPoint;
733725
auto storageIface =
734726
mlir::dyn_cast_or_null<fir::FortranVariableStorageOpInterface>(
@@ -773,6 +765,19 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
773765
LLVM_DEBUG(llvm::dbgs()
774766
<< "Tagged under '" << globalName << "' root\n");
775767
}
768+
};
769+
770+
if (source.isPointer()) {
771+
// Pointers can alias with any pointer or target.
772+
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
773+
} else if (source.isTarget()) {
774+
// Targets could alias with any pointer but not with each other.
775+
addTagUsingStorageDesc(
776+
&state.getMutableFuncTreeWithScope(func, scopeOp).targetDataTree);
777+
} else {
778+
// In general, place the tags under the "global data" root.
779+
addTagUsingStorageDesc(
780+
&state.getMutableFuncTreeWithScope(func, scopeOp).globalDataTree);
776781
}
777782

778783
// TBAA for global variables with descriptors

flang/test/Transforms/tbaa-for-common-vars.fir

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,52 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr = dense<64> : vector<4
427427
// CHECK: fir.load %{{[0-9]+}} {tbaa = [#[[$ATTR_86]]]} : !fir.ptr<f32>
428428
// CHECK: fir.load %{{[0-9]+}} : !fir.ref<i32>
429429
// CHECK: fir.store %{{[0-9]+}} to %{{[0-9]+}} : !fir.ref<f32>
430+
431+
// -----
432+
433+
// Fortran source:
434+
// subroutine target_comon_tbaa()
435+
// real :: a
436+
// real, target :: b, c
437+
// common /common1/ a,b,c
438+
// a = b
439+
// end subroutine
440+
//
441+
// Test generation of tbaa tags where some members of a common block are TARGET
442+
module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, i64 = dense<[32, 64]> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little">, llvm.data_layout = ""} { fir.global common @block_(dense<0> : vector<44xi8>) {alignment = 4 : i64} : !fir.array<44xi8>
443+
fir.global common @common1_(dense<0> : vector<12xi8>) {alignment = 4 : i64} : !fir.array<12xi8>
444+
func.func @_QPtarget_common_tbaa() {
445+
%c8 = arith.constant 8 : index
446+
%c4 = arith.constant 4 : index
447+
%c0 = arith.constant 0 : index
448+
%0 = fir.dummy_scope : !fir.dscope
449+
%1 = fir.address_of(@common1_) : !fir.ref<!fir.array<12xi8>>
450+
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<12xi8>>, index) -> !fir.ref<i8>
451+
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<f32>
452+
%4 = fir.declare %3 storage(%1[0]) {uniq_name = "_QFtarget_comon_tbaaEa"} : (!fir.ref<f32>, !fir.ref<!fir.array<12xi8>>) -> !fir.ref<f32>
453+
%5 = fir.coordinate_of %1, %c4 : (!fir.ref<!fir.array<12xi8>>, index) -> !fir.ref<i8>
454+
%6 = fir.convert %5 : (!fir.ref<i8>) -> !fir.ref<f32>
455+
%7 = fir.declare %6 storage(%1[4]) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtarget_comon_tbaaEb"} : (!fir.ref<f32>, !fir.ref<!fir.array<12xi8>>) -> !fir.ref<f32>
456+
%8 = fir.coordinate_of %1, %c8 : (!fir.ref<!fir.array<12xi8>>, index) -> !fir.ref<i8>
457+
%9 = fir.convert %8 : (!fir.ref<i8>) -> !fir.ref<f32>
458+
%10 = fir.declare %9 storage(%1[8]) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtarget_comon_tbaaEc"} : (!fir.ref<f32>, !fir.ref<!fir.array<12xi8>>) -> !fir.ref<f32>
459+
%11 = fir.load %7 : !fir.ref<f32>
460+
fir.store %11 to %4 : !fir.ref<f32>
461+
return
462+
}
463+
}
464+
// CHECK: #[[TBAA_FUNC_ROOT:.*]] = #llvm.tbaa_root<id = "Flang function root _QPtarget_common_tbaa">
465+
// CHECK-NEXT: #[[ANY_ACCESS:.*]] = #llvm.tbaa_type_desc<id = "any access", members = {<#[[TBAA_FUNC_ROOT]], 0>}>
466+
// CHECK-NEXT: #[[ANY_DATA:.*]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#[[ANY_ACCESS]], 0>}>
467+
// CHECK-NEXT: #[[TARGET_DATA:.*]] = #llvm.tbaa_type_desc<id = "target data", members = {<#[[ANY_DATA]], 0>}>
468+
// CHECK-NEXT: #[[GLOBAL_DATA:.*]] = #llvm.tbaa_type_desc<id = "global data", members = {<#[[ANY_DATA]], 0>}>
469+
// CHECK-NEXT: #[[TARGET_COMMON:.*]] = #llvm.tbaa_type_desc<id = "target data/common1_", members = {<#[[TARGET_DATA]], 0>}>
470+
// CHECK-NEXT: #[[GLOBAL_COMMON:.*]] = #llvm.tbaa_type_desc<id = "global data/common1_", members = {<#[[GLOBAL_DATA]], 0>}>
471+
// CHECK-NEXT: #[[B:.*]] = #llvm.tbaa_type_desc<id = "target data/common1_/bytes_4_to_7", members = {<#[[TARGET_COMMON]], 0>}>
472+
// CHECK-NEXT: #[[A:.*]] = #llvm.tbaa_type_desc<id = "global data/common1_/bytes_0_to_3", members = {<#[[GLOBAL_COMMON]], 0>}>
473+
// CHECK-NEXT: #[[B_TAG:.*]] = #llvm.tbaa_tag<base_type = #[[B]], access_type = #[[B]], offset = 0>
474+
// CHECK-NEXT: #[[A_TAG:.*]] = #llvm.tbaa_tag<base_type = #[[A]], access_type = #[[A]], offset = 0>
475+
476+
// CHECK-LABEL: func.func @_QPtarget_common_tbaa()
477+
// CHECK: %[[LOAD:.*]] = fir.load %{{.*}} {tbaa = [#[[B_TAG]]]}
478+
// CHECK: fir.store %[[LOAD]] to %{{.*}} {tbaa = [#[[A_TAG]]]}

0 commit comments

Comments
 (0)