91 changes: 51 additions & 40 deletions clang/tools/clang-scan-deps/ClangScanDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ enum ResourceDirRecipeKind {
RDRK_InvokeCompiler,
};

static std::string OutputFileName = "-";
static ScanningMode ScanMode = ScanningMode::DependencyDirectivesScan;
static ScanningOutputFormat Format = ScanningOutputFormat::Make;
static ScanningOptimizations OptimizeArgs;
Expand All @@ -98,8 +99,8 @@ static bool RoundTripArgs = DoRoundTripDefault;
static void ParseArgs(int argc, char **argv) {
ScanDepsOptTable Tbl;
llvm::StringRef ToolName = argv[0];
llvm::BumpPtrAllocator A;
llvm::StringSaver Saver{A};
llvm::BumpPtrAllocator Alloc;
llvm::StringSaver Saver{Alloc};
llvm::opt::InputArgList Args =
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
llvm::errs() << Msg << '\n';
Expand Down Expand Up @@ -175,6 +176,9 @@ static void ParseArgs(int argc, char **argv) {
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_module_files_dir_EQ))
ModuleFilesDir = A->getValue();

if (const llvm::opt::Arg *A = Args.getLastArg(OPT_o))
OutputFileName = A->getValue();

EagerLoadModules = Args.hasArg(OPT_eager_load_pcm);

if (const llvm::opt::Arg *A = Args.getLastArg(OPT_j)) {
Expand All @@ -186,14 +190,8 @@ static void ParseArgs(int argc, char **argv) {
}
}

if (const llvm::opt::Arg *A = Args.getLastArg(OPT_compilation_database_EQ)) {
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_compilation_database_EQ))
CompilationDB = A->getValue();
} else if (Format != ScanningOutputFormat::P1689) {
llvm::errs() << ToolName
<< ": for the --compiilation-database option: must be "
"specified at least once!";
std::exit(1);
}

if (const llvm::opt::Arg *A = Args.getLastArg(OPT_module_name_EQ))
ModuleName = A->getValue();
Expand Down Expand Up @@ -225,9 +223,8 @@ static void ParseArgs(int argc, char **argv) {

RoundTripArgs = Args.hasArg(OPT_round_trip_args);

if (auto *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
CommandLine.insert(CommandLine.end(), A->getValues().begin(),
A->getValues().end());
if (const llvm::opt::Arg *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
CommandLine.assign(A->getValues().begin(), A->getValues().end());
}

class SharedStream {
Expand Down Expand Up @@ -426,6 +423,11 @@ class FullDeps {
}

void printFullOutput(raw_ostream &OS) {
// Skip sorting modules and constructing the JSON object if the output
// cannot be observed anyway. This makes timings less noisy.
if (&OS == &llvm::nulls())
return;

// Sort the modules by name to get a deterministic order.
std::vector<IndexedModuleID> ModuleIDs;
for (auto &&M : Modules)
Expand Down Expand Up @@ -694,38 +696,28 @@ static std::string getModuleCachePath(ArrayRef<std::string> Args) {
return std::string(Path);
}

// getCompilationDataBase - If -compilation-database is set, load the
// compilation database from the specified file. Otherwise if the we're
// generating P1689 format, trying to generate the compilation database
// form specified command line after the positional parameter "--".
/// Attempts to construct the compilation database from '-compilation-database'
/// or from the arguments following the positional '--'.
static std::unique_ptr<tooling::CompilationDatabase>
getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
getCompilationDatabase(int argc, char **argv, std::string &ErrorMessage) {
ParseArgs(argc, argv);

if (!(CommandLine.empty() ^ CompilationDB.empty())) {
llvm::errs() << "The compilation command line must be provided either via "
"'-compilation-database' or after '--'.";
return nullptr;
}

if (!CompilationDB.empty())
return tooling::JSONCompilationDatabase::loadFromFile(
CompilationDB, ErrorMessage,
tooling::JSONCommandLineSyntax::AutoDetect);

if (Format != ScanningOutputFormat::P1689) {
llvm::errs() << "the --compilation-database option: must be specified at "
"least once!";
return nullptr;
}

// Trying to get the input file, the output file and the command line options
// from the positional parameter "--".
char **DoubleDash = std::find(argv, argv + argc, StringRef("--"));
if (DoubleDash == argv + argc) {
llvm::errs() << "The command line arguments is required after '--' in "
"P1689 per file mode.";
return nullptr;
}

llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions);
driver::Driver TheDriver(CommandLine[0], llvm::sys::getDefaultTargetTriple(),
*Diags);
TheDriver.setCheckInputsExist(false);
std::unique_ptr<driver::Compilation> C(
TheDriver.BuildCompilation(CommandLine));
if (!C || C->getJobs().empty())
Expand All @@ -740,7 +732,8 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {

FrontendOptions &FEOpts = CI->getFrontendOpts();
if (FEOpts.Inputs.size() != 1) {
llvm::errs() << "Only one input file is allowed in P1689 per file mode.";
llvm::errs()
<< "Exactly one input file is required in the per-file mode ('--').\n";
return nullptr;
}

Expand All @@ -749,8 +742,9 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
auto LastCmd = C->getJobs().end();
LastCmd--;
if (LastCmd->getOutputFilenames().size() != 1) {
llvm::errs() << "The command line should provide exactly one output file "
"in P1689 per file mode.\n";
llvm::errs()
<< "Exactly one output file is required in the per-file mode ('--').\n";
return nullptr;
}
StringRef OutputFile = LastCmd->getOutputFilenames().front();

Expand Down Expand Up @@ -790,7 +784,7 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
std::string ErrorMessage;
std::unique_ptr<tooling::CompilationDatabase> Compilations =
getCompilationDataBase(argc, argv, ErrorMessage);
getCompilationDatabase(argc, argv, ErrorMessage);
if (!Compilations) {
llvm::errs() << ErrorMessage << "\n";
return 1;
Expand Down Expand Up @@ -864,8 +858,25 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
});

SharedStream Errs(llvm::errs());
// Print out the dependency results to STDOUT by default.
SharedStream DependencyOS(llvm::outs());

std::optional<llvm::raw_fd_ostream> FileOS;
llvm::raw_ostream &ThreadUnsafeDependencyOS = [&]() -> llvm::raw_ostream & {
if (OutputFileName == "-")
return llvm::outs();

if (OutputFileName == "/dev/null")
return llvm::nulls();

std::error_code EC;
FileOS.emplace(OutputFileName, EC);
if (EC) {
llvm::errs() << "Failed to open output file '" << OutputFileName
<< "': " << llvm::errorCodeToError(EC) << '\n';
std::exit(1);
}
return *FileOS;
}();
SharedStream DependencyOS(ThreadUnsafeDependencyOS);

std::vector<tooling::CompileCommand> Inputs =
AdjustingCompilations->getAllCompileCommands();
Expand Down Expand Up @@ -1006,9 +1017,9 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
HadErrors = true;

if (Format == ScanningOutputFormat::Full)
FD->printFullOutput(llvm::outs());
FD->printFullOutput(ThreadUnsafeDependencyOS);
else if (Format == ScanningOutputFormat::P1689)
PD.printDependencies(llvm::outs());
PD.printDependencies(ThreadUnsafeDependencyOS);

return HadErrors;
}
4 changes: 3 additions & 1 deletion clang/tools/clang-scan-deps/Opts.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ multiclass Eq<string name, string help> {
def help : Flag<["--"], "help">, HelpText<"Display this help">;
def version : Flag<["--"], "version">, HelpText<"Display the version">;

def o : Arg<"o", "Destination of the primary output">;

defm mode : Eq<"mode", "The preprocessing mode used to compute the dependencies">;

defm format : Eq<"format", "The output format for the dependencies">;
Expand All @@ -37,4 +39,4 @@ def verbose : F<"v", "Use verbose output">;

def round_trip_args : F<"round-trip-args", "verify that command-line arguments are canonical by parsing and re-serializing">;

def DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>;
def DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>;
30 changes: 30 additions & 0 deletions clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,36 @@ TEST(ExprMutationAnalyzerTest, FollowFuncArgModified) {
"void f() { int x; g(x); }");
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x)"));

AST = buildASTFromCode(
StdRemoveReference + StdForward +
"template <class T> void f1(T &&a);"
"template <class T> void f2(T &&a);"
"template <class T> void f1(T &&a) { f2<T>(std::forward<T>(a)); }"
"template <class T> void f2(T &&a) { f1<T>(std::forward<T>(a)); }"
"void f() { int x; f1(x); }");
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_FALSE(isMutated(Results, AST.get()));

AST = buildASTFromCode(
StdRemoveReference + StdForward +
"template <class T> void f1(T &&a);"
"template <class T> void f2(T &&a);"
"template <class T> void f1(T &&a) { f2<T>(std::forward<T>(a)); }"
"template <class T> void f2(T &&a) { f1<T>(std::forward<T>(a)); a++; }"
"void f() { int x; f1(x); }");
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("f1(x)"));

AST = buildASTFromCode(
StdRemoveReference + StdForward +
"template <class T> void f1(T &&a);"
"template <class T> void f2(T &&a);"
"template <class T> void f1(T &&a) { f2<T>(std::forward<T>(a)); a++; }"
"template <class T> void f2(T &&a) { f1<T>(std::forward<T>(a)); }"
"void f() { int x; f1(x); }");
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("f1(x)"));
}

TEST(ExprMutationAnalyzerTest, FollowFuncArgNotModified) {
Expand Down
52 changes: 52 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3182,6 +3182,58 @@ TEST(TransferTest, ResultObjectLocationForStdInitializerListExpr) {
});
}

TEST(TransferTest, ResultObjectLocationForStmtExpr) {
std::string Code = R"(
struct S {};
void target() {
S s = ({ S(); });
// [[p]]
}
)";
using ast_matchers::cxxConstructExpr;
using ast_matchers::match;
using ast_matchers::selectFirst;
using ast_matchers::traverse;
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

auto *Construct = selectFirst<CXXConstructExpr>(
"construct", match(cxxConstructExpr().bind("construct"), ASTCtx));

EXPECT_EQ(&Env.getResultObjectLocation(*Construct),
&getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s"));
});
}

TEST(TransferTest, ResultObjectLocationForBuiltinBitCastExpr) {
std::string Code = R"(
struct S { int i; };
void target(int i) {
S s = __builtin_bit_cast(S, i);
// [[p]]
}
)";
using ast_matchers::explicitCastExpr;
using ast_matchers::match;
using ast_matchers::selectFirst;
using ast_matchers::traverse;
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

auto *BuiltinBitCast = selectFirst<BuiltinBitCastExpr>(
"cast", match(explicitCastExpr().bind("cast"), ASTCtx));

EXPECT_EQ(&Env.getResultObjectLocation(*BuiltinBitCast),
&getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s"));
});
}

TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
std::string Code = R"(
struct A {
Expand Down
8 changes: 4 additions & 4 deletions clang/utils/TableGen/NeonEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2266,7 +2266,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
InIfdef = false;
}
if (!InIfdef && IsA64) {
OS << "#ifdef __aarch64__\n";
OS << "#if defined(__aarch64__) || defined(__arm64ec__)\n";
InIfdef = true;
}

Expand Down Expand Up @@ -2299,7 +2299,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
InIfdef = false;
}
if (!InIfdef && IsA64) {
OS << "#ifdef __aarch64__\n";
OS << "#if defined(__aarch64__) || defined(__arm64ec__)\n";
InIfdef = true;
}

Expand Down Expand Up @@ -2381,7 +2381,7 @@ void NeonEmitter::run(raw_ostream &OS) {
OS << "#include <arm_vector_types.h>\n";

// For now, signedness of polynomial types depends on target
OS << "#ifdef __aarch64__\n";
OS << "#if defined(__aarch64__) || defined(__arm64ec__)\n";
OS << "typedef uint8_t poly8_t;\n";
OS << "typedef uint16_t poly16_t;\n";
OS << "typedef uint64_t poly64_t;\n";
Expand Down Expand Up @@ -2582,7 +2582,7 @@ void NeonEmitter::runVectorTypes(raw_ostream &OS) {
OS << "typedef float float32_t;\n";
OS << "typedef __fp16 float16_t;\n";

OS << "#ifdef __aarch64__\n";
OS << "#if defined(__aarch64__) || defined(__arm64ec__)\n";
OS << "typedef double float64_t;\n";
OS << "#endif\n\n";

Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/cmake/Modules/CompilerRTUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,12 @@ macro(construct_compiler_rt_default_triple)
"Default triple for which compiler-rt runtimes will be built.")
endif()

if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
execute_process(COMMAND ${CMAKE_C_COMPILER} --target=${COMPILER_RT_DEFAULT_TARGET_TRIPLE} -print-effective-triple
OUTPUT_VARIABLE COMPILER_RT_DEFAULT_TARGET_TRIPLE
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()

string(REPLACE "-" ";" LLVM_TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE})
list(GET LLVM_TARGET_TRIPLE_LIST 0 COMPILER_RT_DEFAULT_TARGET_ARCH)

Expand Down
4 changes: 0 additions & 4 deletions flang/include/flang/Lower/CallInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,6 @@ class CallerInterface : public CallInterface<CallerInterface> {
llvm_unreachable("getting host associated type in CallerInterface");
}

/// Set attributes on MLIR function.
void setFuncAttrs(mlir::func::FuncOp) const {}

private:
/// Check that the input vector is complete.
bool verifyActualInputs() const;
Expand Down Expand Up @@ -444,7 +441,6 @@ class CalleeInterface : public CallInterface<CalleeInterface> {
bool hasHostAssociated() const;
mlir::Type getHostAssociatedTy() const;
mlir::Value getHostAssociatedTuple() const;
void setFuncAttrs(mlir::func::FuncOp) const;

private:
Fortran::lower::pft::FunctionLikeUnit &funit;
Expand Down
25 changes: 25 additions & 0 deletions flang/include/flang/Optimizer/Dialect/FIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -3222,4 +3222,29 @@ def fir_CUDAAllocateOp : fir_Op<"cuda_allocate", [AttrSizedOperandSegments,
let hasVerifier = 1;
}

def fir_CUDADeallocateOp : fir_Op<"cuda_deallocate",
[MemoryEffects<[MemFree<DefaultResource>]>]> {
let summary = "Perform the device deallocation of data of an allocatable";

let description = [{
The fir.cuda_deallocate operation performs the deallocation on the device
of the data of an allocatable.
}];

let arguments = (ins Arg<fir_ReferenceType, "", [MemRead, MemWrite]>:$box,
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg,
fir_CUDADataAttributeAttr:$cuda_attr,
UnitAttr:$hasStat);

let results = (outs AnyIntegerType:$stat);

let assemblyFormat = [{
$box `:` qualified(type($box))
( `errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
attr-dict `->` type($stat)
}];

let hasVerifier = 1;
}

#endif
10 changes: 5 additions & 5 deletions flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ static constexpr llvm::StringRef getHostAssocAttrName() {
return "fir.host_assoc";
}

/// Attribute to mark an internal procedure.
static constexpr llvm::StringRef getInternalProcedureAttrName() {
return "fir.internal_proc";
/// Attribute to link an internal procedure to its host procedure symbol.
static constexpr llvm::StringRef getHostSymbolAttrName() {
return "fir.host_symbol";
}

/// Attribute containing the original name of a function from before the
Expand All @@ -122,8 +122,8 @@ bool hasHostAssociationArgument(mlir::func::FuncOp func);
/// Is the function, \p func an internal procedure ?
/// Some internal procedures may have access to saved host procedure
/// variables even when they do not have a tuple argument.
inline bool isInternalPorcedure(mlir::func::FuncOp func) {
return func->hasAttr(fir::getInternalProcedureAttrName());
inline bool isInternalProcedure(mlir::func::FuncOp func) {
return func->hasAttr(fir::getHostSymbolAttrName());
}

/// Tell if \p value is:
Expand Down
40 changes: 28 additions & 12 deletions flang/lib/Lower/CallInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,20 +575,41 @@ mlir::Value Fortran::lower::CalleeInterface::getHostAssociatedTuple() const {
return converter.hostAssocTupleValue();
}

void Fortran::lower::CalleeInterface::setFuncAttrs(
mlir::func::FuncOp func) const {
if (funit.parentHasHostAssoc())
func->setAttr(fir::getInternalProcedureAttrName(),
mlir::UnitAttr::get(func->getContext()));
}

//===----------------------------------------------------------------------===//
// CallInterface implementation: this part is common to both caller and callee.
//===----------------------------------------------------------------------===//

static void addSymbolAttribute(mlir::func::FuncOp func,
const Fortran::semantics::Symbol &sym,
mlir::MLIRContext &mlirContext) {
const Fortran::semantics::Symbol &ultimate = sym.GetUltimate();
// The link between an internal procedure and its host procedure is lost
// in FIR if the host is BIND(C) since the internal mangling will not
// allow retrieving the host bind(C) name, and therefore func.func symbol.
// Preserve it as an attribute so that this can be later retrieved.
if (Fortran::semantics::ClassifyProcedure(ultimate) ==
Fortran::semantics::ProcedureDefinitionClass::Internal) {
if (ultimate.owner().kind() ==
Fortran::semantics::Scope::Kind::Subprogram) {
if (const Fortran::semantics::Symbol *hostProcedure =
ultimate.owner().symbol()) {
std::string hostName = Fortran::lower::mangle::mangleName(
*hostProcedure, /*keepExternalInScope=*/true);
func->setAttr(
fir::getHostSymbolAttrName(),
mlir::SymbolRefAttr::get(
&mlirContext, mlir::StringAttr::get(&mlirContext, hostName)));
}
} else if (ultimate.owner().kind() ==
Fortran::semantics::Scope::Kind::MainProgram) {
func->setAttr(fir::getHostSymbolAttrName(),
mlir::SymbolRefAttr::get(
&mlirContext,
mlir::StringAttr::get(
&mlirContext, fir::NameUniquer::doProgramEntry())));
}
}

// Only add this on bind(C) functions for which the symbol is not reflected in
// the current context.
if (!Fortran::semantics::IsBindCProcedure(sym))
Expand Down Expand Up @@ -686,7 +707,6 @@ void Fortran::lower::CallInterface<T>::declare() {
for (const auto &placeHolder : llvm::enumerate(inputs))
if (!placeHolder.value().attributes.empty())
func.setArgAttrs(placeHolder.index(), placeHolder.value().attributes);
side().setFuncAttrs(func);

setCUDAAttributes(func, side().getProcedureSymbol(), characteristic);
}
Expand Down Expand Up @@ -1599,10 +1619,6 @@ class SignatureBuilder
return proc;
}

/// Set internal procedure attribute on MLIR function. Internal procedure
/// are defined in the current file and will not go through SignatureBuilder.
void setFuncAttrs(mlir::func::FuncOp) const {}

/// This is not the description of an indirect call.
static constexpr bool isIndirectCall() { return false; }

Expand Down
167 changes: 110 additions & 57 deletions flang/lib/Lower/OpenMP/OpenMP.cpp

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions flang/lib/Optimizer/Dialect/FIROps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4012,6 +4012,19 @@ mlir::LogicalResult fir::CUDAAllocateOp::verify() {
return mlir::success();
}

mlir::LogicalResult fir::CUDADeallocateOp::verify() {
if (!fir::unwrapRefType(getBox().getType()).isa<fir::BaseBoxType>())
return emitOpError(
"expect box to be a reference to class or box type value");
if (getErrmsg() &&
!fir::unwrapRefType(getErrmsg().getType()).isa<fir::BoxType>())
return emitOpError(
"expect errmsg to be a reference to/or a box type value");
if (getErrmsg() && !getHasStat())
return emitOpError("expect stat attribute when errmsg is provided");
return mlir::success();
}

//===----------------------------------------------------------------------===//
// FIROpsDialect
//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ conservativeCallConflict(llvm::ArrayRef<mlir::Operation *> reaches) {
if (auto callee =
call.getCallableForCallee().dyn_cast<mlir::SymbolRefAttr>()) {
auto module = op->getParentOfType<mlir::ModuleOp>();
return isInternalPorcedure(
return isInternalProcedure(
module.lookupSymbol<mlir::func::FuncOp>(callee));
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
name->symbol->GetUltimate().owner();
if (!curScope.IsTopLevel()) {
const semantics::Scope &declScope =
GetProgramUnitContaining(curScope);
GetProgramUnitOrBlockConstructContaining(curScope);
const semantics::Symbol *sym{
declScope.parent().FindSymbol(name->symbol->name())};
if (sym &&
Expand Down
101 changes: 54 additions & 47 deletions flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,16 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
omp.parallel {
%1 = fir.alloca i32 {adapt.valuebyref, pinned}
%2 = fir.load %arg0 : !fir.ref<i32>
omp.simdloop for (%arg2) : i32 = (%c1_i32) to (%2) step (%c1_i32) {
fir.store %arg2 to %1 : !fir.ref<i32>
%3 = fir.load %1 : !fir.ref<i32>
%4 = fir.convert %3 : (i32) -> i64
%5 = arith.subi %4, %c1_i64 : i64
%6 = fir.coordinate_of %arg1, %5 : (!fir.ref<!fir.array<?xi32>>, i64) -> !fir.ref<i32>
fir.store %3 to %6 : !fir.ref<i32>
omp.yield
omp.simd {
omp.loop_nest (%arg2) : i32 = (%c1_i32) to (%2) step (%c1_i32) {
fir.store %arg2 to %1 : !fir.ref<i32>
%3 = fir.load %1 : !fir.ref<i32>
%4 = fir.convert %3 : (i32) -> i64
%5 = arith.subi %4, %c1_i64 : i64
%6 = fir.coordinate_of %arg1, %5 : (!fir.ref<!fir.array<?xi32>>, i64) -> !fir.ref<i32>
fir.store %3 to %6 : !fir.ref<i32>
omp.yield
}
}
omp.terminator
}
Expand All @@ -202,8 +204,8 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
// CHECK: omp.simdloop
// CHECK-SAME: (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) {
// CHECK: omp.simd {
// CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) {
// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
Expand All @@ -212,6 +214,7 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: }
// CHECK: }
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return
Expand Down Expand Up @@ -471,55 +474,59 @@ func.func @_QPomp_target() {

// -----

func.func @_QPsimdloop_with_nested_loop() {
func.func @_QPsimd_with_nested_loop() {
%0 = fir.alloca i32 {adapt.valuebyref}
%1 = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFsimdloop_with_nested_loopEa"}
%2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimdloop_with_nested_loopEi"}
%3 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFsimdloop_with_nested_loopEj"}
%1 = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFsimd_with_nested_loopEa"}
%2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimd_with_nested_loopEi"}
%3 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFsimd_with_nested_loopEj"}
%c1_i32 = arith.constant 1 : i32
%c10_i32 = arith.constant 10 : i32
%c1_i32_0 = arith.constant 1 : i32
omp.simdloop for (%arg0) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32_0) {
fir.store %arg0 to %0 : !fir.ref<i32>
%c1_i32_1 = arith.constant 1 : i32
%4 = fir.convert %c1_i32_1 : (i32) -> index
%c10_i32_2 = arith.constant 10 : i32
%5 = fir.convert %c10_i32_2 : (i32) -> index
%c1 = arith.constant 1 : index
%6 = fir.do_loop %arg1 = %4 to %5 step %c1 -> index {
%8 = fir.convert %arg1 : (index) -> i32
fir.store %8 to %3 : !fir.ref<i32>
%9 = fir.load %0 : !fir.ref<i32>
%10 = fir.load %0 : !fir.ref<i32>
%11 = fir.convert %10 : (i32) -> i64
%c1_i64 = arith.constant 1 : i64
%12 = arith.subi %11, %c1_i64 : i64
%13 = fir.coordinate_of %1, %12 : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
fir.store %9 to %13 : !fir.ref<i32>
%14 = arith.addi %arg1, %c1 : index
fir.result %14 : index
omp.simd {
omp.loop_nest (%arg0) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32_0) {
fir.store %arg0 to %0 : !fir.ref<i32>
%c1_i32_1 = arith.constant 1 : i32
%4 = fir.convert %c1_i32_1 : (i32) -> index
%c10_i32_2 = arith.constant 10 : i32
%5 = fir.convert %c10_i32_2 : (i32) -> index
%c1 = arith.constant 1 : index
%6 = fir.do_loop %arg1 = %4 to %5 step %c1 -> index {
%8 = fir.convert %arg1 : (index) -> i32
fir.store %8 to %3 : !fir.ref<i32>
%9 = fir.load %0 : !fir.ref<i32>
%10 = fir.load %0 : !fir.ref<i32>
%11 = fir.convert %10 : (i32) -> i64
%c1_i64 = arith.constant 1 : i64
%12 = arith.subi %11, %c1_i64 : i64
%13 = fir.coordinate_of %1, %12 : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
fir.store %9 to %13 : !fir.ref<i32>
%14 = arith.addi %arg1, %c1 : index
fir.result %14 : index
}
%7 = fir.convert %6 : (index) -> i32
fir.store %7 to %3 : !fir.ref<i32>
omp.yield
}
%7 = fir.convert %6 : (index) -> i32
fir.store %7 to %3 : !fir.ref<i32>
omp.yield
}
return
}

// CHECK-LABEL: llvm.func @_QPsimdloop_with_nested_loop() {
// CHECK-LABEL: llvm.func @_QPsimd_with_nested_loop() {
// CHECK: %[[LOWER:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[UPPER:.*]] = llvm.mlir.constant(10 : i32) : i32
// CHECK: %[[STEP:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: omp.simdloop for (%[[CNT:.*]]) : i32 = (%[[LOWER]]) to (%[[UPPER]]) inclusive step (%[[STEP]]) {
// CHECK: llvm.br ^bb1(%[[VAL_1:.*]], %[[VAL_2:.*]] : i64, i64)
// CHECK: ^bb1(%[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64):
// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(0 : index) : i64
// CHECK: %[[VAL_6:.*]] = llvm.icmp "sgt" %[[VAL_4]], %[[VAL_5]] : i64
// CHECK: llvm.cond_br %[[VAL_6]], ^bb2, ^bb3
// CHECK: ^bb2:
// CHECK: llvm.br ^bb1(%[[VAL_7:.*]], %[[VAL_8:.*]] : i64, i64)
// CHECK: ^bb3:
// CHECK: omp.yield
// CHECK: omp.simd {
// CHECK-NEXT: omp.loop_nest (%[[CNT:.*]]) : i32 = (%[[LOWER]]) to (%[[UPPER]]) inclusive step (%[[STEP]]) {
// CHECK: llvm.br ^bb1(%[[VAL_1:.*]], %[[VAL_2:.*]] : i64, i64)
// CHECK: ^bb1(%[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64):
// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(0 : index) : i64
// CHECK: %[[VAL_6:.*]] = llvm.icmp "sgt" %[[VAL_4]], %[[VAL_5]] : i64
// CHECK: llvm.cond_br %[[VAL_6]], ^bb2, ^bb3
// CHECK: ^bb2:
// CHECK: llvm.br ^bb1(%[[VAL_7:.*]], %[[VAL_8:.*]] : i64, i64)
// CHECK: ^bb3:
// CHECK: omp.yield
// CHECK: }
// CHECK: }
// CHECK: llvm.return
// CHECK: }
Expand Down
37 changes: 37 additions & 0 deletions flang/test/Fir/cuf-invalid.fir
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,40 @@ func.func @_QPsub1() {
%13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> errmsg(%1 : !fir.ref<i32>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
return
}

// -----

func.func @_QPsub1() {
%1 = fir.alloca i32
// expected-error@+1{{'fir.cuda_deallocate' op expect box to be a reference to class or box type value}}
%2 = fir.cuda_deallocate %1 : !fir.ref<i32> {cuda_attr = #fir.cuda<device>} -> i32
return
}

// -----

func.func @_QPsub1() {
%0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"}
%4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
%1 = fir.alloca i32
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
// expected-error@+1{{'fir.cuda_deallocate' op expect errmsg to be a reference to/or a box type value}}
%13 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> errmsg(%1 : !fir.ref<i32>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
return
}

// -----

func.func @_QPsub1() {
%0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"}
%4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
%c100 = arith.constant 100 : index
%7 = fir.alloca !fir.char<1,100> {bindc_name = "msg", uniq_name = "_QFsub1Emsg"}
%8:2 = hlfir.declare %7 typeparams %c100 {uniq_name = "_QFsub1Emsg"} : (!fir.ref<!fir.char<1,100>>, index) -> (!fir.ref<!fir.char<1,100>>, !fir.ref<!fir.char<1,100>>)
%9 = fir.embox %8#1 : (!fir.ref<!fir.char<1,100>>) -> !fir.box<!fir.char<1,100>>
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
%16 = fir.convert %9 : (!fir.box<!fir.char<1,100>>) -> !fir.box<none>
// expected-error@+1{{'fir.cuda_deallocate' op expect stat attribute when errmsg is provided}}
%13 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>} -> i32
return
}
6 changes: 6 additions & 0 deletions flang/test/Fir/cuf.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ func.func @_QPsub1() {
%4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
%13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32
%14 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32
return
}

// CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32
// CHECK: fir.cuda_deallocate %{{.*}} : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32

// -----

Expand Down Expand Up @@ -66,5 +68,9 @@ func.func @_QPsub1() {
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
%16 = fir.convert %9 : (!fir.box<!fir.char<1,100>>) -> !fir.box<none>
%13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
%14 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
return
}

// CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> errmsg(%{{.*}} : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
// CHECK: fir.cuda_deallocate %{{.*}} : !fir.ref<!fir.box<none>> errmsg(%{{.*}} : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
39 changes: 39 additions & 0 deletions flang/test/Lower/HLFIR/internal-procedures-bindc-host.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
! Test fir.host_sym attribute to retain link between internal
! and host procedure in FIR even when BIND(C) is involved.

! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
! RUN: bbc -emit-hlfir -o - %s | fir-opt -external-name-interop -o - |FileCheck %s --check-prefix=AFTER_RENAME_PASS

subroutine foo() bind(c, name="some_c_name")
call bar()
contains
subroutine bar()
end subroutine
end subroutine
! CHECK: func.func @some_c_name()
! CHECK: func.func private @_QFfooPbar() attributes {fir.host_symbol = @some_c_name, llvm.linkage = #llvm.linkage<internal>}
! AFTER_RENAME_PASS: func.func @some_c_name()
! AFTER_RENAME_PASS: func.func private @_QFfooPbar() attributes {fir.host_symbol = @some_c_name, llvm.linkage = #llvm.linkage<internal>}

subroutine notbindc()
call bar()
contains
subroutine bar()
end subroutine
end subroutine
! CHECK: func.func @_QPnotbindc()
! CHECK: func.func private @_QFnotbindcPbar() attributes {fir.host_symbol = @_QPnotbindc, llvm.linkage = #llvm.linkage<internal>}
! AFTER_RENAME_PASS: func.func @notbindc_() attributes {fir.internal_name = "_QPnotbindc"}
! AFTER_RENAME_PASS: func.func private @_QFnotbindcPbar() attributes {fir.host_symbol = @notbindc_, llvm.linkage = #llvm.linkage<internal>}


! Main program
call bar()
contains
subroutine bar()
end subroutine
end
! CHECK: func.func @_QQmain()
! CHECK: func.func private @_QFPbar() attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>}
! AFTER_RENAME_PASS: func.func @_QQmain()
! AFTER_RENAME_PASS: func.func private @_QFPbar() attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>}
6 changes: 3 additions & 3 deletions flang/test/Lower/HLFIR/internal-procedures.f90
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ subroutine internal
end subroutine
end subroutine
! CHECK-LABEL: func.func private @_QFtest_explicit_shape_arrayPinternal(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.box<!fir.array<?xf32>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.box<!fir.array<?xf32>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<!fir.box<!fir.array<?xf32>>>>, i32) -> !fir.ref<!fir.box<!fir.array<?xf32>>>
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
Expand All @@ -28,7 +28,7 @@ subroutine internal
end subroutine
end subroutine
! CHECK-LABEL: func.func private @_QFtest_assumed_shapePinternal(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.box<!fir.array<?xf32>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.box<!fir.array<?xf32>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<!fir.box<!fir.array<?xf32>>>>, i32) -> !fir.ref<!fir.box<!fir.array<?xf32>>>
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
Expand All @@ -45,7 +45,7 @@ subroutine internal()
end subroutine
end subroutine
! CHECK-LABEL: func.func private @_QFtest_scalar_charPinternal(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.boxchar<1>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.boxchar<1>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<!fir.boxchar<1>>>, i32) -> !fir.ref<!fir.boxchar<1>>
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.boxchar<1>>
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenACC/acc-routine04.f90
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ subroutine sub2()
! CHECK: acc.routine @acc_routine_0 func(@_QMdummy_modPsub1) seq
! CHECK: func.func @_QMdummy_modPsub1(%arg0: !fir.ref<i32> {fir.bindc_name = "i"}) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_0]>}
! CHECK: func.func @_QQmain() attributes {fir.bindc_name = "test_acc_routine"}
! CHECK: func.func private @_QFPsub2() attributes {acc.routine_info = #acc.routine_info<[@acc_routine_1]>, llvm.linkage = #llvm.linkage<internal>}
! CHECK: func.func private @_QFPsub2() attributes {acc.routine_info = #acc.routine_info<[@acc_routine_1]>, fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>}
23 changes: 11 additions & 12 deletions flang/test/Lower/OpenMP/FIR/if-clause.f90
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ program main
do i = 1, 10
end do
!$omp end parallel do simd

! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
!$omp parallel do simd if(parallel: .true.) if(simd: .false.)
do i = 1, 10
end do
!$omp end parallel do simd

! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
Expand All @@ -134,7 +134,7 @@ program main
do i = 1, 10
end do
!$omp end parallel do simd

! CHECK: omp.parallel
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
Expand All @@ -147,22 +147,22 @@ program main
! ----------------------------------------------------------------------------
! SIMD
! ----------------------------------------------------------------------------
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
!$omp simd
do i = 1, 10
end do
!$omp end simd

! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp simd if(.true.)
do i = 1, 10
end do
!$omp end simd

! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp simd if(simd: .true.)
do i = 1, 10
Expand Down Expand Up @@ -281,7 +281,6 @@ program main
end do
!$omp end target parallel do


! CHECK: omp.target
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
Expand Down Expand Up @@ -360,7 +359,7 @@ program main
! CHECK: omp.target
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
!$omp target simd
Expand All @@ -370,7 +369,7 @@ program main

! CHECK: omp.target
! CHECK-SAME: if({{.*}})
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp target simd if(.true.)
do i = 1, 10
Expand All @@ -379,7 +378,7 @@ program main

! CHECK: omp.target
! CHECK-SAME: if({{.*}})
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp target simd if(target: .true.) if(simd: .false.)
do i = 1, 10
Expand All @@ -388,7 +387,7 @@ program main

! CHECK: omp.target
! CHECK-SAME: if({{.*}})
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
!$omp target simd if(target: .true.)
Expand All @@ -399,7 +398,7 @@ program main
! CHECK: omp.target
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp target simd if(simd: .true.)
do i = 1, 10
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/FIR/loop-combined.f90
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ program main
! TARGET SIMD
! ----------------------------------------------------------------------------
! CHECK: omp.target
! CHECK: omp.simdloop
! CHECK: omp.simd
!$omp target simd
do i = 1, 10
end do
Expand Down
3 changes: 2 additions & 1 deletion flang/test/Lower/OpenMP/FIR/parallel-private-clause.f90
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ subroutine simd_loop_1
! FIRDialect: %[[UB:.*]] = arith.constant 9 : i32
! FIRDialect: %[[STEP:.*]] = arith.constant 1 : i32

! FIRDialect: omp.simdloop for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! FIRDialect: omp.simd {
! FIRDialect-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
!$OMP SIMD PRIVATE(r)
do i=1, 9
! FIRDialect: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
Expand Down
109 changes: 59 additions & 50 deletions flang/test/Lower/OpenMP/FIR/simd.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,34 @@

! RUN: bbc -fopenmp -emit-fir -hlfir=false %s -o - | FileCheck %s

!CHECK-LABEL: func @_QPsimdloop()
subroutine simdloop
integer :: i
!CHECK-LABEL: func @_QPsimd()
subroutine simd
integer :: i
!$OMP SIMD
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK-NEXT: %[[UB:.*]] = arith.constant 9 : i32
! CHECK-NEXT: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK-NEXT: omp.simdloop for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK-NEXT: omp.simd {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i=1, 9
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
print*, i
end do
!$OMP END SIMD
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_if_clause
subroutine simdloop_with_if_clause(n, threshold)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_if_clause
subroutine simd_with_if_clause(n, threshold)
integer :: i, n, threshold
!$OMP SIMD IF( n .GE. threshold )
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %arg0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: %[[COND:.*]] = arith.cmpi sge
! CHECK: omp.simdloop if(%[[COND:.*]]) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd if(%[[COND:.*]]) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
Expand All @@ -37,14 +39,15 @@ subroutine simdloop_with_if_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause
subroutine simdloop_with_simdlen_clause(n, threshold)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_simdlen_clause
subroutine simd_with_simdlen_clause(n, threshold)
integer :: i, n, threshold
!$OMP SIMD SIMDLEN(2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %arg0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
Expand All @@ -54,15 +57,16 @@ subroutine simdloop_with_simdlen_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause_from_param
subroutine simdloop_with_simdlen_clause_from_param(n, threshold)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!CHECK-LABEL: func @_QPsimd_with_simdlen_clause_from_param
subroutine simd_with_simdlen_clause_from_param(n, threshold)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!$OMP SIMD SIMDLEN(simdlen)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %arg0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
Expand All @@ -72,15 +76,16 @@ subroutine simdloop_with_simdlen_clause_from_param(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause_from_expr_from_param
subroutine simdloop_with_simdlen_clause_from_expr_from_param(n, threshold)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!CHECK-LABEL: func @_QPsimd_with_simdlen_clause_from_expr_from_param
subroutine simd_with_simdlen_clause_from_expr_from_param(n, threshold)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!$OMP SIMD SIMDLEN(simdlen*2 + 2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %arg0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(6) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(6) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
Expand All @@ -90,14 +95,15 @@ subroutine simdloop_with_simdlen_clause_from_expr_from_param(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause
subroutine simdloop_with_safelen_clause(n, threshold)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_safelen_clause
subroutine simd_with_safelen_clause(n, threshold)
integer :: i, n, threshold
!$OMP SIMD SAFELEN(2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %arg0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd safelen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
Expand All @@ -107,15 +113,16 @@ subroutine simdloop_with_safelen_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause_from_expr_from_param
subroutine simdloop_with_safelen_clause_from_expr_from_param(n, threshold)
integer :: i, n, threshold
integer, parameter :: safelen = 2;
!CHECK-LABEL: func @_QPsimd_with_safelen_clause_from_expr_from_param
subroutine simd_with_safelen_clause_from_expr_from_param(n, threshold)
integer :: i, n, threshold
integer, parameter :: safelen = 2;
!$OMP SIMD SAFELEN(safelen*2 + 2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %arg0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop safelen(6) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd safelen(6) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
Expand All @@ -125,14 +132,15 @@ subroutine simdloop_with_safelen_clause_from_expr_from_param(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_safelen_clause
subroutine simdloop_with_simdlen_safelen_clause(n, threshold)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_simdlen_safelen_clause
subroutine simd_with_simdlen_safelen_clause(n, threshold)
integer :: i, n, threshold
!$OMP SIMD SIMDLEN(1) SAFELEN(2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %arg0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(1) safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(1) safelen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
Expand All @@ -142,20 +150,21 @@ subroutine simdloop_with_simdlen_safelen_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_collapse_clause
subroutine simdloop_with_collapse_clause(n)
integer :: i, j, n
integer :: A(n,n)
! CHECK: %[[LOWER_I:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_I:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_I:.*]] = arith.constant 1 : i32
! CHECK: %[[LOWER_J:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_J:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_J:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop for (%[[ARG_0:.*]], %[[ARG_1:.*]]) : i32 = (
! CHECK-SAME: %[[LOWER_I]], %[[LOWER_J]]) to (
! CHECK-SAME: %[[UPPER_I]], %[[UPPER_J]]) inclusive step (
! CHECK-SAME: %[[STEP_I]], %[[STEP_J]]) {
!CHECK-LABEL: func @_QPsimd_with_collapse_clause
subroutine simd_with_collapse_clause(n)
integer :: i, j, n
integer :: A(n,n)
! CHECK: %[[LOWER_I:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_I:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_I:.*]] = arith.constant 1 : i32
! CHECK: %[[LOWER_J:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_J:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_J:.*]] = arith.constant 1 : i32
! CHECK: omp.simd {
! CHECK-NEXT: omp.loop_nest (%[[ARG_0:.*]], %[[ARG_1:.*]]) : i32 = (
! CHECK-SAME: %[[LOWER_I]], %[[LOWER_J]]) to (
! CHECK-SAME: %[[UPPER_I]], %[[UPPER_J]]) inclusive step (
! CHECK-SAME: %[[STEP_I]], %[[STEP_J]]) {
!$OMP SIMD COLLAPSE(2)
do i = 1, n
do j = 1, n
Expand Down
23 changes: 11 additions & 12 deletions flang/test/Lower/OpenMP/if-clause.f90
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ program main
do i = 1, 10
end do
!$omp end parallel do simd

! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
!$omp parallel do simd if(parallel: .true.) if(simd: .false.)
do i = 1, 10
end do
!$omp end parallel do simd

! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
Expand All @@ -134,7 +134,7 @@ program main
do i = 1, 10
end do
!$omp end parallel do simd

! CHECK: omp.parallel
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
Expand All @@ -147,22 +147,22 @@ program main
! ----------------------------------------------------------------------------
! SIMD
! ----------------------------------------------------------------------------
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
!$omp simd
do i = 1, 10
end do
!$omp end simd

! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp simd if(.true.)
do i = 1, 10
end do
!$omp end simd

! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp simd if(simd: .true.)
do i = 1, 10
Expand Down Expand Up @@ -281,7 +281,6 @@ program main
end do
!$omp end target parallel do


! CHECK: omp.target
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
Expand Down Expand Up @@ -360,7 +359,7 @@ program main
! CHECK: omp.target
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
!$omp target simd
Expand All @@ -370,7 +369,7 @@ program main

! CHECK: omp.target
! CHECK-SAME: if({{.*}})
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp target simd if(.true.)
do i = 1, 10
Expand All @@ -379,7 +378,7 @@ program main

! CHECK: omp.target
! CHECK-SAME: if({{.*}})
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp target simd if(target: .true.) if(simd: .false.)
do i = 1, 10
Expand All @@ -388,7 +387,7 @@ program main

! CHECK: omp.target
! CHECK-SAME: if({{.*}})
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
!$omp target simd if(target: .true.)
Expand All @@ -399,7 +398,7 @@ program main
! CHECK: omp.target
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
! CHECK: omp.simdloop
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
!$omp target simd if(simd: .true.)
do i = 1, 10
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/loop-combined.f90
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ program main
! TARGET SIMD
! ----------------------------------------------------------------------------
! CHECK: omp.target
! CHECK: omp.simdloop
! CHECK: omp.simd
!$omp target simd
do i = 1, 10
end do
Expand Down
3 changes: 2 additions & 1 deletion flang/test/Lower/OpenMP/parallel-private-clause.f90
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ subroutine simd_loop_1
! FIRDialect: %[[UB:.*]] = arith.constant 9 : i32
! FIRDialect: %[[STEP:.*]] = arith.constant 1 : i32

! FIRDialect: omp.simdloop for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! FIRDialect: omp.simd {
! FIRDialect-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
!$OMP SIMD PRIVATE(r)
do i=1, 9
! FIRDialect: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
Expand Down
123 changes: 66 additions & 57 deletions flang/test/Lower/OpenMP/simd.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,35 @@
!RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: bbc -hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s

!CHECK-LABEL: func @_QPsimdloop()
subroutine simdloop
integer :: i
!CHECK-LABEL: func @_QPsimd()
subroutine simd
integer :: i
!$OMP SIMD
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK-NEXT: %[[UB:.*]] = arith.constant 9 : i32
! CHECK-NEXT: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK-NEXT: omp.simdloop for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK-NEXT: omp.simd {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i=1, 9
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
print*, i
end do
!$OMP END SIMD
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_if_clause
subroutine simdloop_with_if_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_if_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_if_clause
subroutine simd_with_if_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimd_with_if_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!$OMP SIMD IF( n .GE. threshold )
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: %[[COND:.*]] = arith.cmpi sge
! CHECK: omp.simdloop if(%[[COND:.*]]) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd if(%[[COND:.*]]) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
Expand All @@ -39,15 +41,16 @@ subroutine simdloop_with_if_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause
subroutine simdloop_with_simdlen_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_simdlen_clause
subroutine simd_with_simdlen_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimd_with_simdlen_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!$OMP SIMD SIMDLEN(2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
Expand All @@ -57,16 +60,17 @@ subroutine simdloop_with_simdlen_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause_from_param
subroutine simdloop_with_simdlen_clause_from_param(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_clause_from_paramEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!CHECK-LABEL: func @_QPsimd_with_simdlen_clause_from_param
subroutine simd_with_simdlen_clause_from_param(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimd_with_simdlen_clause_from_paramEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!$OMP SIMD SIMDLEN(simdlen)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
Expand All @@ -76,16 +80,17 @@ subroutine simdloop_with_simdlen_clause_from_param(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_clause_from_expr_from_param
subroutine simdloop_with_simdlen_clause_from_expr_from_param(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_clause_from_expr_from_paramEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!CHECK-LABEL: func @_QPsimd_with_simdlen_clause_from_expr_from_param
subroutine simd_with_simdlen_clause_from_expr_from_param(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimd_with_simdlen_clause_from_expr_from_paramEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
integer, parameter :: simdlen = 2;
!$OMP SIMD SIMDLEN(simdlen*2 + 2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(6) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(6) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
Expand All @@ -95,15 +100,16 @@ subroutine simdloop_with_simdlen_clause_from_expr_from_param(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause
subroutine simdloop_with_safelen_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_safelen_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_safelen_clause
subroutine simd_with_safelen_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimd_with_safelen_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!$OMP SIMD SAFELEN(2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd safelen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
Expand All @@ -113,16 +119,17 @@ subroutine simdloop_with_safelen_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause_from_expr_from_param
subroutine simdloop_with_safelen_clause_from_expr_from_param(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_safelen_clause_from_expr_from_paramEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
integer, parameter :: safelen = 2;
!CHECK-LABEL: func @_QPsimd_with_safelen_clause_from_expr_from_param
subroutine simd_with_safelen_clause_from_expr_from_param(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimd_with_safelen_clause_from_expr_from_paramEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
integer, parameter :: safelen = 2;
!$OMP SIMD SAFELEN(safelen*2 + 2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop safelen(6) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd safelen(6) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
Expand All @@ -132,15 +139,16 @@ subroutine simdloop_with_safelen_clause_from_expr_from_param(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_simdlen_safelen_clause
subroutine simdloop_with_simdlen_safelen_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimdloop_with_simdlen_safelen_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!CHECK-LABEL: func @_QPsimd_with_simdlen_safelen_clause
subroutine simd_with_simdlen_safelen_clause(n, threshold)
! CHECK: %[[ARG_N:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsimd_with_simdlen_safelen_clauseEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
integer :: i, n, threshold
!$OMP SIMD SIMDLEN(1) SAFELEN(2)
! CHECK: %[[LB:.*]] = arith.constant 1 : i32
! CHECK: %[[UB:.*]] = fir.load %[[ARG_N]]#0
! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop simdlen(1) safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
! CHECK: omp.simd simdlen(1) safelen(2) {
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
do i = 1, n
! CHECK: fir.store %[[I]] to %[[LOCAL:.*]]#1 : !fir.ref<i32>
! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]]#0 : !fir.ref<i32>
Expand All @@ -150,20 +158,21 @@ subroutine simdloop_with_simdlen_safelen_clause(n, threshold)
!$OMP END SIMD
end subroutine

!CHECK-LABEL: func @_QPsimdloop_with_collapse_clause
subroutine simdloop_with_collapse_clause(n)
integer :: i, j, n
integer :: A(n,n)
! CHECK: %[[LOWER_I:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_I:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_I:.*]] = arith.constant 1 : i32
! CHECK: %[[LOWER_J:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_J:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_J:.*]] = arith.constant 1 : i32
! CHECK: omp.simdloop for (%[[ARG_0:.*]], %[[ARG_1:.*]]) : i32 = (
! CHECK-SAME: %[[LOWER_I]], %[[LOWER_J]]) to (
! CHECK-SAME: %[[UPPER_I]], %[[UPPER_J]]) inclusive step (
! CHECK-SAME: %[[STEP_I]], %[[STEP_J]]) {
!CHECK-LABEL: func @_QPsimd_with_collapse_clause
subroutine simd_with_collapse_clause(n)
integer :: i, j, n
integer :: A(n,n)
! CHECK: %[[LOWER_I:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_I:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_I:.*]] = arith.constant 1 : i32
! CHECK: %[[LOWER_J:.*]] = arith.constant 1 : i32
! CHECK: %[[UPPER_J:.*]] = fir.load %[[PARAM_ARG:.*]] : !fir.ref<i32>
! CHECK: %[[STEP_J:.*]] = arith.constant 1 : i32
! CHECK: omp.simd {
! CHECK-NEXT: omp.loop_nest (%[[ARG_0:.*]], %[[ARG_1:.*]]) : i32 = (
! CHECK-SAME: %[[LOWER_I]], %[[LOWER_J]]) to (
! CHECK-SAME: %[[UPPER_I]], %[[UPPER_J]]) inclusive step (
! CHECK-SAME: %[[STEP_I]], %[[STEP_J]]) {
!$OMP SIMD COLLAPSE(2)
do i = 1, n
do j = 1, n
Expand Down
1 change: 1 addition & 0 deletions flang/test/Lower/OpenMP/threadprivate-hlfir.f90
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ subroutine sub()
print *, a
!$omp end parallel
end subroutine

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
!CHECK: fir.call @_QFPsub() fastmath<contract> : () -> ()
!CHECK: return
!CHECK: }
!CHECK: func.func private @_QFPsub() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
!CHECK: func.func private @_QFPsub() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
!CHECK: %[[A:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFEa"}
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: %[[A_ADDR:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/threadprivate-host-association.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
!CHECK: fir.call @_QFPsub() fastmath<contract> : () -> ()
!CHECK: return
!CHECK: }
!CHECK: func.func private @_QFPsub() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
!CHECK: func.func private @_QFPsub() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
!CHECK: %[[A:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: %[[TP_A:.*]] = omp.threadprivate %[[A_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
Expand Down
15 changes: 7 additions & 8 deletions flang/test/Lower/character-elemental.f90
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ subroutine substring_main
character*7 :: string(2) = ['12 ', '12 ']
integer :: result(2)
integer :: ival
interface
elemental function inner(arg)
character(len=*), intent(in) :: arg
integer :: inner
end function inner
end interface

ival = 1
! CHECK: %[[a0:.*]] = fir.alloca i32 {bindc_name = "ival", uniq_name = "_QFsubstring_mainEival"}
Expand All @@ -26,14 +32,7 @@ subroutine substring_main
! CHECK: %[[a14:.*]] = fir.coordinate_of %[[a13]], %[[a12]] : (!fir.ref<!fir.array<7x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
! CHECK: %[[a15:.*]] = fir.convert %[[a14]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
! CHECK: %[[a16:.*]] = fir.emboxchar %[[a15]], {{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
! CHECK: %[[a17:.*]] = fir.call @_QFsubstring_mainPinner(%[[a16]]) {{.*}}: (!fir.boxchar<1>) -> i32
! CHECK: %[[a17:.*]] = fir.call @_QPinner(%[[a16]]) {{.*}}: (!fir.boxchar<1>) -> i32
result = inner(string(1:2)(ival:ival))
print *, result
contains
elemental function inner(arg)
character(len=*), intent(in) :: arg
integer :: inner

inner = len(arg)
end function inner
end subroutine substring_main
16 changes: 8 additions & 8 deletions flang/test/Lower/equivalence-with-host-assoc.f90
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ subroutine inner
i1 = j1
end subroutine inner
end subroutine test1
! FIR-LABEL: func.func private @_QFtest1Pinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! FIR-LABEL: func.func private @_QFtest1Pinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! FIR: %[[VAL_0:.*]] = fir.address_of(@_QFtest1Ei1) : !fir.ref<!fir.array<1xi32>>
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand All @@ -24,7 +24,7 @@ end subroutine test1
! FIR: return
! FIR: }

! HLFIR-LABEL: func.func private @_QFtest1Pinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR-LABEL: func.func private @_QFtest1Pinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@_QFtest1Ei1) : !fir.ref<!fir.array<1xi32>>
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand Down Expand Up @@ -54,7 +54,7 @@ subroutine inner
end subroutine inner
end subroutine host
end module test2
! FIR-LABEL: func.func private @_QMtest2FhostPinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! FIR-LABEL: func.func private @_QMtest2FhostPinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! FIR: %[[VAL_0:.*]] = fir.address_of(@_QMtest2FhostEf1) : !fir.ref<!fir.array<1xi32>>
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand All @@ -68,7 +68,7 @@ end module test2
! FIR: return
! FIR: }

! HLFIR-LABEL: func.func private @_QMtest2FhostPinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR-LABEL: func.func private @_QMtest2FhostPinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@_QMtest2FhostEf1) : !fir.ref<!fir.array<1xi32>>
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<1xi32>>) -> !fir.ref<!fir.array<4xi8>>
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand All @@ -94,7 +94,7 @@ subroutine inner
i1 = j1 + k1
end subroutine inner
end subroutine test3
! FIR-LABEL: func.func private @_QFtest3Pinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! FIR-LABEL: func.func private @_QFtest3Pinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! FIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand All @@ -115,7 +115,7 @@ end subroutine test3
! FIR: return
! FIR: }

! HLFIR-LABEL: func.func private @_QFtest3Pinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR-LABEL: func.func private @_QFtest3Pinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand Down Expand Up @@ -149,7 +149,7 @@ subroutine inner
i1 = j1 + k1
end subroutine inner
end subroutine test4
! FIR-LABEL: func.func private @_QFtest4Pinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! FIR-LABEL: func.func private @_QFtest4Pinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! FIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
! FIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
! FIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand All @@ -170,7 +170,7 @@ end subroutine test4
! FIR: return
! FIR: }

! HLFIR-LABEL: func.func private @_QFtest4Pinner() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR-LABEL: func.func private @_QFtest4Pinner() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! HLFIR: %[[VAL_0:.*]] = fir.address_of(@blk_) : !fir.ref<tuple<i32>>
! HLFIR: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<tuple<i32>>) -> !fir.ref<!fir.array<?xi8>>
! HLFIR: %[[VAL_2:.*]] = arith.constant 0 : index
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/explicit-interface-results-2.f90
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ subroutine host4()
call internal_proc_a()
contains
! CHECK-LABEL: func private @_QFhost4Pinternal_proc_a
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine internal_proc_a()
call takes_array(return_array())
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
Expand All @@ -94,7 +94,7 @@ subroutine host5()
implicit none
call internal_proc_a()
contains
! CHECK-LABEL: func private @_QFhost5Pinternal_proc_a() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-LABEL: func private @_QFhost5Pinternal_proc_a() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine internal_proc_a()
call takes_array(return_array())
! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QMsome_moduleEn_module) : !fir.ref<i32>
Expand Down
6 changes: 3 additions & 3 deletions flang/test/Lower/host-associated-functions.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ subroutine capture_char_func_dummy(char_func_dummy, n)
call internal()
contains
! CHECK-LABEL: func private @_QFcapture_char_func_dummyPinternal(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine internal()
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>>, i32) -> !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
Expand Down Expand Up @@ -56,7 +56,7 @@ subroutine capture_char_func_assumed_dummy(char_func_dummy)
call internal()
contains
! CHECK-LABEL: func private @_QFcapture_char_func_assumed_dummyPinternal(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine internal()
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>>>, i32) -> !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
Expand Down Expand Up @@ -110,7 +110,7 @@ function array_func()
contains
subroutine internal()
! CHECK-LABEL: func private @_QFcapture_array_funcPinternal(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.llvm_ptr<!fir.ref<i32>>
Expand Down
6 changes: 3 additions & 3 deletions flang/test/Lower/host-associated-globals.f90
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ subroutine bar()
print *, j_in_equiv, not_in_equiv
end subroutine
end subroutine
! CHECK-LABEL: func.func private @_QFtest_commonPbar() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-LABEL: func.func private @_QFtest_commonPbar() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_0:.*]] = fir.address_of(@x_) : !fir.ref<!fir.array<12xi8>>
! CHECK: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.array<12xi8>>) -> !fir.ref<!fir.array<?xi8>>
! CHECK: %[[VAL_2:.*]] = arith.constant 4 : index
Expand All @@ -59,7 +59,7 @@ subroutine bar()
print *, j_in_equiv, not_in_equiv
end subroutine
end subroutine
! CHECK-LABEL: func.func private @_QFsaved_equivPbar() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-LABEL: func.func private @_QFsaved_equivPbar() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFsaved_equivEi) : !fir.ref<!fir.array<8xi8>>
! CHECK: %[[VAL_1:.*]] = arith.constant 4 : index
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<!fir.array<8xi8>>, index) -> !fir.ref<i8>
Expand All @@ -80,7 +80,7 @@ subroutine bar()
end subroutine
end subroutine
! CHECK-LABEL: func.func private @_QFmixed_capturePbar(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QFmixed_captureEsaved_i) : !fir.ref<!fir.array<4xi8>>
! CHECK: %[[VAL_2:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
Expand Down
32 changes: 16 additions & 16 deletions flang/test/Lower/host-associated.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ subroutine test1
print *, i
contains
! CHECK-LABEL: func private @_QFtest1Ptest1_internal(
! CHECK-SAME: %[[arg:[^:]*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[arg:[^:]*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[iaddr:.*]] = fir.coordinate_of %[[arg]], %c0
! CHECK: %[[i:.*]] = fir.load %[[iaddr]] : !fir.llvm_ptr<!fir.ref<i32>>
! CHECK: %[[val:.*]] = fir.call @_QPifoo() {{.*}}: () -> i32
Expand All @@ -47,7 +47,7 @@ subroutine test2
print *, a, b
contains
! CHECK-LABEL: func private @_QFtest2Ptest2_internal(
! CHECK-SAME: %[[arg:[^:]*]]: !fir.ref<tuple<!fir.ref<f32>, !fir.ref<f32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[arg:[^:]*]]: !fir.ref<tuple<!fir.ref<f32>, !fir.ref<f32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine test2_internal
! CHECK: %[[a:.*]] = fir.coordinate_of %[[arg]], %c0
! CHECK: %[[aa:.*]] = fir.load %[[a]] : !fir.llvm_ptr<!fir.ref<f32>>
Expand All @@ -62,7 +62,7 @@ subroutine test2_internal
end subroutine test2_internal

! CHECK-LABEL: func private @_QFtest2Ptest2_inner(
! CHECK-SAME: %[[arg:[^:]*]]: !fir.ref<tuple<!fir.ref<f32>, !fir.ref<f32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[arg:[^:]*]]: !fir.ref<tuple<!fir.ref<f32>, !fir.ref<f32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine test2_inner
! CHECK: %[[a:.*]] = fir.coordinate_of %[[arg]], %c0
! CHECK: %[[aa:.*]] = fir.load %[[a]] : !fir.llvm_ptr<!fir.ref<f32>>
Expand Down Expand Up @@ -96,7 +96,7 @@ subroutine test6(c)

contains
! CHECK-LABEL: func private @_QFtest6Ptest6_inner(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.boxchar<1>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.boxchar<1>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine test6_inner
! CHECK: %[[coor:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.boxchar<1>>>, i32) -> !fir.ref<!fir.boxchar<1>>
! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref<!fir.boxchar<1>>
Expand Down Expand Up @@ -138,7 +138,7 @@ subroutine test3(p,q,i)

contains
! CHECK-LABEL: func private @_QFtest3Ptest3_inner(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine test3_inner
! CHECK: %[[pcoor:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>>>, i32) -> !fir.ref<!fir.box<!fir.array<?xf32>>>
! CHECK: %[[p:.*]] = fir.load %[[pcoor]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
Expand Down Expand Up @@ -185,7 +185,7 @@ subroutine test3a(p)

contains
! CHECK: func private @_QFtest3aPtest3a_inner(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.box<!fir.array<10xf32>>, !fir.box<!fir.array<10xf32>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.box<!fir.array<10xf32>>, !fir.box<!fir.array<10xf32>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine test3a_inner
! CHECK: %[[pcoor:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.box<!fir.array<10xf32>>, !fir.box<!fir.array<10xf32>>>>, i32) -> !fir.ref<!fir.box<!fir.array<10xf32>>>
! CHECK: %[[p:.*]] = fir.load %[[pcoor]] : !fir.ref<!fir.box<!fir.array<10xf32>>>
Expand Down Expand Up @@ -229,7 +229,7 @@ subroutine test4

contains
! CHECK-LABEL: func private @_QFtest4Ptest4_inner(
! CHECK-SAME:%[[tup:.*]]: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME:%[[tup:.*]]: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine test4_inner
! CHECK: %[[ptup:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<f32>>>>
! CHECK: %[[p:.*]] = fir.load %[[ptup]] : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<f32>>>>
Expand Down Expand Up @@ -271,7 +271,7 @@ subroutine test5

contains
! CHECK-LABEL: func private @_QFtest5Ptest5_inner(
! CHECK-SAME:%[[tup:.*]]: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME:%[[tup:.*]]: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine test5_inner
! CHECK: %[[ptup:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>>
! CHECK: %[[p:.*]] = fir.load %[[ptup]] : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>>
Expand Down Expand Up @@ -309,7 +309,7 @@ subroutine test7(j, k)
contains

! CHECK-LABEL: func private @_QFtest7Ptest7_inner(
! CHECK-SAME: %[[i:.*]]: !fir.ref<i32>{{.*}}, %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) -> i32 attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[i:.*]]: !fir.ref<i32>{{.*}}, %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) -> i32 attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
elemental integer function test7_inner(i)
implicit none
integer, intent(in) :: i
Expand All @@ -330,7 +330,7 @@ subroutine issue990()
call bar()
contains
! CHECK-LABEL: func private @_QFissue990Pbar(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine bar()
integer :: stmt_func, i
stmt_func(i) = i + captured
Expand All @@ -352,7 +352,7 @@ subroutine issue990b()
call bar()
contains
! CHECK-LABEL: func private @_QFissue990bPbar(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine bar()
! CHECK: %[[tupAddr:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
! CHECK: %[[addr:.*]] = fir.load %[[tupAddr]] : !fir.llvm_ptr<!fir.ref<i32>>
Expand All @@ -373,7 +373,7 @@ real function dummy_proc(x)
call bar()
contains
! CHECK-LABEL: func private @_QFtest8Pbar(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.boxproc<() -> ()>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.boxproc<() -> ()>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine bar()
! CHECK: %[[tupAddr:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.boxproc<() -> ()>>>, i32) -> !fir.ref<!fir.boxproc<() -> ()>>
! CHECK: %[[dummyProc:.*]] = fir.load %[[tupAddr]] : !fir.ref<!fir.boxproc<() -> ()>>
Expand All @@ -393,7 +393,7 @@ subroutine dummy_proc()
call bar()
contains
! CHECK-LABEL: func private @_QFtest9Pbar(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.boxproc<() -> ()>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.boxproc<() -> ()>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine bar()
! CHECK: %[[tupAddr:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.boxproc<() -> ()>>>, i32) -> !fir.ref<!fir.boxproc<() -> ()>>
! CHECK: %[[dummyProc:.*]] = fir.load %[[tupAddr]] : !fir.ref<!fir.boxproc<() -> ()>>
Expand All @@ -416,7 +416,7 @@ subroutine test10(i)
call bar()
contains
! CHECK-LABEL: func private @_QFtest10Pbar(
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[tup:.*]]: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
subroutine bar()
! CHECK: %[[tupAddr:.*]] = fir.coordinate_of %[[tup]], %c0{{.*}} : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>>
! CHECK: fir.load %[[tupAddr]] : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>>
Expand All @@ -435,7 +435,7 @@ subroutine bar()

! CHECK-LABEL: func private @_QFtest_proc_dummyPtest_proc_dummy_a(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "j"},
! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32
! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.llvm_ptr<!fir.ref<i32>>
Expand Down Expand Up @@ -528,7 +528,7 @@ end subroutine test_proc_dummy_other
! CHECK-LABEL: func private @_QFtest_proc_dummy_charPgen_message(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1,10>>,
! CHECK-SAME: %[[VAL_1:.*]]: index,
! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<tuple<!fir.boxchar<1>>> {fir.host_assoc}) -> !fir.boxchar<1> attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<tuple<!fir.boxchar<1>>> {fir.host_assoc}) -> !fir.boxchar<1> attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 0 : i32
! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 10 : index
! CHECK-DAG: %[[VAL_5:.*]] = arith.constant false
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/polymorphic.f90
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ subroutine internal
end subroutine

! CHECK-LABEL: func.func private @_QMpolymorphic_testFhost_assocPinternal(
! CHECK-SAME: %[[TUPLE:.*]]: !fir.ref<tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>> {fir.host_assoc}) attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} {
! CHECK-SAME: %[[TUPLE:.*]]: !fir.ref<tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
! CHECK: %[[POS_IN_TUPLE:.*]] = arith.constant 0 : i32
! CHECK: %[[COORD_OF_CLASS:.*]] = fir.coordinate_of %[[TUPLE]], %[[POS_IN_TUPLE]] : (!fir.ref<tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>, i32) -> !fir.ref<!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
! CHECK: %[[CLASS:.*]] = fir.load %[[COORD_OF_CLASS]] : !fir.ref<!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
Expand Down
15 changes: 15 additions & 0 deletions flang/test/Semantics/OpenMP/threadprivate07.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp

! Check Threadprivate Directive with local variable of a BLOCK construct.

program main
call sub1()
print *, 'pass'
end program main

subroutine sub1()
BLOCK
integer, save :: a
!$omp threadprivate(a)
END BLOCK
end subroutine
4 changes: 2 additions & 2 deletions libc/hdr/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ add_proxy_header_library(
fenv_t.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.fenv_t
libc.incude.fenv
libc.include.fenv
)

add_proxy_header_library(
Expand All @@ -37,5 +37,5 @@ add_proxy_header_library(
fexcept_t.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.fexcept_t
libc.incude.fenv
libc.include.fenv
)
5 changes: 2 additions & 3 deletions libc/src/__support/macros/sanitizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,13 @@
// Functions to unpoison memory
//-----------------------------------------------------------------------------

#if defined(LIBC_HAVE_MEMORY_SANITIZER) && __has_builtin(__builtin_constant_p)
#if defined(LIBC_HAVE_MEMORY_SANITIZER)
// Only perform MSAN unpoison in non-constexpr context.
#include <sanitizer/msan_interface.h>
#define MSAN_UNPOISON(addr, size) \
do { \
if (!__builtin_constant_p(*addr)) { \
if (!__builtin_is_constant_evaluated()) \
__msan_unpoison(addr, size); \
} \
} while (0)
#else
#define MSAN_UNPOISON(ptr, size)
Expand Down
50 changes: 48 additions & 2 deletions libcxx/include/__chrono/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef _LIBCPP___CHRONO_FORMATTER_H
#define _LIBCPP___CHRONO_FORMATTER_H

#include <__algorithm/ranges_copy.h>
#include <__chrono/calendar.h>
#include <__chrono/concepts.h>
#include <__chrono/convert_to_tm.h>
Expand Down Expand Up @@ -170,10 +171,45 @@ _LIBCPP_HIDE_FROM_ABI void __format_century(basic_stringstream<_CharT>& __sstr,
__sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __century);
}

// Implements the %z format specifier according to [tab:time.format.spec], where
// '__modifier' signals %Oz or %Ez were used. (Both modifiers behave the same,
// so there is no need to distinguish between them.)
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI void
__format_zone_offset(basic_stringstream<_CharT>& __sstr, chrono::seconds __offset, bool __modifier) {
if (__offset < 0s) {
__sstr << _CharT('-');
__offset = -__offset;
} else {
__sstr << _CharT('+');
}

chrono::hh_mm_ss __hms{__offset};
std::ostreambuf_iterator<_CharT> __out_it{__sstr};
if (__modifier)
std::format_to(__out_it, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:%H:%M}"), __hms);
else
std::format_to(__out_it, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:%H%M}"), __hms);
}

// Helper to store the time zone information needed for formatting.
struct _LIBCPP_HIDE_FROM_ABI __time_zone {
// Typically these abbreviations are short and fit in the string's internal
// buffer.
string __abbrev;
chrono::seconds __offset;
};

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI __time_zone __convert_to_time_zone([[maybe_unused]] const _Tp& __value) {
return {"UTC", chrono::seconds{0}};
}

template <class _CharT, class _Tp>
_LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
basic_stringstream<_CharT>& __sstr, const _Tp& __value, basic_string_view<_CharT> __chrono_specs) {
tm __t = std::__convert_to_tm<tm>(__value);
__time_zone __z = __formatter::__convert_to_time_zone(__value);
const auto& __facet = std::use_facet<time_put<_CharT>>(__sstr.getloc());
for (auto __it = __chrono_specs.begin(); __it != __chrono_specs.end(); ++__it) {
if (*__it == _CharT('%')) {
Expand Down Expand Up @@ -296,9 +332,13 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
{__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
} break;

case _CharT('z'):
__formatter::__format_zone_offset(__sstr, __z.__offset, false);
break;

case _CharT('Z'):
// TODO FMT Add proper timezone support.
__sstr << _LIBCPP_STATICALLY_WIDEN(_CharT, "UTC");
// __abbrev is always a char so the copy may convert.
ranges::copy(__z.__abbrev, std::ostreambuf_iterator<_CharT>{__sstr});
break;

case _CharT('O'):
Expand All @@ -314,9 +354,15 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
break;
}
}

// Oz produces the same output as Ez below.
[[fallthrough]];
case _CharT('E'):
++__it;
if (*__it == 'z') {
__formatter::__format_zone_offset(__sstr, __z.__offset, true);
break;
}
[[fallthrough]];
default:
__facet.put(
Expand Down
39 changes: 4 additions & 35 deletions libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,12 +904,6 @@ static void test_valid_values_date_time() {

template <class CharT>
static void test_valid_values_time_zone() {
// The Apple CI gives %z='-0700' %Ez='-0700' %Oz='-0700' %Z='UTC'
// -0700 looks like the local time where the CI happens to reside, therefore
// omit this test on Apple.
// The Windows CI gives %z='-0000', but on local machines set to a different
// timezone, it gives e.g. %z='+0200'.
#if !defined(__APPLE__) && !defined(_WIN32)
using namespace std::literals::chrono_literals;

constexpr std::basic_string_view<CharT> fmt = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
Expand All @@ -918,48 +912,23 @@ static void test_valid_values_time_zone() {
const std::locale loc(LOCALE_ja_JP_UTF_8);
std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));

# if defined(_AIX)
// Non localized output using C-locale
check(SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
fmt,
file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use the global locale (fr_FR)
check(SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
lfmt,
file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use supplied locale (ja_JP). This locale has a different alternate.a
// Use supplied locale (ja_JP).
check(loc,
SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
lfmt,
file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
# else // defined(_AIX)
// Non localized output using C-locale
check(SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
fmt,
file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use the global locale (fr_FR)
check(SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
lfmt,
file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use supplied locale (ja_JP). This locale has a different alternate.a
# if defined(__FreeBSD__)
check(loc,
SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
lfmt,
file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
# else
check(loc,
SV("%z='+0000'\t%Ez='+0000'\t%Oz='+〇'\t%Z='UTC'\n"),
lfmt,
file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
# endif
# endif // defined(_AIX)
std::locale::global(std::locale::classic());
#endif // !defined(__APPLE__) && !defined(_WIN32)
}

template <class CharT>
Expand Down
39 changes: 4 additions & 35 deletions libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,12 +900,6 @@ static void test_valid_values_date_time() {

template <class CharT>
static void test_valid_values_time_zone() {
// The Apple CI gives %z='-0700' %Ez='-0700' %Oz='-0700' %Z='UTC'
// -0700 looks like the local time where the CI happens to reside, therefore
// omit this test on Apple.
// The Windows CI gives %z='-0000', but on local machines set to a different
// timezone, it gives e.g. %z='+0200'.
#if !defined(__APPLE__) && !defined(_WIN32)
using namespace std::literals::chrono_literals;

constexpr std::basic_string_view<CharT> fmt = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
Expand All @@ -914,48 +908,23 @@ static void test_valid_values_time_zone() {
const std::locale loc(LOCALE_ja_JP_UTF_8);
std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));

# if defined(_AIX)
// Non localized output using C-locale
check(SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
fmt,
std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use the global locale (fr_FR)
check(SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
lfmt,
std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use supplied locale (ja_JP). This locale has a different alternate.a
// Use supplied locale (ja_JP).
check(loc,
SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
lfmt,
std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
# else // defined(_AIX)
// Non localized output using C-locale
check(SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
fmt,
std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use the global locale (fr_FR)
check(SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
lfmt,
std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970

// Use supplied locale (ja_JP). This locale has a different alternate.a
# if defined(__FreeBSD__)
check(loc,
SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
lfmt,
std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
# else
check(loc,
SV("%z='+0000'\t%Ez='+0000'\t%Oz='+〇'\t%Z='UTC'\n"),
lfmt,
std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
# endif
# endif // defined(_AIX)
std::locale::global(std::locale::classic());
#endif // !defined(__APPLE__) && !defined(_WIN32)
}

template <class CharT>
Expand Down
2 changes: 1 addition & 1 deletion lldb/packages/Python/lldbsuite/test/dotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def parseOptionsAndInitTestdirs():
configuration.compiler = which(args.compiler)
if not is_exe(configuration.compiler):
logging.error(
"%s is not a valid compiler executable; aborting...", args.compiler
'"%s" is not a valid compiler executable; aborting...', args.compiler
)
sys.exit(-1)
else:
Expand Down
6 changes: 5 additions & 1 deletion lldb/test/API/functionalities/asan/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
C_SOURCES := main.c
CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
asan: all

libsanitizers: CFLAGS_EXTRAS := -fsanitize=address -fsanitize-stable-abi -g -gcolumn-info
libsanitizers: all

include Makefile.rules
Loading