Skip to content

Commit 33fcfb3

Browse files
authored
[flang][TBAA] refine TARGET/POINTER encoding (#170908)
Depends upon #170900 Re-land #169544 Previously we were less specific for POINTER/TARGET: encoding that they could alias with (almost) anything. In the new system, the "target data" tree is now a sibling of the other trees (e.g. "global data"). POITNTER variables go at the root of the "target data" tree, whereas TARGET variables get their own nodes under that tree. For example, ``` integer, pointer :: ip real, pointer :: rp integer, target :: it integer, target :: it2(:) real, target :: rt integer :: i real :: r ``` - `ip` and `rp` may alias with any variable except `i` and `r`. - `it`, `it2`, and `rt` may alias only with `ip` or `rp`. - `i` and `r` cannot alias with any other variable. Fortran 2023 15.5.2.14 gives restrictions on entities associated with dummy arguments. These do not allow non-target globals to be modified through dummy arguments and therefore I don't think we need to make all globals alias with dummy arguments. I haven't implemented it in this patch, but I wonder whether it is ever possible for `ip` to alias with `rt`. While I was updating the tests I fixed up some tests that still assumed that local alloc tbaa wasn't the default. Cray pointers/pointees are (optionally) modelled as aliasing with all non-descriptor data. This is not enabled by default. I found no functional regressions in the gfortran test suite.
1 parent 86f8445 commit 33fcfb3

File tree

14 files changed

+285
-170
lines changed

14 files changed

+285
-170
lines changed

flang/include/flang/Optimizer/Analysis/TBAAForest.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,25 @@ struct TBAATree {
9999
// |- "any data access"
100100
// |
101101
// |- "dummy arg data"
102-
// |- "target data"
103-
// |
104-
// |- "allocated data"
105-
// |- "direct data"
106-
// |- "global data"
102+
// |
103+
// |- <dummy arg name 1>
104+
// |- <dummy arg name 2>
105+
// |- "target data" <-- Any POINTER variable or TARGET dummy arg
106+
// |
107+
// |- <target name 1> <--- any TARGET variable which isn't a dummy arg
108+
// |- <target name 2>
109+
// |- "allocated data"
110+
// |
111+
// |- <allocated name 1>
112+
// |- <allocated name 2>
113+
// |- "direct data"
114+
// |
115+
// |- <direct name 1>
116+
// |- <direct name 2>
117+
// |- "global data"
118+
// |
119+
// |- <global name 1>
120+
// |- <global name 2>
107121
static TBAATree buildTree(mlir::StringAttr functionName);
108122

109123
private:

flang/lib/Optimizer/Analysis/TBAAForest.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,9 @@ fir::TBAATree::TBAATree(mlir::LLVM::TBAATypeDescriptorAttr anyAccess,
6666
mlir::LLVM::TBAATypeDescriptorAttr dataRoot,
6767
mlir::LLVM::TBAATypeDescriptorAttr boxMemberTypeDesc)
6868
: targetDataTree(dataRoot.getContext(), "target data", dataRoot),
69-
globalDataTree(dataRoot.getContext(), "global data",
70-
targetDataTree.getRoot()),
71-
allocatedDataTree(dataRoot.getContext(), "allocated data",
72-
targetDataTree.getRoot()),
69+
globalDataTree(dataRoot.getContext(), "global data", dataRoot),
70+
allocatedDataTree(dataRoot.getContext(), "allocated data", dataRoot),
7371
dummyArgDataTree(dataRoot.getContext(), "dummy arg data", dataRoot),
74-
directDataTree(dataRoot.getContext(), "direct data",
75-
targetDataTree.getRoot()),
72+
directDataTree(dataRoot.getContext(), "direct data", dataRoot),
7673
anyAccessDesc(anyAccess), boxMemberTypeDesc(boxMemberTypeDesc),
7774
anyDataTypeDesc(dataRoot) {}

flang/lib/Optimizer/Transforms/AddAliasTags.cpp

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ static llvm::cl::opt<unsigned> localAllocsThreshold(
6060
llvm::cl::desc("If present, stops generating TBAA tags for accesses of "
6161
"local allocations after N accesses in a module"));
6262

63+
// Defined in AliasAnalysis.cpp
64+
extern llvm::cl::opt<bool> supportCrayPointers;
65+
6366
namespace {
6467

6568
// Return the size and alignment (in bytes) for the given type.
@@ -668,6 +671,7 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
668671
LLVM_DEBUG(llvm::dbgs() << "Analysing " << op << "\n");
669672

670673
const fir::AliasAnalysis::Source &source = state.getSource(memref);
674+
LLVM_DEBUG(llvm::dbgs() << "Got source " << source << "\n");
671675

672676
// Process the scopes, if not processed yet.
673677
state.processFunctionScopes(func);
@@ -686,14 +690,22 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
686690
}
687691

688692
mlir::LLVM::TBAATagAttr tag;
689-
// TBAA for dummy arguments
690-
if (enableDummyArgs &&
691-
source.kind == fir::AliasAnalysis::SourceKind::Argument) {
693+
// Cray pointer/pointee is a special case. These might alias with any data.
694+
if (supportCrayPointers && source.isCrayPointerOrPointee()) {
695+
LLVM_DEBUG(llvm::dbgs().indent(2)
696+
<< "Found reference to Cray pointer/pointee at " << *op << "\n");
697+
mlir::LLVM::TBAATypeDescriptorAttr anyDataDesc =
698+
state.getFuncTreeWithScope(func, scopeOp).anyDataTypeDesc;
699+
tag = mlir::LLVM::TBAATagAttr::get(anyDataDesc, anyDataDesc, /*offset=*/0);
700+
// TBAA for dummy arguments
701+
} else if (enableDummyArgs &&
702+
source.kind == fir::AliasAnalysis::SourceKind::Argument) {
692703
LLVM_DEBUG(llvm::dbgs().indent(2)
693704
<< "Found reference to dummy argument at " << *op << "\n");
694705
std::string name = getFuncArgName(llvm::cast<mlir::Value>(source.origin.u));
695-
// If it is a TARGET or POINTER, then we do not care about the name,
696-
// because the tag points to the root of the subtree currently.
706+
// POINTERS can alias with any POINTER or TARGET. Assume that TARGET dummy
707+
// arguments might alias with each other (because of the "TARGET" hole for
708+
// dummy arguments). See flang/docs/Aliasing.md.
697709
if (source.isTargetOrPointer()) {
698710
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
699711
} else if (!name.empty()) {
@@ -715,13 +727,10 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
715727
LLVM_DEBUG(llvm::dbgs().indent(2)
716728
<< "Found reference to global " << globalName.str() << " at "
717729
<< *op << "\n");
718-
if (source.isPointer()) {
719-
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
720-
} else {
721-
// In general, place the tags under the "global data" root.
722-
fir::TBAATree::SubtreeState *subTree =
723-
&state.getMutableFuncTreeWithScope(func, scopeOp).globalDataTree;
724730

731+
// Add a named tag inside the given subtree, disambiguating members of a
732+
// common block
733+
auto addTagUsingStorageDesc = [&](fir::TBAATree::SubtreeState *subTree) {
725734
mlir::Operation *instantiationPoint = source.origin.instantiationPoint;
726735
auto storageIface =
727736
mlir::dyn_cast_or_null<fir::FortranVariableStorageOpInterface>(
@@ -766,6 +775,19 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
766775
LLVM_DEBUG(llvm::dbgs()
767776
<< "Tagged under '" << globalName << "' root\n");
768777
}
778+
};
779+
780+
if (source.isPointer()) {
781+
// Pointers can alias with any pointer or target.
782+
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
783+
} else if (source.isTarget()) {
784+
// Targets could alias with any pointer but not with each other.
785+
addTagUsingStorageDesc(
786+
&state.getMutableFuncTreeWithScope(func, scopeOp).targetDataTree);
787+
} else {
788+
// In general, place the tags under the "global data" root.
789+
addTagUsingStorageDesc(
790+
&state.getMutableFuncTreeWithScope(func, scopeOp).globalDataTree);
769791
}
770792

771793
// TBAA for global variables with descriptors
@@ -776,9 +798,17 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
776798
const char *name = glbl.getRootReference().data();
777799
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to direct " << name
778800
<< " at " << *op << "\n");
801+
// Pointer can alias with any pointer or target so that gets the root.
779802
if (source.isPointer())
780803
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
804+
// Targets could alias with any pointer but not with each other so they
805+
// get their own node inside of the target data tree.
806+
else if (source.isTarget())
807+
tag = state.getFuncTreeWithScope(func, scopeOp)
808+
.targetDataTree.getTag(name);
781809
else
810+
// Boxes that are not pointers or targets cannot alias with those that
811+
// are. Put them under global data.
782812
tag = state.getFuncTreeWithScope(func, scopeOp)
783813
.directDataTree.getTag(name);
784814
} else {
@@ -815,8 +845,13 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
815845
<< "\n");
816846
} else if (source.isPointer() && state.attachLocalAllocTag()) {
817847
LLVM_DEBUG(llvm::dbgs().indent(2)
818-
<< "Found reference to allocation at " << *op << "\n");
848+
<< "Found reference to POINTER allocation at " << *op << "\n");
819849
tag = state.getFuncTreeWithScope(func, scopeOp).targetDataTree.getTag();
850+
} else if (source.isTarget() && state.attachLocalAllocTag()) {
851+
LLVM_DEBUG(llvm::dbgs().indent(2)
852+
<< "Found reference to TARGET allocation at " << *op << "\n");
853+
tag = state.getFuncTreeWithScope(func, scopeOp)
854+
.targetDataTree.getTag(*name);
820855
} else if (name && state.attachLocalAllocTag()) {
821856
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to allocation "
822857
<< name << " at " << *op << "\n");

flang/test/Driver/tco-test-gen.fir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ func.func @_QPtest(%arg0: !fir.ref<i32> {fir.bindc_name = "num"}, %arg1: !fir.re
7777
// CHECK: llvm.cond_br %[[VAL_17]], ^bb2, ^bb3
7878
// CHECK: ^bb2:
7979

80-
// AA: llvm.store %[[VAL_15]], %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : i32, !llvm.ptr
80+
// AA: llvm.store %[[VAL_15]], %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : i32, !llvm.ptr
8181
// NOAA: llvm.store %[[VAL_15]], %{{.*}} : i32, !llvm.ptr
8282

8383
// AA: %[[VAL_18:.*]] = llvm.load %[[ARG0]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "dummy arg data/_QFtestEnum", members = {<#llvm.tbaa_type_desc<id = "dummy arg data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "dummy arg data/_QFtestEnum", members = {<#llvm.tbaa_type_desc<id = "dummy arg data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : !llvm.ptr -> i32
8484
// NOAA: %[[VAL_18:.*]] = llvm.load %[[ARG0]] : !llvm.ptr -> i32
8585

86-
// AA: %[[VAL_19:.*]] = llvm.load %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : !llvm.ptr -> i32
86+
// AA: %[[VAL_19:.*]] = llvm.load %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : !llvm.ptr -> i32
8787
// NOAA: %[[VAL_19:.*]] = llvm.load %{{.*}} : !llvm.ptr -> i32
8888

8989
// CHECK: %[[VAL_20:.*]] = llvm.add %[[VAL_18]], %[[VAL_19]] : i32
@@ -92,15 +92,15 @@ func.func @_QPtest(%arg0: !fir.ref<i32> {fir.bindc_name = "num"}, %arg1: !fir.re
9292

9393
// CHECK: %[[VAL_21:.*]] = llvm.trunc %[[VAL_10]] : i64 to i32
9494

95-
// AA: %[[VAL_22:.*]] = llvm.load %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : !llvm.ptr -> i32
95+
// AA: %[[VAL_22:.*]] = llvm.load %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : !llvm.ptr -> i32
9696
// NOAA: %[[VAL_22:.*]] = llvm.load %{{.*}} : !llvm.ptr -> i32
9797

9898
// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_22]], %[[VAL_21]] overflow<nsw> : i32
9999
// CHECK: %[[VAL_24:.*]] = llvm.sub %[[VAL_16]], %{{.*}} : i64
100100
// CHECK: llvm.br ^bb1(%[[VAL_23]], %[[VAL_24]] : i32, i64)
101101
// CHECK: ^bb3:
102102

103-
// AA: llvm.store %[[VAL_15]], %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "target data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : i32, !llvm.ptr
103+
// AA: llvm.store %[[VAL_15]], %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : i32, !llvm.ptr
104104
// NOAA: llvm.store %[[VAL_15]], %{{.*}} : i32, !llvm.ptr
105105

106106
// CHECK: llvm.return

flang/test/Fir/tbaa-codegen2.fir

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,3 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
114114
// CHECK: ![[TMP_DATA_ACCESS_TAG]] = !{![[TMP_DATA_ACCESS_TYPE:.*]], ![[TMP_DATA_ACCESS_TYPE]], i64 0}
115115
// CHECK: ![[TMP_DATA_ACCESS_TYPE]] = !{!"allocated data/", ![[TMP_ACCESS_TYPE:.*]], i64 0}
116116
// CHECK: ![[TMP_ACCESS_TYPE]] = !{!"allocated data", ![[TARGET_ACCESS_TAG:.*]], i64 0}
117-
// CHECK: ![[TARGET_ACCESS_TAG]] = !{!"target data", ![[DATA_ACCESS_TYPE]], i64 0}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: fir-opt -funsafe-cray-pointers --fir-add-alias-tags %s | FileCheck %s
2+
3+
// Fortran source:
4+
// subroutine test()
5+
// real :: a, b
6+
// pointer(p, a)
7+
// p = loc(b)
8+
// b = 2
9+
// end subroutine
10+
11+
// CHECK: #[[TBAA_ROOT:.*]] = #llvm.tbaa_root<id = "Flang function root _QPtest">
12+
// CHECK-NEXT: #[[ANY_ACCESS:.*]] = #llvm.tbaa_type_desc<id = "any access", members = {<#[[TBAA_ROOT]], 0>}>
13+
// CHECK-NEXT: #[[ANY_DATA:.*]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#[[ANY_ACCESS]], 0>}>
14+
// CHECK-NEXT: #[[ANY_DATA_TAG:.*]] = #llvm.tbaa_tag<base_type = #[[ANY_DATA]], access_type = #[[ANY_DATA]], offset = 0>
15+
// CHECK-NEXT: #[[ALLOCATED_DATA:.*]] = #llvm.tbaa_type_desc<id = "allocated data", members = {<#[[ANY_DATA]], 0>}>
16+
// CHECK-NEXT: #[[B:.*]] = #llvm.tbaa_type_desc<id = "allocated data/_QFtestEb", members = {<#[[ALLOCATED_DATA]], 0>}>
17+
// CHECK-NEXT: #[[B_TAG:.*]] = #llvm.tbaa_tag<base_type = #[[B]], access_type = #[[B]], offset = 0>
18+
19+
module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i8 = dense<[8, 32]> : vector<2xi64>, i16 = dense<[16, 32]> : vector<2xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 32, 64>, "dlti.stack_alignment" = 128 : i64, "dlti.function_pointer_alignment" = #dlti.function_pointer_alignment<32, function_dependent = true>>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"} {
20+
// CHECK-LABEL: func.func @_QPtest()
21+
func.func @_QPtest() {
22+
%cst = arith.constant 2.000000e+00 : f32
23+
%0 = fir.alloca !fir.box<!fir.ptr<f32>>
24+
%1 = fir.dummy_scope : !fir.dscope
25+
%2 = fir.alloca i64 {bindc_name = "p", uniq_name = "_QFtestEp"}
26+
%3 = fir.declare %2 {fortran_attrs = #fir.var_attrs<cray_pointer>, uniq_name = "_QFtestEp"} : (!fir.ref<i64>) -> !fir.ref<i64>
27+
%4 = fir.alloca f32 {bindc_name = "b", uniq_name = "_QFtestEb"}
28+
%5 = fir.declare %4 {uniq_name = "_QFtestEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
29+
%6 = fir.declare %0 {fortran_attrs = #fir.var_attrs<pointer, cray_pointee>, uniq_name = "_QFtestEa"} : (!fir.ref<!fir.box<!fir.ptr<f32>>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
30+
%7 = fir.zero_bits !fir.ptr<f32>
31+
%8 = fir.embox %7 : (!fir.ptr<f32>) -> !fir.box<!fir.ptr<f32>>
32+
fir.store %8 to %6 : !fir.ref<!fir.box<!fir.ptr<f32>>>
33+
// Descriptor tagged in codegen
34+
// CHECK: fir.store %{{.*}} to %{{.*}} : !fir.ref<!fir.box<!fir.ptr<f32>>
35+
%9 = fir.convert %5 : (!fir.ref<f32>) -> i64
36+
fir.store %9 to %3 : !fir.ref<i64>
37+
// CHECK: fir.store {{.*}} to {{.*}} {tbaa = [#[[ANY_DATA_TAG]]]} : !fir.ref<i64>
38+
fir.store %cst to %5 : !fir.ref<f32>
39+
// CHECK: fir.store {{.*}} to {{.*}} {tbaa = [#[[B_TAG]]]} : !fir.ref<f32>
40+
return
41+
}
42+
}
43+

0 commit comments

Comments
 (0)