Skip to content

Commit 181eab2

Browse files
authored
[flang] Set KIND in compiler generated COUNT for SIZE(PACK) (#79801)
Compiler was rewriting SIZE(PACK(x, MASK)) to COUNT(MASK). It was wrapping the COUNT call without a KIND argument (leading to INTEGER(4) result in the characteristics) in an Expr<ExtentType> (implying INTEGER(8) result), this lead to inconsistencies that later hit verifier errors in lowering. Set the KIND argument to the KIND of ExtentType to ensure the built expression is consistent. This requires giving access to some safe place where the "kind" name can be saved and turned into a CharBlock (count has a DIM argument that require using the KIND keyword here). For the FoldingContext that belong to SemanticsContext, this is the same string set as the one used by SemanticsContext for similar purposes.
1 parent db6bf92 commit 181eab2

File tree

9 files changed

+46
-18
lines changed

9 files changed

+46
-18
lines changed

flang/include/flang/Evaluate/common.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "flang/Parser/message.h"
2121
#include <cinttypes>
2222
#include <map>
23+
#include <set>
2324
#include <string>
2425

2526
namespace Fortran::semantics {
@@ -217,26 +218,30 @@ class FoldingContext {
217218
public:
218219
FoldingContext(const common::IntrinsicTypeDefaultKinds &d,
219220
const IntrinsicProcTable &t, const TargetCharacteristics &c,
220-
const common::LanguageFeatureControl &lfc)
221+
const common::LanguageFeatureControl &lfc,
222+
std::set<std::string> &tempNames)
221223
: defaults_{d}, intrinsics_{t}, targetCharacteristics_{c},
222-
languageFeatures_{lfc} {}
224+
languageFeatures_{lfc}, tempNames_{tempNames} {}
223225
FoldingContext(const parser::ContextualMessages &m,
224226
const common::IntrinsicTypeDefaultKinds &d, const IntrinsicProcTable &t,
225-
const TargetCharacteristics &c, const common::LanguageFeatureControl &lfc)
227+
const TargetCharacteristics &c, const common::LanguageFeatureControl &lfc,
228+
std::set<std::string> &tempNames)
226229
: messages_{m}, defaults_{d}, intrinsics_{t}, targetCharacteristics_{c},
227-
languageFeatures_{lfc} {}
230+
languageFeatures_{lfc}, tempNames_{tempNames} {}
228231
FoldingContext(const FoldingContext &that)
229232
: messages_{that.messages_}, defaults_{that.defaults_},
230233
intrinsics_{that.intrinsics_},
231234
targetCharacteristics_{that.targetCharacteristics_},
232235
pdtInstance_{that.pdtInstance_}, impliedDos_{that.impliedDos_},
233-
languageFeatures_{that.languageFeatures_} {}
236+
languageFeatures_{that.languageFeatures_}, tempNames_{that.tempNames_} {
237+
}
234238
FoldingContext(
235239
const FoldingContext &that, const parser::ContextualMessages &m)
236240
: messages_{m}, defaults_{that.defaults_}, intrinsics_{that.intrinsics_},
237241
targetCharacteristics_{that.targetCharacteristics_},
238242
pdtInstance_{that.pdtInstance_}, impliedDos_{that.impliedDos_},
239-
languageFeatures_{that.languageFeatures_} {}
243+
languageFeatures_{that.languageFeatures_}, tempNames_{that.tempNames_} {
244+
}
240245

241246
parser::ContextualMessages &messages() { return messages_; }
242247
const parser::ContextualMessages &messages() const { return messages_; }
@@ -273,6 +278,10 @@ class FoldingContext {
273278
return common::ScopedSet(pdtInstance_, nullptr);
274279
}
275280

281+
parser::CharBlock SaveTempName(std::string &&name) {
282+
return {*tempNames_.emplace(std::move(name)).first};
283+
}
284+
276285
private:
277286
parser::ContextualMessages messages_;
278287
const common::IntrinsicTypeDefaultKinds &defaults_;
@@ -282,6 +291,7 @@ class FoldingContext {
282291
bool inModuleFile_{false};
283292
std::map<parser::CharBlock, ConstantSubscript> impliedDos_;
284293
const common::LanguageFeatureControl &languageFeatures_;
294+
std::set<std::string> &tempNames_;
285295
};
286296

287297
void RealFlagWarnings(FoldingContext &, const RealFlags &, const char *op);

flang/include/flang/Lower/Bridge.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "flang/Optimizer/Builder/FIRBuilder.h"
2222
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
2323
#include "mlir/IR/BuiltinOps.h"
24+
#include <set>
2425

2526
namespace llvm {
2627
class DataLayout;
@@ -111,7 +112,7 @@ class LoweringBridge {
111112
}
112113

113114
/// Create a folding context. Careful: this is very expensive.
114-
Fortran::evaluate::FoldingContext createFoldingContext() const;
115+
Fortran::evaluate::FoldingContext createFoldingContext();
115116

116117
Fortran::semantics::SemanticsContext &getSemanticsContext() const {
117118
return semanticsContext;
@@ -164,6 +165,7 @@ class LoweringBridge {
164165
const Fortran::lower::LoweringOptions &loweringOptions;
165166
const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults;
166167
const Fortran::common::LanguageFeatureControl &languageFeatures;
168+
std::set<std::string> tempNames;
167169
};
168170

169171
} // namespace lower

flang/lib/Evaluate/shape.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -973,9 +973,14 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
973973
}
974974
}
975975
} else {
976-
// Non-scalar MASK= -> [COUNT(mask)]
977-
ActualArguments toCount{ActualArgument{common::Clone(
978-
DEREF(call.arguments().at(1).value().UnwrapExpr()))}};
976+
// Non-scalar MASK= -> [COUNT(mask, KIND=extent_kind)]
977+
ActualArgument kindArg{
978+
AsGenericExpr(Constant<ExtentType>{ExtentType::kind})};
979+
kindArg.set_keyword(context_->SaveTempName("kind"));
980+
ActualArguments toCount{
981+
ActualArgument{common::Clone(
982+
DEREF(call.arguments().at(1).value().UnwrapExpr()))},
983+
std::move(kindArg)};
979984
auto specific{context_->intrinsics().Probe(
980985
CallCharacteristics{"count"}, toCount, *context_)};
981986
CHECK(specific);

flang/lib/Lower/Bridge.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5058,9 +5058,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
50585058
} // namespace
50595059

50605060
Fortran::evaluate::FoldingContext
5061-
Fortran::lower::LoweringBridge::createFoldingContext() const {
5061+
Fortran::lower::LoweringBridge::createFoldingContext() {
50625062
return {getDefaultKinds(), getIntrinsicTable(), getTargetCharacteristics(),
5063-
getLanguageFeatures()};
5063+
getLanguageFeatures(), tempNames};
50645064
}
50655065

50665066
void Fortran::lower::LoweringBridge::lower(

flang/lib/Semantics/semantics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ SemanticsContext::SemanticsContext(
313313
globalScope_{*this}, intrinsicModulesScope_{globalScope_.MakeScope(
314314
Scope::Kind::IntrinsicModules, nullptr)},
315315
foldingContext_{parser::ContextualMessages{&messages_}, defaultKinds_,
316-
intrinsics_, targetCharacteristics_, languageFeatures_} {}
316+
intrinsics_, targetCharacteristics_, languageFeatures_, tempNames_} {}
317317

318318
SemanticsContext::~SemanticsContext() {}
319319

flang/test/Evaluate/rewrite07.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
3+
subroutine test_pack_size_rewrite(x, mask)
4+
real :: x(:)
5+
logical, intent(in) :: mask(:)
6+
! CHECK: CALL test(count(mask,kind=8_8))
7+
call test(size(pack(x, mask), dim=1, kind=8))
8+
end subroutine

flang/unittests/Evaluate/expression.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ int main() {
2323
auto intrinsics{Fortran::evaluate::IntrinsicProcTable::Configure(defaults)};
2424
TargetCharacteristics targetCharacteristics;
2525
Fortran::common::LanguageFeatureControl languageFeatures;
26+
std::set<std::string> tempNames;
2627
FoldingContext context{Fortran::parser::ContextualMessages{nullptr}, defaults,
27-
intrinsics, targetCharacteristics, languageFeatures};
28+
intrinsics, targetCharacteristics, languageFeatures, tempNames};
2829
ex1 = Fold(context, std::move(ex1));
2930
MATCH("-10_4", ex1.AsFortran());
3031
MATCH("1_4/2_4", (DefaultIntegerExpr{1} / DefaultIntegerExpr{2}).AsFortran());

flang/unittests/Evaluate/folding.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ void TestHostRuntimeSubnormalFlushing() {
5050
TargetCharacteristics noFlushingTargetCharacteristics;
5151
noFlushingTargetCharacteristics.set_areSubnormalsFlushedToZero(false);
5252
Fortran::common::LanguageFeatureControl languageFeatures;
53+
std::set<std::string> tempNames;
5354
FoldingContext flushingContext{messages, defaults, intrinsics,
54-
flushingTargetCharacteristics, languageFeatures};
55+
flushingTargetCharacteristics, languageFeatures, tempNames};
5556
FoldingContext noFlushingContext{messages, defaults, intrinsics,
56-
noFlushingTargetCharacteristics, languageFeatures};
57+
noFlushingTargetCharacteristics, languageFeatures, tempNames};
5758

5859
DynamicType r4{R4{}.GetType()};
5960
// Test subnormal argument flushing

flang/unittests/Evaluate/intrinsics.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ struct TestCall {
106106
auto messages{strings.Messages(buffer)};
107107
TargetCharacteristics targetCharacteristics;
108108
common::LanguageFeatureControl languageFeatures;
109-
FoldingContext context{
110-
messages, defaults, table, targetCharacteristics, languageFeatures};
109+
FoldingContext context{messages, defaults, table, targetCharacteristics,
110+
languageFeatures, tempNames};
111111
std::optional<SpecificCall> si{table.Probe(call, args, context)};
112112
if (resultType.has_value()) {
113113
TEST(si.has_value());
@@ -142,6 +142,7 @@ struct TestCall {
142142
ActualArguments args;
143143
std::string name;
144144
std::vector<std::string> keywords;
145+
std::set<std::string> tempNames;
145146
};
146147

147148
void TestIntrinsics() {

0 commit comments

Comments
 (0)