Skip to content

Commit e4c95cb

Browse files
SC llvm teamSC llvm team
SC llvm team
authored and
SC llvm team
committed
Merged main:9df0568b0733 into amd-gfx:e66d351d8224
Local branch amd-gfx e66d351 Merged main:f6038cdca031 into amd-gfx:528f4a3febe9 Remote branch main 9df0568 [SLP] Fix crash caused by reorderBottomToTop().
2 parents e66d351 + 9df0568 commit e4c95cb

File tree

20 files changed

+858
-151
lines changed

20 files changed

+858
-151
lines changed

compiler-rt/lib/scudo/standalone/memtag.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@
1818

1919
namespace scudo {
2020

21+
#if (__clang_major__ >= 12 && defined(__aarch64__) && !defined(__ILP32__)) || \
22+
defined(SCUDO_FUZZ)
23+
2124
// We assume that Top-Byte Ignore is enabled if the architecture supports memory
2225
// tagging. Not all operating systems enable TBI, so we only claim architectural
2326
// support for memory tagging if the operating system enables TBI.
2427
// HWASan uses the top byte for its own purpose and Scudo should not touch it.
25-
#if (__clang_major__ >= 12 && defined(__aarch64__) && !defined(__ILP32__) && \
26-
SCUDO_LINUX && \
27-
!defined(SCUDO_DISABLE_TBI) !__has_feature(hwaddress_sanitizer)) || \
28-
defined(SCUDO_FUZZ)
29-
28+
#if SCUDO_LINUX && !defined(SCUDO_DISABLE_TBI) && \
29+
!__has_feature(hwaddress_sanitizer)
3030
inline constexpr bool archSupportsMemoryTagging() { return true; }
31+
#else
32+
inline constexpr bool archSupportsMemoryTagging() { return false; }
33+
#endif
3134

3235
inline constexpr uptr archMemoryTagGranuleSize() { return 16; }
3336

flang/include/flang/Lower/BoxAnalyzer.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ inline bool isExplicitShape(const Fortran::semantics::Symbol &sym) {
236236
return det && det->IsArray() && det->shape().IsExplicitShape();
237237
}
238238

239+
inline bool isAssumedSize(const Fortran::semantics::Symbol &sym) {
240+
return Fortran::semantics::IsAssumedSizeArray(sym.GetUltimate());
241+
}
242+
239243
//===----------------------------------------------------------------------===//
240244
// Perform analysis to determine a box's parameter values
241245
//===----------------------------------------------------------------------===//
@@ -378,7 +382,7 @@ class BoxAnalyzer : public fir::details::matcher<BoxAnalyzer> {
378382
/// Run the analysis on `sym`.
379383
void analyze(const Fortran::semantics::Symbol &sym) {
380384
if (symIsArray(sym)) {
381-
bool isConstant = true;
385+
bool isConstant = !isAssumedSize(sym);
382386
llvm::SmallVector<int64_t> lbounds;
383387
llvm::SmallVector<int64_t> shapes;
384388
llvm::SmallVector<const Fortran::semantics::ShapeSpec *> bounds;
@@ -396,6 +400,8 @@ class BoxAnalyzer : public fir::details::matcher<BoxAnalyzer> {
396400
continue;
397401
}
398402
} else if (subs.ubound().isStar()) {
403+
assert(Fortran::semantics::IsNamedConstant(sym) &&
404+
"expect implied shape constant");
399405
shapes.push_back(fir::SequenceType::getUnknownExtent());
400406
continue;
401407
}

flang/include/flang/Lower/PFTBuilder.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,6 @@ struct FunctionLikeUnit : public ProgramUnit {
668668
entryPointList{std::pair{nullptr, nullptr}};
669669
/// Current index into entryPointList. Index 0 is the primary entry point.
670670
int activeEntry = 0;
671-
/// Dummy arguments that are not universal across entry points.
672-
llvm::SmallVector<const semantics::Symbol *, 1> nonUniversalDummyArguments;
673671
/// Primary result for function subprograms with alternate entries. This
674672
/// is one of the largest result values, not necessarily the first one.
675673
const semantics::Symbol *primaryResult{nullptr};

flang/lib/Lower/Bridge.cpp

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,19 +2392,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
23922392
for (const Fortran::lower::CalleeInterface::PassedEntity &arg :
23932393
callee.getPassedArguments())
23942394
mapPassedEntity(arg);
2395-
2396-
// Allocate local skeleton instances of dummies from other entry points.
2397-
// Most of these locals will not survive into final generated code, but
2398-
// some will. It is illegal to reference them at run time if they do.
2399-
for (const Fortran::semantics::Symbol *arg :
2400-
funit.nonUniversalDummyArguments) {
2401-
if (lookupSymbol(*arg))
2402-
continue;
2403-
mlir::Type type = genType(*arg);
2404-
// TODO: Account for VALUE arguments (and possibly other variants).
2405-
type = builder->getRefType(type);
2406-
addSymbol(*arg, builder->create<fir::UndefOp>(toLocation(), type));
2407-
}
24082395
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
24092396
passedResult = callee.getPassedResult()) {
24102397
mapPassedEntity(*passedResult);
@@ -2491,15 +2478,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
24912478
}
24922479
}
24932480

2494-
// If this is a host procedure with host associations, then create the tuple
2495-
// of pointers for passing to the internal procedures.
2496-
if (!funit.getHostAssoc().empty())
2497-
funit.getHostAssoc().hostProcedureBindings(*this, localSymbols);
2498-
2499-
/// TODO: should use same mechanism as equivalence?
2500-
/// One blocking point is character entry returns that need special handling
2501-
/// since they are not locally allocated but come as argument. CHARACTER(*)
2502-
/// is not something that fit wells with equivalence lowering.
2481+
// TODO: should use same mechanism as equivalence?
2482+
// One blocking point is character entry returns that need special handling
2483+
// since they are not locally allocated but come as argument. CHARACTER(*)
2484+
// is not something that fits well with equivalence lowering.
25032485
for (const Fortran::lower::pft::Variable &altResult :
25042486
deferredFuncResultList) {
25052487
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
@@ -2510,6 +2492,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
25102492
stmtCtx, primaryFuncResultStorage);
25112493
}
25122494

2495+
// If this is a host procedure with host associations, then create the tuple
2496+
// of pointers for passing to the internal procedures.
2497+
if (!funit.getHostAssoc().empty())
2498+
funit.getHostAssoc().hostProcedureBindings(*this, localSymbols);
2499+
25132500
// Create most function blocks in advance.
25142501
createEmptyBlocks(funit.evaluationList);
25152502

flang/lib/Lower/ConvertType.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ struct TypeBuilder {
225225
// links, the fir type is built based on the ultimate symbol. This relies
226226
// on the fact volatile and asynchronous are not reflected in fir types.
227227
const Fortran::semantics::Symbol &ultimate = symbol.GetUltimate();
228+
if (Fortran::semantics::IsProcedurePointer(ultimate))
229+
TODO(loc, "procedure pointers");
228230
if (const Fortran::semantics::DeclTypeSpec *type = ultimate.GetType()) {
229231
if (const Fortran::semantics::IntrinsicTypeSpec *tySpec =
230232
type->AsIntrinsic()) {

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter,
122122
// symbol is an object of a function pointer.
123123
const Fortran::semantics::Symbol &ultimate = sym.GetUltimate();
124124
if (!ultimate.has<Fortran::semantics::ObjectEntityDetails>() &&
125-
!ultimate.has<Fortran::semantics::ProcEntityDetails>())
125+
!Fortran::semantics::IsProcedurePointer(ultimate))
126126
mlir::emitError(loc, "lowering global declaration: symbol '")
127127
<< toStringRef(sym.name()) << "' has unexpected details\n";
128128
return builder.createGlobal(loc, converter.genType(var), globalName, linkage,
@@ -378,6 +378,10 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
378378

379379
if (global && globalIsInitialized(global))
380380
return global;
381+
382+
if (Fortran::semantics::IsProcedurePointer(sym))
383+
TODO(loc, "procedure pointer globals");
384+
381385
// If this is an array, check to see if we can use a dense attribute
382386
// with a tensor mlir type. This optimization currently only supports
383387
// rank-1 Fortran arrays of integer, real, or logical. The tensor
@@ -1187,11 +1191,10 @@ static mlir::Value genExtentValue(fir::FirOpBuilder &builder,
11871191
}
11881192

11891193
/// Lower specification expressions and attributes of variable \p var and
1190-
/// add it to the symbol map.
1191-
/// For global and aliases, the address must be pre-computed and provided
1192-
/// in \p preAlloc.
1193-
/// Dummy arguments must have already been mapped to mlir block arguments
1194-
/// their mapping may be updated here.
1194+
/// add it to the symbol map. For a global or an alias, the address must be
1195+
/// pre-computed and provided in \p preAlloc. A dummy argument for the current
1196+
/// entry point has already been mapped to an mlir block argument in
1197+
/// mapDummiesAndResults. Its mapping may be updated here.
11951198
void Fortran::lower::mapSymbolAttributes(
11961199
AbstractConverter &converter, const Fortran::lower::pft::Variable &var,
11971200
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx,
@@ -1200,14 +1203,32 @@ void Fortran::lower::mapSymbolAttributes(
12001203
const Fortran::semantics::Symbol &sym = var.getSymbol();
12011204
const mlir::Location loc = converter.genLocation(sym.name());
12021205
mlir::IndexType idxTy = builder.getIndexType();
1203-
const bool isDummy = Fortran::semantics::IsDummy(sym);
1206+
const bool isDeclaredDummy = Fortran::semantics::IsDummy(sym);
1207+
// An active dummy from the current entry point.
1208+
const bool isDummy = isDeclaredDummy && symMap.lookupSymbol(sym).getAddr();
1209+
// An unused dummy from another entry point.
1210+
const bool isUnusedEntryDummy = isDeclaredDummy && !isDummy;
12041211
const bool isResult = Fortran::semantics::IsFunctionResult(sym);
12051212
const bool replace = isDummy || isResult;
12061213
fir::factory::CharacterExprHelper charHelp{builder, loc};
1214+
1215+
if (Fortran::semantics::IsProcedure(sym)) {
1216+
if (isUnusedEntryDummy) {
1217+
// Additional discussion below.
1218+
mlir::Type dummyProcType =
1219+
Fortran::lower::getDummyProcedureType(sym, converter);
1220+
mlir::Value undefOp = builder.create<fir::UndefOp>(loc, dummyProcType);
1221+
symMap.addSymbol(sym, undefOp);
1222+
}
1223+
if (Fortran::semantics::IsPointer(sym))
1224+
TODO(loc, "procedure pointers");
1225+
return;
1226+
}
1227+
12071228
Fortran::lower::BoxAnalyzer ba;
12081229
ba.analyze(sym);
12091230

1210-
// First deal with pointers an allocatables, because their handling here
1231+
// First deal with pointers and allocatables, because their handling here
12111232
// is the same regardless of their rank.
12121233
if (Fortran::semantics::IsAllocatableOrPointer(sym)) {
12131234
// Get address of fir.box describing the entity.
@@ -1263,6 +1284,42 @@ void Fortran::lower::mapSymbolAttributes(
12631284
}
12641285
}
12651286

1287+
// A dummy from another entry point that is not declared in the current
1288+
// entry point requires a skeleton definition. Most such "unused" dummies
1289+
// will not survive into final generated code, but some will. It is illegal
1290+
// to reference one at run time if it does. Such a dummy is mapped to a
1291+
// value in one of three ways:
1292+
//
1293+
// - Generate a fir::UndefOp value. This is lightweight, easy to clean up,
1294+
// and often valid, but it may fail for a dummy with dynamic bounds,
1295+
// or a dummy used to define another dummy. Information to distinguish
1296+
// valid cases is not generally available here, with the exception of
1297+
// dummy procedures. See the first function exit above.
1298+
//
1299+
// - Allocate an uninitialized stack slot. This is an intermediate-weight
1300+
// solution that is harder to clean up. It is often valid, but may fail
1301+
// for an object with dynamic bounds. This option is "automatically"
1302+
// used by default for cases that do not use one of the other options.
1303+
//
1304+
// - Allocate a heap box/descriptor, initialized to zero. This always
1305+
// works, but is more heavyweight and harder to clean up. It is used
1306+
// for dynamic objects via calls to genUnusedEntryPointBox.
1307+
1308+
auto genUnusedEntryPointBox = [&]() {
1309+
if (isUnusedEntryDummy) {
1310+
assert(!Fortran::semantics::IsAllocatableOrPointer(sym) &&
1311+
"handled above");
1312+
// The box is read right away because lowering code does not expect
1313+
// a non pointer/allocatable symbol to be mapped to a MutableBox.
1314+
symMap.addSymbol(sym, fir::factory::genMutableBoxRead(
1315+
builder, loc,
1316+
fir::factory::createTempMutableBox(
1317+
builder, loc, converter.genType(var))));
1318+
return true;
1319+
}
1320+
return false;
1321+
};
1322+
12661323
// Helper to generate scalars for the symbol properties.
12671324
auto genValue = [&](const Fortran::lower::SomeExpr &expr) {
12681325
return genScalarValue(converter, loc, expr, symMap, stmtCtx);
@@ -1412,24 +1469,17 @@ void Fortran::lower::mapSymbolAttributes(
14121469
//===--------------------------------------------------------------===//
14131470

14141471
[&](const Fortran::lower::details::ScalarDynamicChar &x) {
1472+
if (genUnusedEntryPointBox())
1473+
return;
14151474
// type is a CHARACTER, determine the LEN value
14161475
auto charLen = x.charLen();
14171476
if (replace) {
14181477
Fortran::lower::SymbolBox symBox = symMap.lookupSymbol(sym);
14191478
mlir::Value boxAddr = symBox.getAddr();
14201479
mlir::Value len;
14211480
mlir::Type addrTy = boxAddr.getType();
1422-
if (addrTy.isa<fir::BoxCharType>() || addrTy.isa<fir::BoxType>()) {
1481+
if (addrTy.isa<fir::BoxCharType>() || addrTy.isa<fir::BoxType>())
14231482
std::tie(boxAddr, len) = charHelp.createUnboxChar(symBox.getAddr());
1424-
} else {
1425-
// dummy from an other entry case: we cannot get a dynamic length
1426-
// for it, it's illegal for the user program to use it. However,
1427-
// since we are lowering all function unit statements regardless
1428-
// of whether the execution will reach them or not, we need to
1429-
// fill a value for the length here.
1430-
len = builder.createIntegerConstant(
1431-
loc, builder.getCharacterLengthType(), 1);
1432-
}
14331483
// Override LEN with an expression
14341484
if (charLen)
14351485
len = genExplicitCharLen(charLen);
@@ -1484,6 +1534,8 @@ void Fortran::lower::mapSymbolAttributes(
14841534
//===--------------------------------------------------------------===//
14851535

14861536
[&](const Fortran::lower::details::DynamicArray &x) {
1537+
if (genUnusedEntryPointBox())
1538+
return;
14871539
// cast to the known constant parts from the declaration
14881540
mlir::Type varType = converter.genType(var);
14891541
mlir::Value addr = symMap.lookupSymbol(sym).getAddr();
@@ -1587,6 +1639,8 @@ void Fortran::lower::mapSymbolAttributes(
15871639
//===--------------------------------------------------------------===//
15881640

15891641
[&](const Fortran::lower::details::StaticArrayDynamicChar &x) {
1642+
if (genUnusedEntryPointBox())
1643+
return;
15901644
mlir::Value addr;
15911645
mlir::Value len;
15921646
[[maybe_unused]] bool mustBeDummy = false;
@@ -1656,6 +1710,8 @@ void Fortran::lower::mapSymbolAttributes(
16561710
//===--------------------------------------------------------------===//
16571711

16581712
[&](const Fortran::lower::details::DynamicArrayStaticChar &x) {
1713+
if (genUnusedEntryPointBox())
1714+
return;
16591715
mlir::Value addr;
16601716
mlir::Value len;
16611717
mlir::Value argBox;
@@ -1714,6 +1770,8 @@ void Fortran::lower::mapSymbolAttributes(
17141770
//===--------------------------------------------------------------===//
17151771

17161772
[&](const Fortran::lower::details::DynamicArrayDynamicChar &x) {
1773+
if (genUnusedEntryPointBox())
1774+
return;
17171775
mlir::Value addr;
17181776
mlir::Value len;
17191777
mlir::Value argBox;

0 commit comments

Comments
 (0)