29 changes: 29 additions & 0 deletions clang/test/SemaOpenCL/builtins-amdgcn-error-gfx950-param.cl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ typedef float float4 __attribute__((ext_vector_type(4)));
typedef float float16 __attribute__((ext_vector_type(16)));
typedef half half8 __attribute__((ext_vector_type(8)));
typedef __bf16 bfloat8 __attribute__((ext_vector_type(8)));
typedef int int4 __attribute__((ext_vector_type(4)));
typedef int int8 __attribute__((ext_vector_type(8)));
typedef int int16 __attribute__((ext_vector_type(16)));


void test_mfma_f32_16x16x32_f16(__global float4* out, half8 a, half8 b, float4 c, int X) {
Expand All @@ -26,3 +29,29 @@ void test_mfma_f32_32x32x16_bf16(__global float16* out, bfloat8 a, bfloat8 b, fl
*out = __builtin_amdgcn_mfma_f32_32x32x16_bf16(a, b, c, 0, X, 0); // expected-error{{argument to '__builtin_amdgcn_mfma_f32_32x32x16_bf16' must be a constant integer}}
*out = __builtin_amdgcn_mfma_f32_32x32x16_bf16(a, b, c, 0, 0, X); // expected-error{{argument to '__builtin_amdgcn_mfma_f32_32x32x16_bf16' must be a constant integer}}
}

void test_mfma_scale_f32_16x16x128_f8f6f4(__global float4* out, int8 a, int8 b, float4 c, int X, int Y) {
*out = __builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4(a, b, c, X, 0, 1, Y, 2, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4' must be a constant integer}}
*out = __builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4(a, b, c, 0, X, 1, Y, 2, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4' must be a constant integer}}
*out = __builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4(a, b, c, 0, 0, X, Y, 2, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4' must be a constant integer}}
*out = __builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4(a, b, c, 0, 0, 0, Y, X, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4' must be a constant integer}}
}

void test_mfma_scale_f32_32x32x64_f8f6f4(__global float16* out, int8 a, int8 b, float16 c, int X, int Y) {
*out = __builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4(a, b, c, X, 0, 1, Y, 2, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4' must be a constant integer}}
*out = __builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4(a, b, c, 0, X, 1, Y, 2, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4' must be a constant integer}}
*out = __builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4(a, b, c, 0, 0, X, Y, 2, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4' must be a constant integer}}
*out = __builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4(a, b, c, 0, 0, 0, Y, X, Y); // expected-error{{argument to '__builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4' must be a constant integer}}
}

void test_mfma_i32_16x16x64_i8(__global int4* out, int4 a, int4 b, int4 c, int X) {
*out = __builtin_amdgcn_mfma_i32_16x16x64_i8(a, b, c, X, 0, 0); // expected-error{{argument to '__builtin_amdgcn_mfma_i32_16x16x64_i8' must be a constant integer}}
*out = __builtin_amdgcn_mfma_i32_16x16x64_i8(a, b, c, 0, X, 0); // expected-error{{argument to '__builtin_amdgcn_mfma_i32_16x16x64_i8' must be a constant integer}}
*out = __builtin_amdgcn_mfma_i32_16x16x64_i8(a, b, c, 0, 0, X); // expected-error{{argument to '__builtin_amdgcn_mfma_i32_16x16x64_i8' must be a constant integer}}
}

void test_mfma_i32_32x32x32_i8(__global int16* out, int4 a, int4 b, int16 c, int X) {
*out = __builtin_amdgcn_mfma_i32_32x32x32_i8(a, b, c, X, 0, 0); // expected-error{{argument to '__builtin_amdgcn_mfma_i32_32x32x32_i8' must be a constant integer}}
*out = __builtin_amdgcn_mfma_i32_32x32x32_i8(a, b, c, 0, X, 0); // expected-error{{argument to '__builtin_amdgcn_mfma_i32_32x32x32_i8' must be a constant integer}}
*out = __builtin_amdgcn_mfma_i32_32x32x32_i8(a, b, c, 0, 0, X); // expected-error{{argument to '__builtin_amdgcn_mfma_i32_32x32x32_i8' must be a constant integer}}
}
25 changes: 24 additions & 1 deletion clang/test/SemaOpenCL/builtins-amdgcn-error-gfx950.cl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,35 @@
typedef float float4 __attribute__((ext_vector_type(4)));
typedef float float16 __attribute__((ext_vector_type(16)));
typedef half half8 __attribute__((ext_vector_type(8)));
typedef half half16 __attribute__((ext_vector_type(16)));
typedef __bf16 bfloat8 __attribute__((ext_vector_type(8)));
typedef __bf16 bfloat16 __attribute__((ext_vector_type(16)));
typedef unsigned int uint2 __attribute__((ext_vector_type(2)));
typedef int int4 __attribute__((ext_vector_type(4)));
typedef int int8 __attribute__((ext_vector_type(8)));
typedef int int16 __attribute__((ext_vector_type(16)));

void test(__global float4* out0, half8 a0, half8 b0, float4 c0,
__global float16* out1, half8 a1, half8 b1, float16 c1,
__global float16* out2, bfloat8 a2, bfloat8 b2, float16 c2) {
__global float16* out2, bfloat8 a2, bfloat8 b2, float16 c2,
__global int4* out3, int4 a3, int4 b3, int4 c3,
__global int16* out4, int4 a4, int4 b4, int16 c4,
__global float4* out5, bfloat8 a5, bfloat8 b5, float4 c5,
__global float4* out6, half8 a6, half16 b6, float4 c6,
__global float16* out7, half8 a7, half16 b7, float16 c7,
__global float4* out8, bfloat8 a8, bfloat16 b8, float4 c8,
__global float16* out9, bfloat8 a9, bfloat16 b9, float16 c9,
__global int4* out10, int4 a10, int8 b10, int4 c10,
__global int16* out11, int4 a11, int8 b11, int16 c11,
__global float4* out12, int4 a12, int8 b12, float4 c12,
__global float16* out13, int4 a13, int8 b13, float16 c13,
__global float4* out14, int8 a14, int8 b14, float4 c14, int d14, int e14,
__global float16* out15, int8 a15, int8 b15, float16 c15, int d15, int e15) {
*out0 = __builtin_amdgcn_mfma_f32_16x16x32_f16(a0, b0, c0, 0, 0, 0); // expected-error{{'__builtin_amdgcn_mfma_f32_16x16x32_f16' needs target feature gfx950-insts}}
*out1 = __builtin_amdgcn_mfma_f32_32x32x16_f16(a1, b1, c1, 0, 0, 0); // expected-error{{'__builtin_amdgcn_mfma_f32_32x32x16_f16' needs target feature gfx950-insts}}
*out2 = __builtin_amdgcn_mfma_f32_32x32x16_bf16(a2, b2, c2, 0, 0, 0); // expected-error{{'__builtin_amdgcn_mfma_f32_32x32x16_bf16' needs target feature gfx950-insts}}
*out3 = __builtin_amdgcn_mfma_i32_16x16x64_i8(a3, b3, c3, 0, 0, 0); // expected-error{{'__builtin_amdgcn_mfma_i32_16x16x64_i8' needs target feature gfx950-insts}}
*out4 = __builtin_amdgcn_mfma_i32_32x32x32_i8(a4, b4, c4, 0, 0, 0); // expected-error{{'__builtin_amdgcn_mfma_i32_32x32x32_i8' needs target feature gfx950-insts}}
*out14 = __builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4(a14, b14, c14, 0, 0, 0, d14, 0, e14); // expected-error{{'__builtin_amdgcn_mfma_scale_f32_16x16x128_f8f6f4' needs target feature gfx950-insts}}
*out15 = __builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4(a15, b15, c15, 0, 0, 0, d15, 0, e15); // expected-error{{'__builtin_amdgcn_mfma_scale_f32_32x32x64_f8f6f4' needs target feature gfx950-insts}}
}
9 changes: 6 additions & 3 deletions clang/tools/c-index-test/core_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
Expand Down Expand Up @@ -219,8 +220,9 @@ static bool printSourceSymbols(const char *Executable,
SmallVector<const char *, 4> ArgsWithProgName;
ArgsWithProgName.push_back(Executable);
ArgsWithProgName.append(Args.begin(), Args.end());
IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
new DiagnosticOptions));
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
Expand Down Expand Up @@ -273,7 +275,8 @@ static bool printSourceSymbolsFromModule(StringRef modulePath,
auto HSOpts = std::make_shared<HeaderSearchOptions>();

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
new DiagnosticOptions());
std::unique_ptr<ASTUnit> AU =
ASTUnit::LoadFromASTFile(modulePath, *pchRdr, ASTUnit::LoadASTOnly, Diags,
FileSystemOpts, HSOpts, /*LangOpts=*/nullptr,
Expand Down
4 changes: 3 additions & 1 deletion clang/tools/clang-import-test/clang-import-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Host.h"

#include <memory>
Expand Down Expand Up @@ -164,7 +165,8 @@ std::unique_ptr<CompilerInstance> BuildCompilerInstance() {
auto Ins = std::make_unique<CompilerInstance>();
auto DC = std::make_unique<TestDiagnosticConsumer>();
const bool ShouldOwnClient = true;
Ins->createDiagnostics(DC.release(), ShouldOwnClient);
Ins->createDiagnostics(*llvm::vfs::getRealFileSystem(), DC.release(),
ShouldOwnClient);

auto Inv = std::make_unique<CompilerInvocation>();

Expand Down
2 changes: 1 addition & 1 deletion clang/tools/clang-installapi/ClangInstallAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ static bool run(ArrayRef<const char *> Args, const char *ProgName) {
// Set up compilation.
std::unique_ptr<CompilerInstance> CI(new CompilerInstance());
CI->setFileManager(FM.get());
CI->createDiagnostics();
CI->createDiagnostics(FM->getVirtualFileSystem());
if (!CI->hasDiagnostics())
return EXIT_FAILURE;

Expand Down
7 changes: 5 additions & 2 deletions clang/tools/clang-scan-deps/ClangScanDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Host.h"
#include <mutex>
#include <optional>
Expand Down Expand Up @@ -424,7 +425,8 @@ class FullDeps {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions{};
TextDiagnosticPrinter DiagConsumer(ErrOS, &*DiagOpts);
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(&*DiagOpts, &DiagConsumer,
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
&*DiagOpts, &DiagConsumer,
/*ShouldOwnClient=*/false);

for (auto &&M : Modules)
Expand Down Expand Up @@ -739,7 +741,8 @@ getCompilationDatabase(int argc, char **argv, std::string &ErrorMessage) {
tooling::JSONCommandLineSyntax::AutoDetect);

llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions);
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
new DiagnosticOptions);
driver::Driver TheDriver(CommandLine[0], llvm::sys::getDefaultTargetTriple(),
*Diags);
TheDriver.setCheckInputsExist(false);
Expand Down
4 changes: 3 additions & 1 deletion clang/tools/diagtool/ShowEnabledWarnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/VirtualFileSystem.h"

DEF_DIAGTOOL("show-enabled",
"Show which warnings are enabled for a given command line",
Expand Down Expand Up @@ -74,7 +75,8 @@ createDiagnostics(unsigned int argc, char **argv) {

// Build the diagnostics parser
IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts());
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
&Invocation->getDiagnosticOpts());
if (!FinalDiags)
return nullptr;

Expand Down
3 changes: 2 additions & 1 deletion clang/tools/driver/cc1_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/AArch64TargetParser.h"
Expand Down Expand Up @@ -264,7 +265,7 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
CompilerInvocation::GetResourcesPath(Argv0, MainAddr);

// Create the actual diagnostics engine.
Clang->createDiagnostics();
Clang->createDiagnostics(*llvm::vfs::getRealFileSystem());
if (!Clang->hasDiagnostics())
return 1;

Expand Down
7 changes: 5 additions & 2 deletions clang/tools/libclang/CIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/thread.h"
#include <mutex>
Expand Down Expand Up @@ -4092,7 +4093,8 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
auto HSOpts = std::make_shared<HeaderSearchOptions>();

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
new DiagnosticOptions());
std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
ASTUnit::LoadEverything, Diags, FileSystemOpts, HSOpts,
Expand Down Expand Up @@ -4165,7 +4167,8 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
std::unique_ptr<DiagnosticOptions> DiagOpts = CreateAndPopulateDiagOpts(
llvm::ArrayRef(command_line_args, num_command_line_args));
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
CompilerInstance::createDiagnostics(DiagOpts.release()));
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
DiagOpts.release()));

if (options & CXTranslationUnit_KeepGoing)
Diags->setFatalsAsError(true);
Expand Down
9 changes: 5 additions & 4 deletions clang/tools/libclang/Indexing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <cstdio>
#include <mutex>
#include <utility>
Expand Down Expand Up @@ -479,10 +480,10 @@ static CXErrorCode clang_indexSourceFile_Impl(
CaptureDiag = new CaptureDiagnosticConsumer();

// Configure the diagnostics.
IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
CaptureDiag,
/*ShouldOwnClient=*/true));
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
new DiagnosticOptions, CaptureDiag,
/*ShouldOwnClient=*/true));

// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
Expand Down
5 changes: 3 additions & 2 deletions clang/unittests/AST/ExternalASTSourceTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"

using namespace clang;
Expand Down Expand Up @@ -46,7 +47,7 @@ class TestFrontendAction : public ASTFrontendAction {
bool testExternalASTSource(ExternalASTSource *Source,
StringRef FileContents) {
CompilerInstance Compiler;
Compiler.createDiagnostics();
Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

auto Invocation = std::make_shared<CompilerInvocation>();
Invocation->getPreprocessorOpts().addRemappedFile(
Expand Down
3 changes: 2 additions & 1 deletion clang/unittests/CodeGen/TestCompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Host.h"

namespace llvm {
Expand All @@ -35,7 +36,7 @@ struct TestCompiler {
clang::CodeGenOptions CGO = clang::CodeGenOptions()) {
compiler.getLangOpts() = LO;
compiler.getCodeGenOpts() = CGO;
compiler.createDiagnostics();
compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

std::string TrStr = llvm::Triple::normalize(llvm::sys::getProcessTriple());
llvm::Triple Tr(TrStr);
Expand Down
3 changes: 2 additions & 1 deletion clang/unittests/Driver/DXCModeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ TEST(DxcModeTest, DefaultEntry) {
const char *Args[] = {"clang", "--driver-mode=dxc", "-Tcs_6_7", "foo.hlsl"};

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CompilerInstance::createDiagnostics(*InMemoryFileSystem,
new DiagnosticOptions());

CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/Driver/ToolChainTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ TEST(CompilerInvocation, SplitSwarfSingleCrash) {

TEST(ToolChainTest, UEFICallingConventionTest) {
clang::CompilerInstance compiler;
compiler.createDiagnostics();
compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

std::string TrStr = "x86_64-unknown-uefi";
llvm::Triple Tr(TrStr);
Expand Down
17 changes: 11 additions & 6 deletions clang/unittests/Frontend/ASTUnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"

using namespace llvm;
Expand All @@ -41,17 +42,18 @@ class ASTUnitTest : public ::testing::Test {

const char *Args[] = {"clang", "-xc++", InputFileName.c_str()};

Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
auto VFS = llvm::vfs::getRealFileSystem();
Diags = CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions());

CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.VFS = VFS;
CInvok = createInvocation(Args, std::move(CIOpts));

if (!CInvok)
return nullptr;

FileManager *FileMgr =
new FileManager(FileSystemOptions(), vfs::getRealFileSystem());
FileManager *FileMgr = new FileManager(FileSystemOptions(), VFS);
PCHContainerOps = std::make_shared<PCHContainerOperations>();

return ASTUnit::LoadFromCompilerInvocation(
Expand Down Expand Up @@ -134,7 +136,8 @@ TEST_F(ASTUnitTest, ModuleTextualHeader) {

const char *Args[] = {"clang", "test.cpp", "-fmodule-map-file=m.modulemap",
"-fmodule-name=M"};
Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
Diags =
CompilerInstance::createDiagnostics(*InMemoryFs, new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CInvok = createInvocation(Args, std::move(CIOpts));
Expand Down Expand Up @@ -162,7 +165,8 @@ TEST_F(ASTUnitTest, LoadFromCommandLineEarlyError) {

const char *Args[] = {"clang", "-target", "foobar", InputFileName.c_str()};

auto Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
auto Diags = CompilerInstance::createDiagnostics(
*llvm::vfs::getRealFileSystem(), new DiagnosticOptions());
auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
std::unique_ptr<clang::ASTUnit> ErrUnit;

Expand All @@ -189,7 +193,8 @@ TEST_F(ASTUnitTest, LoadFromCommandLineWorkingDirectory) {
const char *Args[] = {"clang", "-working-directory", WorkingDir.c_str(),
InputFileName.c_str()};

auto Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
auto Diags = CompilerInstance::createDiagnostics(
*llvm::vfs::getRealFileSystem(), new DiagnosticOptions());
auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
std::unique_ptr<clang::ASTUnit> ErrUnit;

Expand Down
7 changes: 4 additions & 3 deletions clang/unittests/Frontend/CodeGenActionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"

using namespace llvm;
Expand Down Expand Up @@ -52,7 +53,7 @@ TEST(CodeGenTest, TestNullCodeGen) {
Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
CompilerInstance Compiler;
Compiler.setInvocation(std::move(Invocation));
Compiler.createDiagnostics();
Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());
EXPECT_TRUE(Compiler.hasDiagnostics());

std::unique_ptr<FrontendAction> Act(new NullCodeGenAction);
Expand All @@ -70,7 +71,7 @@ TEST(CodeGenTest, CodeGenFromIRMemBuffer) {
Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
CompilerInstance Compiler;
Compiler.setInvocation(std::move(Invocation));
Compiler.createDiagnostics();
Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());
EXPECT_TRUE(Compiler.hasDiagnostics());

EmitLLVMOnlyAction Action;
Expand Down Expand Up @@ -101,7 +102,7 @@ TEST(CodeGenTest, DebugInfoCWDCodeGen) {
SmallString<256> IRBuffer;
Compiler.setOutputStream(std::make_unique<raw_svector_ostream>(IRBuffer));
Compiler.setInvocation(std::move(Invocation));
Compiler.createDiagnostics();
Compiler.createDiagnostics(*VFS);
Compiler.createFileManager(std::move(VFS));

EmitLLVMAction Action;
Expand Down
9 changes: 6 additions & 3 deletions clang/unittests/Frontend/CompilerInstanceTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"

using namespace llvm;
Expand Down Expand Up @@ -53,7 +54,8 @@ TEST(CompilerInstance, DefaultVFSOverlayFromInvocation) {
const char *Args[] = {"clang", VFSArg.c_str(), "-xc++", "-"};

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
new DiagnosticOptions());

CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
Expand Down Expand Up @@ -87,8 +89,9 @@ TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) {
auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
DiagnosticsOS, new DiagnosticOptions());
CompilerInstance Instance;
IntrusiveRefCntPtr<DiagnosticsEngine> Diags = Instance.createDiagnostics(
DiagOpts, DiagPrinter.get(), /*ShouldOwnClient=*/false);
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
Instance.createDiagnostics(*llvm::vfs::getRealFileSystem(), DiagOpts,
DiagPrinter.get(), /*ShouldOwnClient=*/false);

Diags->Report(diag::err_expected) << "no crash";
ASSERT_EQ(DiagnosticOutput, "error: expected no crash\n");
Expand Down
7 changes: 4 additions & 3 deletions clang/unittests/Frontend/CompilerInvocationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Host.h"

#include "gmock/gmock.h"
Expand All @@ -38,9 +39,9 @@ class CommandLineTest : public ::testing::Test {
}

CommandLineTest()
: Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions(),
new TextDiagnosticBuffer())) {
}
: Diags(CompilerInstance::createDiagnostics(
*llvm::vfs::getRealFileSystem(), new DiagnosticOptions(),
new TextDiagnosticBuffer())) {}
};

template <typename M>
Expand Down
14 changes: 8 additions & 6 deletions clang/unittests/Frontend/FrontendActionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "clang/Serialization/InMemoryModuleCache.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Triple.h"
#include "gtest/gtest.h"

Expand Down Expand Up @@ -90,7 +91,7 @@ TEST(ASTFrontendAction, Sanity) {
invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
CompilerInstance compiler;
compiler.setInvocation(std::move(invocation));
compiler.createDiagnostics();
compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

TestASTFrontendAction test_action;
ASSERT_TRUE(compiler.ExecuteAction(test_action));
Expand All @@ -110,7 +111,7 @@ TEST(ASTFrontendAction, IncrementalParsing) {
invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
CompilerInstance compiler;
compiler.setInvocation(std::move(invocation));
compiler.createDiagnostics();
compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true);
ASSERT_TRUE(compiler.ExecuteAction(test_action));
Expand All @@ -137,7 +138,7 @@ TEST(ASTFrontendAction, LateTemplateIncrementalParsing) {
invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
CompilerInstance compiler;
compiler.setInvocation(std::move(invocation));
compiler.createDiagnostics();
compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true,
/*actOnEndOfTranslationUnit=*/true);
Expand Down Expand Up @@ -183,7 +184,7 @@ TEST(PreprocessorFrontendAction, EndSourceFile) {
Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
CompilerInstance Compiler;
Compiler.setInvocation(std::move(Invocation));
Compiler.createDiagnostics();
Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

TestPPCallbacks *Callbacks = new TestPPCallbacks;
TestPPCallbacksFrontendAction TestAction(Callbacks);
Expand Down Expand Up @@ -245,7 +246,8 @@ TEST(ASTFrontendAction, ExternalSemaSource) {
CompilerInstance Compiler;
Compiler.setInvocation(std::move(Invocation));
auto *TDC = new TypoDiagnosticConsumer;
Compiler.createDiagnostics(TDC, /*ShouldOwnClient=*/true);
Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem(), TDC,
/*ShouldOwnClient=*/true);
Compiler.setExternalSemaSource(new TypoExternalSemaSource(Compiler));

SyntaxOnlyAction TestAction;
Expand Down Expand Up @@ -277,7 +279,7 @@ TEST(GeneratePCHFrontendAction, CacheGeneratedPCH) {
Invocation->getTargetOpts().Triple = "x86_64-apple-darwin19.0.0";
CompilerInstance Compiler;
Compiler.setInvocation(std::move(Invocation));
Compiler.createDiagnostics();
Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

GeneratePCHAction TestAction;
ASSERT_TRUE(Compiler.ExecuteAction(TestAction));
Expand Down
5 changes: 4 additions & 1 deletion clang/unittests/Frontend/OutputStreamTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/FrontendTool/Utils.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"

using namespace llvm;
Expand All @@ -37,7 +38,7 @@ TEST(FrontendOutputTests, TestOutputStream) {

Compiler.setOutputStream(std::move(IRStream));
Compiler.setInvocation(std::move(Invocation));
Compiler.createDiagnostics();
Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

bool Success = ExecuteCompilerInvocation(&Compiler);
EXPECT_TRUE(Success);
Expand All @@ -62,6 +63,7 @@ TEST(FrontendOutputTests, TestVerboseOutputStreamShared) {
Compiler.setInvocation(std::move(Invocation));
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
Compiler.createDiagnostics(
*llvm::vfs::getRealFileSystem(),
new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
Compiler.setVerboseOutputStream(VerboseStream);

Expand Down Expand Up @@ -91,6 +93,7 @@ TEST(FrontendOutputTests, TestVerboseOutputStreamOwned) {
Compiler.setInvocation(std::move(Invocation));
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
Compiler.createDiagnostics(
*llvm::vfs::getRealFileSystem(),
new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
Compiler.setVerboseOutputStream(std::move(VerboseStream));

Expand Down
5 changes: 3 additions & 2 deletions clang/unittests/Frontend/PCHPreambleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ class PCHPreambleTest : public ::testing::Test {
PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
PPOpts.RemappedFilesKeepOriginalName = true;

IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions, new DiagnosticConsumer));
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions,
new DiagnosticConsumer));

FileManager *FileMgr = new FileManager(FSOpts, VFS);

Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/Frontend/ReparseWorkingDirTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ReparseWorkingDirTest : public ::testing::Test {
CI->getTargetOpts().Triple = "i386-unknown-linux-gnu";

IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
CompilerInstance::createDiagnostics(new DiagnosticOptions,
CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions,
new DiagnosticConsumer));

FileManager *FileMgr = new FileManager(CI->getFileSystemOpts(), VFS);
Expand Down
6 changes: 3 additions & 3 deletions clang/unittests/Frontend/UtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ TEST(BuildCompilerInvocationTest, RecoverMultipleJobs) {
clang::IgnoringDiagConsumer D;
CreateInvocationOptions Opts;
Opts.RecoverOnError = true;
Opts.Diags = clang::CompilerInstance::createDiagnostics(new DiagnosticOptions,
&D, false);
Opts.VFS = new llvm::vfs::InMemoryFileSystem();
Opts.Diags = clang::CompilerInstance::createDiagnostics(
*Opts.VFS, new DiagnosticOptions, &D, false);
std::unique_ptr<CompilerInvocation> CI = createInvocation(Args, Opts);
ASSERT_TRUE(CI);
EXPECT_THAT(CI->TargetOpts->Triple, testing::StartsWith("i386-"));
Expand All @@ -46,7 +46,7 @@ TEST(BuildCompilerInvocationTest, ProbePrecompiled) {

clang::IgnoringDiagConsumer D;
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine =
clang::CompilerInstance::createDiagnostics(new DiagnosticOptions, &D,
clang::CompilerInstance::createDiagnostics(*FS, new DiagnosticOptions, &D,
false);
// Default: ProbePrecompiled=false
CreateInvocationOptions CIOpts;
Expand Down
7 changes: 4 additions & 3 deletions clang/unittests/Sema/SemaNoloadLookupTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ class NoloadLookupTest : public ::testing::Test {
std::string FileName = llvm::Twine(ModuleName + ".cppm").str();
addFile(FileName, Contents);

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.VFS = llvm::vfs::getRealFileSystem();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*CIOpts.VFS,
new DiagnosticOptions());
CIOpts.Diags = Diags;
CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();

std::string CacheBMIPath =
llvm::Twine(TestDir + "/" + ModuleName + ".pcm").str();
Expand Down
15 changes: 9 additions & 6 deletions clang/unittests/Serialization/ForceCheckFileInputTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ export int aa = 43;
std::string BMIPath = llvm::Twine(TestDir + "/a.pcm").str();

{
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*CIOpts.VFS,
new DiagnosticOptions());
CIOpts.Diags = Diags;

const char *Args[] = {"clang++", "-std=c++20",
"--precompile", "-working-directory",
TestDir.c_str(), "a.cppm"};
Expand Down Expand Up @@ -103,11 +105,12 @@ export int aa = 43;
}

{
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*CIOpts.VFS,
new DiagnosticOptions());
CIOpts.Diags = Diags;

std::string BMIPath = llvm::Twine(TestDir + "/a.pcm").str();
const char *Args[] = {
Expand Down
12 changes: 6 additions & 6 deletions clang/unittests/Serialization/ModuleCacheTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) {

SmallString<256> MCPArg("-fmodules-cache-path=");
MCPArg.append(ModuleCachePath);
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
CIOpts.Diags = Diags;

// First run should pass with no errors
const char *Args[] = {"clang", "-fmodules", "-Fframeworks",
Expand Down Expand Up @@ -156,11 +156,11 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) {

SmallString<256> MCPArg("-fmodules-cache-path=");
MCPArg.append(ModuleCachePath);
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
CIOpts.Diags = Diags;

// First run should pass with no errors
const char *Args[] = {"clang", "-fmodules", "-Fframeworks",
Expand Down
6 changes: 3 additions & 3 deletions clang/unittests/Serialization/NoCommentsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ export module Comments;
void foo() {}
)cpp");

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
CIOpts.Diags = Diags;

std::string CacheBMIPath = llvm::Twine(TestDir + "/Comments.pcm").str();
const char *Args[] = {"clang++", "-std=c++20",
Expand Down
4 changes: 2 additions & 2 deletions clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ export using ::E;
)cpp",
MainFilePath);

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
llvm::vfs::createPhysicalFileSystem();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions());

CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
Expand Down
6 changes: 3 additions & 3 deletions clang/unittests/Serialization/VarDeclConstantInitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ export namespace Fibonacci
}
)cpp");

IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
CIOpts.Diags = Diags;

const char *Args[] = {"clang++", "-std=c++20",
"--precompile", "-working-directory",
Expand Down
4 changes: 2 additions & 2 deletions clang/unittests/Support/TimeProfilerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ std::string teardownProfiler() {
// We only parse AST here. This is enough for constexpr evaluation.
bool compileFromString(StringRef Code, StringRef Standard, StringRef File,
llvm::StringMap<std::string> Headers = {}) {
CompilerInstance Compiler;
Compiler.createDiagnostics();

llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
new llvm::vfs::InMemoryFileSystem());
Expand All @@ -57,6 +55,8 @@ bool compileFromString(StringRef Code, StringRef Standard, StringRef File,
}
llvm::IntrusiveRefCntPtr<FileManager> Files(
new FileManager(FileSystemOptions(), FS));
CompilerInstance Compiler;
Compiler.createDiagnostics(Files->getVirtualFileSystem());
Compiler.setFileManager(Files.get());

auto Invocation = std::make_shared<CompilerInvocation>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class TestDependencyScanningAction : public tooling::ToolAction {
Compiler.setInvocation(std::move(Invocation));
Compiler.setFileManager(FileMgr);

Compiler.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
Compiler.createDiagnostics(FileMgr->getVirtualFileSystem(), DiagConsumer,
/*ShouldOwnClient=*/false);
if (!Compiler.hasDiagnostics())
return false;

Expand Down
3 changes: 2 additions & 1 deletion clang/unittests/Tooling/ToolingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@ struct CommandLineExtractorTest : public ::testing::Test {
public:
CommandLineExtractorTest()
: InMemoryFS(new llvm::vfs::InMemoryFileSystem),
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)),
Diags(CompilerInstance::createDiagnostics(*InMemoryFS,
new DiagnosticOptions)),
Driver("clang", llvm::sys::getDefaultTargetTriple(), *Diags,
"clang LLVM compiler", overlayRealFS(InMemoryFS)) {}

Expand Down
52 changes: 34 additions & 18 deletions clang/utils/TableGen/NeonEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ enum EltType {
Float16,
Float32,
Float64,
BFloat16
BFloat16,
MFloat8 // Not used by Sema or CodeGen in Clang
};

} // end namespace NeonTypeFlags
Expand Down Expand Up @@ -143,14 +144,7 @@ class Type {
private:
TypeSpec TS;

enum TypeKind {
Void,
Float,
SInt,
UInt,
Poly,
BFloat16
};
enum TypeKind { Void, Float, SInt, UInt, Poly, BFloat16, MFloat8 };
TypeKind Kind;
bool Immediate, Constant, Pointer;
// ScalarForMangling and NoManglingQ are really not suited to live here as
Expand Down Expand Up @@ -203,6 +197,7 @@ class Type {
bool isLong() const { return isInteger() && ElementBitwidth == 64; }
bool isVoid() const { return Kind == Void; }
bool isBFloat16() const { return Kind == BFloat16; }
bool isMFloat8() const { return Kind == MFloat8; }
unsigned getNumElements() const { return Bitwidth / ElementBitwidth; }
unsigned getSizeInBits() const { return Bitwidth; }
unsigned getElementSizeInBits() const { return ElementBitwidth; }
Expand Down Expand Up @@ -657,6 +652,8 @@ std::string Type::str() const {
S += "float";
else if (isBFloat16())
S += "bfloat";
else if (isMFloat8())
S += "mfloat";
else
S += "int";

Expand Down Expand Up @@ -699,6 +696,9 @@ std::string Type::builtin_str() const {
else if (isBFloat16()) {
assert(ElementBitwidth == 16 && "BFloat16 can only be 16 bits");
S += "y";
} else if (isMFloat8()) {
assert(ElementBitwidth == 8 && "MFloat8 can only be 8 bits");
S += "m";
} else
switch (ElementBitwidth) {
case 16: S += "h"; break;
Expand Down Expand Up @@ -758,6 +758,10 @@ unsigned Type::getNeonEnum() const {
Base = (unsigned)NeonTypeFlags::BFloat16;
}

if (isMFloat8()) {
Base = (unsigned)NeonTypeFlags::MFloat8;
}

if (Bitwidth == 128)
Base |= (unsigned)NeonTypeFlags::QuadFlag;
if (isInteger() && !isSigned())
Expand All @@ -779,6 +783,8 @@ Type Type::fromTypedefName(StringRef Name) {
T.Kind = Poly;
} else if (Name.consume_front("bfloat")) {
T.Kind = BFloat16;
} else if (Name.consume_front("mfloat")) {
T.Kind = MFloat8;
} else {
assert(Name.starts_with("int"));
Name = Name.drop_front(3);
Expand Down Expand Up @@ -879,6 +885,10 @@ void Type::applyTypespec(bool &Quad) {
Kind = BFloat16;
ElementBitwidth = 16;
break;
case 'm':
Kind = MFloat8;
ElementBitwidth = 8;
break;
default:
llvm_unreachable("Unhandled type code!");
}
Expand Down Expand Up @@ -993,6 +1003,9 @@ std::string Intrinsic::getInstTypeCode(Type T, ClassKind CK) const {
if (T.isBFloat16())
return "bf16";

if (T.isMFloat8())
return "mfp8";

if (T.isPoly())
typeCode = 'p';
else if (T.isInteger())
Expand Down Expand Up @@ -1030,7 +1043,7 @@ std::string Intrinsic::getBuiltinTypeStr() {

Type RetT = getReturnType();
if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar() &&
!RetT.isFloating() && !RetT.isBFloat16())
!RetT.isFloating() && !RetT.isBFloat16() && !RetT.isMFloat8())
RetT.makeInteger(RetT.getElementSizeInBits(), false);

// Since the return value must be one type, return a vector type of the
Expand Down Expand Up @@ -2270,7 +2283,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
for (auto &TS : TDTypeVec) {
bool IsA64 = false;
Type T(TS, ".");
if (T.isDouble())
if (T.isDouble() || T.isMFloat8())
IsA64 = true;

if (InIfdef && !IsA64) {
Expand All @@ -2282,15 +2295,20 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
InIfdef = true;
}

if (T.isPoly())
if (T.isMFloat8())
OS << "typedef __MFloat8x";
else if (T.isPoly())
OS << "typedef __attribute__((neon_polyvector_type(";
else
OS << "typedef __attribute__((neon_vector_type(";

Type T2 = T;
T2.makeScalar();
OS << T.getNumElements() << "))) ";
OS << T2.str();
OS << T.getNumElements();
if (T.isMFloat8())
OS << "_t ";
else
OS << "))) " << T2.str();
OS << " " << T.str() << ";\n";
}
if (InIfdef)
Expand All @@ -2303,7 +2321,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
for (auto &TS : TDTypeVec) {
bool IsA64 = false;
Type T(TS, ".");
if (T.isDouble())
if (T.isDouble() || T.isMFloat8())
IsA64 = true;

if (InIfdef && !IsA64) {
Expand Down Expand Up @@ -2589,8 +2607,6 @@ void NeonEmitter::runVectorTypes(raw_ostream &OS) {

OS << "#if defined(__aarch64__) || defined(__arm64ec__)\n";
OS << "typedef __mfp8 mfloat8_t;\n";
OS << "typedef __MFloat8x8_t mfloat8x8_t;\n";
OS << "typedef __MFloat8x16_t mfloat8x16_t;\n";
OS << "typedef double float64_t;\n";
OS << "#endif\n\n";

Expand Down Expand Up @@ -2648,7 +2664,7 @@ __arm_set_fpm_lscale2(fpm_t __fpm, uint64_t __scale) {
)";

emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQd", OS);
emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlmQmhQhfQfdQd", OS);

emitNeonTypeDefs("bQb", OS);
OS << "#endif // __ARM_NEON_TYPES_H\n";
Expand Down
9 changes: 9 additions & 0 deletions cmake/Modules/CMakePolicy.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,13 @@ endif()
# building with the Apple linker.
if(POLICY CMP0156)
cmake_policy(SET CMP0156 NEW)

# CMP0179: De-duplication of static libraries on link lines keeps first occurrence.
# Dependent on CMP0156=NEW. Unifies the behaviour across platforms.
# Works around a LLD bug ELF backend bug (#116669) and required for CMP0156
# to have an effect for affected versions. Also fixes building with CMake 3.31.0,
# which lacked the workaround of ignoring CMP0156 unless this is enabled.
if(POLICY CMP0179)
cmake_policy(SET CMP0179 NEW)
endif()
endif()
40 changes: 16 additions & 24 deletions compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,41 +194,33 @@ static int WriteBinaryIds(ProfDataWriter *Writer, const ElfW(Nhdr) * Note,
*/
COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) {
extern const ElfW(Ehdr) __ehdr_start __attribute__((visibility("hidden")));
extern ElfW(Dyn) _DYNAMIC[] __attribute__((weak, visibility("hidden")));

const ElfW(Ehdr) *ElfHeader = &__ehdr_start;
const ElfW(Phdr) *ProgramHeader =
(const ElfW(Phdr) *)((uintptr_t)ElfHeader + ElfHeader->e_phoff);

/* Compute the added base address in case of position-independent code. */
uintptr_t Base = 0;
for (uint32_t I = 0; I < ElfHeader->e_phnum; I++) {
if (ProgramHeader[I].p_type == PT_PHDR)
Base = (uintptr_t)ProgramHeader - ProgramHeader[I].p_vaddr;
if (ProgramHeader[I].p_type == PT_DYNAMIC && _DYNAMIC)
Base = (uintptr_t)_DYNAMIC - ProgramHeader[I].p_vaddr;
}

int TotalBinaryIdsSize = 0;
uint32_t I;
/* Iterate through entries in the program header. */
for (I = 0; I < ElfHeader->e_phnum; I++) {
for (uint32_t I = 0; I < ElfHeader->e_phnum; I++) {
/* Look for the notes segment in program header entries. */
if (ProgramHeader[I].p_type != PT_NOTE)
continue;

/* There can be multiple notes segment, and examine each of them. */
const ElfW(Nhdr) * Note;
const ElfW(Nhdr) * NotesEnd;
/*
* When examining notes in file, use p_offset, which is the offset within
* the elf file, to find the start of notes.
*/
if (ProgramHeader[I].p_memsz == 0 ||
ProgramHeader[I].p_memsz == ProgramHeader[I].p_filesz) {
Note = (const ElfW(Nhdr) *)((uintptr_t)ElfHeader +
ProgramHeader[I].p_offset);
NotesEnd = (const ElfW(Nhdr) *)((const char *)(Note) +
ProgramHeader[I].p_filesz);
} else {
/*
* When examining notes in memory, use p_vaddr, which is the address of
* section after loaded to memory, to find the start of notes.
*/
Note =
(const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_vaddr);
NotesEnd =
(const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_memsz);
}
const ElfW(Nhdr) *Note =
(const ElfW(Nhdr) *)(Base + ProgramHeader[I].p_vaddr);
const ElfW(Nhdr) *NotesEnd =
(const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_memsz);

int BinaryIdsSize = WriteBinaryIds(Writer, Note, NotesEnd);
if (TotalBinaryIdsSize == -1)
Expand Down
6 changes: 1 addition & 5 deletions compiler-rt/lib/rtsan/rtsan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ static void OnViolation(const BufferedStackTrace &stack,
StackDepotHandle handle = StackDepotPut_WithHandle(stack);

const bool is_stack_novel = handle.use_count() == 0;

// Marked UNLIKELY as if user is runing with halt_on_error=false
// we expect a high number of duplicate stacks. We are willing
// To pay for the first insertion.
if (UNLIKELY(is_stack_novel)) {
if (is_stack_novel || !flags().suppress_equal_stacks) {
IncrementUniqueErrorCount();

{
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/rtsan/rtsan_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@
RTSAN_FLAG(bool, halt_on_error, true, "Exit after first reported error.")
RTSAN_FLAG(bool, print_stats_on_exit, false, "Print stats on exit.")
RTSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
RTSAN_FLAG(bool, suppress_equal_stacks, true,
"Suppress a report if we've already output another report "
"with the same stack.")
6 changes: 6 additions & 0 deletions compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,11 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
return REAL(nanosleep)(rqtp, rmtp);
}

INTERCEPTOR(int, sched_yield, void) {
__rtsan_notify_intercepted_call("sched_yield");
return REAL(sched_yield)();
}

// Memory

INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
Expand Down Expand Up @@ -819,6 +824,7 @@ void __rtsan::InitializeInterceptors() {
INTERCEPT_FUNCTION(sleep);
INTERCEPT_FUNCTION(usleep);
INTERCEPT_FUNCTION(nanosleep);
INTERCEPT_FUNCTION(sched_yield);

INTERCEPT_FUNCTION(accept);
INTERCEPT_FUNCTION(bind);
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ TEST(TestRtsan, SleepingAThreadDiesWhenRealtime) {
ExpectNonRealtimeSurvival(Func);
}

TEST(TestRtsan, YieldingDiesWhenRealtime) {
auto Func = []() { std::this_thread::yield(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}

TEST(TestRtsan, IfstreamCreationDiesWhenRealtime) {
auto Func = []() { std::ifstream ifs{"./file.txt"}; };
ExpectRealtimeDeath(Func);
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ TEST(TestRtsanInterceptors, NanosleepDiesWhenRealtime) {
ExpectNonRealtimeSurvival(Func);
}

TEST(TestRtsanInterceptors, SchedYieldDiesWhenRealtime) {
auto Func = []() { sched_yield(); };
ExpectRealtimeDeath(Func, "sched_yield");
ExpectNonRealtimeSurvival(Func);
}

/*
Filesystem
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %clangxx -c -o %t %s
// RUN: %llvm_jitlink %t
//
// REQUIRES: system-darwin && host-arch-compatible

static int x = 1;

class Init {
public:
Init() { x = 0; }
};

static Init I;

int main(int argc, char *argv[]) {
return x;
}
33 changes: 33 additions & 0 deletions compiler-rt/test/profile/Linux/binary-id-offset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// REQUIRES: linux
//
// Make sure the build-id can be found in both EXEC and DYN (PIE) files,
// even when the note's section-start is forced to a weird address.
// (The DYN case would also apply to libraries, not explicitly tested here.)

// DEFINE: %{cflags} =
// DEFINE: %{check} = ( \
// DEFINE: %clang_profgen -Wl,--build-id -o %t %s %{cflags} && \
// DEFINE: env LLVM_PROFILE_FILE=%t.profraw %run %t && \
// DEFINE: llvm-readelf --notes %t && \
// DEFINE: llvm-profdata show --binary-ids %t.profraw \
// DEFINE: ) | FileCheck %s

// REDEFINE: %{cflags} = -no-pie
// RUN: %{check}

// REDEFINE: %{cflags} = -pie -fPIE
// RUN: %{check}

// REDEFINE: %{cflags} = -no-pie -Wl,--section-start=.note.gnu.build-id=0x1000000
// RUN: %{check}

// REDEFINE: %{cflags} = -pie -fPIE -Wl,--section-start=.note.gnu.build-id=0x1000000
// RUN: %{check}

// CHECK-LABEL{LITERAL}: .note.gnu.build-id
// CHECK: Build ID: [[ID:[0-9a-f]+]]

// CHECK-LABEL{LITERAL}: Binary IDs:
// CHECK-NEXT: [[ID]]

int main() { return 0; }
4 changes: 4 additions & 0 deletions compiler-rt/test/rtsan/deduplicate_errors.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %clangxx -fsanitize=realtime %s -o %t
// RUN: env RTSAN_OPTIONS="halt_on_error=false,print_stats_on_exit=true" %run %t 2>&1 | FileCheck %s
// RUN: env RTSAN_OPTIONS="halt_on_error=false,suppress_equal_stacks=false" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUPLICATES

// UNSUPPORTED: ios

Expand Down Expand Up @@ -37,3 +38,6 @@ int main() {
// CHECK: RealtimeSanitizer exit stats:
// CHECK-NEXT: Total error count: 220
// CHECK-NEXT: Unique error count: 4

// CHECK-DUPLICATES-COUNT-220: ==ERROR:
// CHECK-DUPLICATES-NOT: ==ERROR:
13 changes: 13 additions & 0 deletions flang/docs/ParserCombinators.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,16 @@ is built. All of the following parsers consume characters acquired from
Last, a string literal `"..."_debug` denotes a parser that emits the string to
`llvm::errs` and succeeds. It is useful for tracing while debugging a parser but should
obviously not be committed for production code.

### Messages
A list of generated error and warning messages is maintained in the `ParseState`.
The parser combinator that handles alternatives (`||` and `first()`) will
discard the messages from alternatives that fail when there is an alternative
that succeeds.
But when no alternative succeeds, and the alternative parser as a whole is
failing, the messages that survive are chosen from the alternative that
recognized any input tokens, if only one alternative did so;
and when multiple alternatives recognized tokens, the messages from the
alternative that proceeded the furthest into the input are retained.
This strategy tends to show the most useful error messages to the user
in situations where a statement fails to parse.
2 changes: 2 additions & 0 deletions flang/include/flang/Optimizer/Transforms/CUFCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace cuf {
mlir::gpu::GPUModuleOp getOrCreateGPUModule(mlir::ModuleOp mod,
mlir::SymbolTable &symTab);

bool isInCUDADeviceContext(mlir::Operation *op);

} // namespace cuf

#endif // FORTRAN_OPTIMIZER_TRANSFORMS_CUFCOMMON_H_
2 changes: 1 addition & 1 deletion flang/include/flang/Semantics/openmp-modifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace Fortran::semantics {
// or post-modifier (i.e. item: modifier). The default is pre-.
// Add an additional property that reflects the type of modifier.

ENUM_CLASS(OmpProperty, Required, Unique, Exclusive, Ultimate, Post);
ENUM_CLASS(OmpProperty, Required, Unique, Exclusive, Ultimate, Post)
using OmpProperties = common::EnumSet<OmpProperty, OmpProperty_enumSize>;
using OmpClauses =
common::EnumSet<llvm::omp::Clause, llvm::omp::Clause_enumSize>;
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Evaluate/fold-matmul.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static Expr<T> FoldMatmul(FoldingContext &context, FunctionRef<T> &&funcRef) {
auto product{aElt.Multiply(bElt)};
overflow |= product.flags.test(RealFlag::Overflow);
if constexpr (useKahanSummation) {
auto next{correction.Add(product.value, rounding)};
auto next{product.value.Subtract(correction, rounding)};
overflow |= next.flags.test(RealFlag::Overflow);
auto added{sum.Add(next.value, rounding)};
overflow |= added.flags.test(RealFlag::Overflow);
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Evaluate/fold-real.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ template <int KIND> class Norm2Accumulator {
auto scaled{item.Divide(scale).value};
auto square{scaled.Multiply(scaled).value};
if constexpr (useKahanSummation) {
auto next{square.Add(correction_, rounding_)};
auto next{square.Subtract(correction_, rounding_)};
overflow_ |= next.flags.test(RealFlag::Overflow);
auto sum{element.Add(next.value, rounding_)};
overflow_ |= sum.flags.test(RealFlag::Overflow);
Expand Down
6 changes: 3 additions & 3 deletions flang/lib/Evaluate/fold-reduction.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static Expr<T> FoldDotProduct(
const auto &rounding{context.targetCharacteristics().roundingMode()};
for (const Element &x : cProducts.values()) {
if constexpr (useKahanSummation) {
auto next{correction.Add(x, rounding)};
auto next{x.Subtract(correction, rounding)};
overflow |= next.flags.test(RealFlag::Overflow);
auto added{sum.Add(next.value, rounding)};
overflow |= added.flags.test(RealFlag::Overflow);
Expand Down Expand Up @@ -90,7 +90,7 @@ static Expr<T> FoldDotProduct(
const auto &rounding{context.targetCharacteristics().roundingMode()};
for (const Element &x : cProducts.values()) {
if constexpr (useKahanSummation) {
auto next{correction.Add(x, rounding)};
auto next{x.Subtract(correction, rounding)};
overflow |= next.flags.test(RealFlag::Overflow);
auto added{sum.Add(next.value, rounding)};
overflow |= added.flags.test(RealFlag::Overflow);
Expand Down Expand Up @@ -348,7 +348,7 @@ template <typename T> class SumAccumulator {
overflow_ |= sum.overflow;
element = sum.value;
} else { // Real & Complex: use Kahan summation
auto next{array_.At(at).Add(correction_, rounding_)};
auto next{array_.At(at).Subtract(correction_, rounding_)};
overflow_ |= next.flags.test(RealFlag::Overflow);
auto sum{element.Add(next.value, rounding_)};
overflow_ |= sum.flags.test(RealFlag::Overflow);
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/HLFIR/Passes.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/IR/Dominance.h"
#include "mlir/IR/PatternMatch.h"
Expand Down Expand Up @@ -792,7 +793,8 @@ struct ElementalOpConversion
// Generate a loop nest looping around the fir.elemental shape and clone
// fir.elemental region inside the inner loop.
hlfir::LoopNest loopNest =
hlfir::genLoopNest(loc, builder, extents, !elemental.isOrdered());
hlfir::genLoopNest(loc, builder, extents, !elemental.isOrdered(),
flangomp::shouldUseWorkshareLowering(elemental));
auto insPt = builder.saveInsertionPoint();
builder.setInsertionPointToStart(loopNest.body);
auto yield = hlfir::inlineElementalOp(loc, builder, elemental,
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Optimizer/HLFIR/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ add_flang_library(HLFIRTransforms
FIRDialectSupport
FIRSupport
FIRTransforms
FlangOpenMPTransforms
HLFIRDialect
MLIRIR
${dialect_libs}
Expand Down
10 changes: 7 additions & 3 deletions flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/HLFIR/Passes.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/Transforms/Utils.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/Dominance.h"
Expand Down Expand Up @@ -482,7 +483,8 @@ llvm::LogicalResult ElementalAssignBufferization::matchAndRewrite(
// Generate a loop nest looping around the hlfir.elemental shape and clone
// hlfir.elemental region inside the inner loop
hlfir::LoopNest loopNest =
hlfir::genLoopNest(loc, builder, extents, !elemental.isOrdered());
hlfir::genLoopNest(loc, builder, extents, !elemental.isOrdered(),
flangomp::shouldUseWorkshareLowering(elemental));
builder.setInsertionPointToStart(loopNest.body);
auto yield = hlfir::inlineElementalOp(loc, builder, elemental,
loopNest.oneBasedIndices);
Expand Down Expand Up @@ -553,7 +555,8 @@ llvm::LogicalResult BroadcastAssignBufferization::matchAndRewrite(
llvm::SmallVector<mlir::Value> extents =
hlfir::getIndexExtents(loc, builder, shape);
hlfir::LoopNest loopNest =
hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true);
hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true,
flangomp::shouldUseWorkshareLowering(assign));
builder.setInsertionPointToStart(loopNest.body);
auto arrayElement =
hlfir::getElementAt(loc, builder, lhs, loopNest.oneBasedIndices);
Expand Down Expand Up @@ -651,7 +654,8 @@ llvm::LogicalResult VariableAssignBufferization::matchAndRewrite(
llvm::SmallVector<mlir::Value> extents =
hlfir::getIndexExtents(loc, builder, shape);
hlfir::LoopNest loopNest =
hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true);
hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true,
flangomp::shouldUseWorkshareLowering(assign));
builder.setInsertionPointToStart(loopNest.body);
auto rhsArrayElement =
hlfir::getElementAt(loc, builder, rhs, loopNest.oneBasedIndices);
Expand Down
17 changes: 17 additions & 0 deletions flang/lib/Optimizer/Transforms/CUFCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//

#include "flang/Optimizer/Transforms/CUFCommon.h"
#include "flang/Optimizer/Dialect/CUF/CUFOps.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/NVVMDialect.h"

/// Retrieve or create the CUDA Fortran GPU module in the give in \p mod.
Expand All @@ -26,3 +28,18 @@ mlir::gpu::GPUModuleOp cuf::getOrCreateGPUModule(mlir::ModuleOp mod,
symTab.insert(gpuMod, insertPt);
return gpuMod;
}

bool cuf::isInCUDADeviceContext(mlir::Operation *op) {
if (!op)
return false;
if (op->getParentOfType<cuf::KernelOp>() ||
op->getParentOfType<mlir::gpu::GPUFuncOp>())
return true;
if (auto funcOp = op->getParentOfType<mlir::func::FuncOp>()) {
if (auto cudaProcAttr = funcOp->getAttrOfType<cuf::ProcAttributeAttr>(
cuf::getProcAttrName())) {
return cudaProcAttr.getValue() != cuf::ProcAttribute::Host;
}
}
return false;
}
47 changes: 29 additions & 18 deletions flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
#include "flang/Optimizer/Support/InternalNames.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Pass/Pass.h"
Expand Down Expand Up @@ -58,26 +59,36 @@ void ExternalNameConversionPass::runOnOperation() {
auto *context = &getContext();

llvm::DenseMap<mlir::StringAttr, mlir::FlatSymbolRefAttr> remappings;
// Update names of external Fortran functions and names of Common Block
// globals.
for (auto &funcOrGlobal : op->getRegion(0).front()) {
if (llvm::isa<mlir::func::FuncOp>(funcOrGlobal) ||
llvm::isa<fir::GlobalOp>(funcOrGlobal)) {
auto symName = funcOrGlobal.getAttrOfType<mlir::StringAttr>(
mlir::SymbolTable::getSymbolAttrName());
auto deconstructedName = fir::NameUniquer::deconstruct(symName);
if (fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) {
auto newName =
mangleExternalName(deconstructedName, appendUnderscoreOpt);
auto newAttr = mlir::StringAttr::get(context, newName);
mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr);
auto newSymRef = mlir::FlatSymbolRefAttr::get(newAttr);
remappings.try_emplace(symName, newSymRef);
if (llvm::isa<mlir::func::FuncOp>(funcOrGlobal))
funcOrGlobal.setAttr(fir::getInternalFuncNameAttrName(), symName);

auto renameFuncOrGlobalInModule = [&](mlir::Operation *module) {
for (auto &funcOrGlobal : module->getRegion(0).front()) {
if (llvm::isa<mlir::func::FuncOp>(funcOrGlobal) ||
llvm::isa<fir::GlobalOp>(funcOrGlobal)) {
auto symName = funcOrGlobal.getAttrOfType<mlir::StringAttr>(
mlir::SymbolTable::getSymbolAttrName());
auto deconstructedName = fir::NameUniquer::deconstruct(symName);
if (fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) {
auto newName =
mangleExternalName(deconstructedName, appendUnderscoreOpt);
auto newAttr = mlir::StringAttr::get(context, newName);
mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr);
auto newSymRef = mlir::FlatSymbolRefAttr::get(newAttr);
remappings.try_emplace(symName, newSymRef);
if (llvm::isa<mlir::func::FuncOp>(funcOrGlobal))
funcOrGlobal.setAttr(fir::getInternalFuncNameAttrName(), symName);
}
}
}
}
};

// Update names of external Fortran functions and names of Common Block
// globals.
renameFuncOrGlobalInModule(op);

// Do the same in GPU modules.
if (auto mod = mlir::dyn_cast_or_null<mlir::ModuleOp>(*op))
for (auto gpuMod : mod.getOps<mlir::gpu::GPUModuleOp>())
renameFuncOrGlobalInModule(gpuMod);

if (remappings.empty())
return;
Expand Down
3 changes: 3 additions & 0 deletions flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/Transforms/CUFCommon.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "flang/Optimizer/Transforms/Utils.h"
#include "flang/Runtime/entry-names.h"
Expand Down Expand Up @@ -1276,6 +1277,8 @@ void SimplifyIntrinsicsPass::runOnOperation() {
fir::KindMapping kindMap = fir::getKindMapping(module);
module.walk([&](mlir::Operation *op) {
if (auto call = mlir::dyn_cast<fir::CallOp>(op)) {
if (cuf::isInCUDADeviceContext(op))
return;
if (mlir::SymbolRefAttr callee = call.getCalleeAttr()) {
mlir::StringRef funcName = callee.getLeafReference().getValue();
// Replace call to runtime function for SUM when it has single
Expand Down
15 changes: 11 additions & 4 deletions flang/lib/Parser/executable-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// Per-type parsers for executable statements

#include "basic-parsers.h"
#include "debug-parser.h"
#include "expr-parsers.h"
#include "misc-parsers.h"
#include "stmt-parser.h"
Expand Down Expand Up @@ -282,18 +281,26 @@ TYPE_CONTEXT_PARSER("loop control"_en_US,
"CONCURRENT" >> concurrentHeader,
many(Parser<LocalitySpec>{})))))

// "DO" is a valid statement, so the loop control is optional; but for
// better recovery from errors in the loop control, don't parse a
// DO statement with a bad loop control as a DO statement that has
// no loop control and is followed by garbage.
static constexpr auto loopControlOrEndOfStmt{
construct<std::optional<LoopControl>>(Parser<LoopControl>{}) ||
lookAhead(";\n"_ch) >> construct<std::optional<LoopControl>>()};

// R1121 label-do-stmt -> [do-construct-name :] DO label [loop-control]
// A label-do-stmt with a do-construct-name is parsed as a nonlabel-do-stmt
// with an optional label.
TYPE_CONTEXT_PARSER("label DO statement"_en_US,
construct<LabelDoStmt>("DO" >> label, maybe(loopControl)))
construct<LabelDoStmt>("DO" >> label, loopControlOrEndOfStmt))

// R1122 nonlabel-do-stmt -> [do-construct-name :] DO [loop-control]
TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US,
construct<NonLabelDoStmt>(
name / ":", "DO" >> maybe(label), maybe(loopControl)) ||
name / ":", "DO" >> maybe(label), loopControlOrEndOfStmt) ||
construct<NonLabelDoStmt>(construct<std::optional<Name>>(),
construct<std::optional<Label>>(), "DO" >> maybe(loopControl)))
construct<std::optional<Label>>(), "DO" >> loopControlOrEndOfStmt))

// R1132 end-do-stmt -> END DO [do-construct-name]
TYPE_CONTEXT_PARSER("END DO statement"_en_US,
Expand Down
96 changes: 58 additions & 38 deletions flang/lib/Parser/prescan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,15 @@ void Prescanner::Statement() {
}
break;
}
case LineClassification::Kind::Source:
case LineClassification::Kind::Source: {
BeginStatementAndAdvance();
bool checkLabelField{false};
if (inFixedForm_) {
if (features_.IsEnabled(LanguageFeature::OldDebugLines) &&
(*at_ == 'D' || *at_ == 'd')) {
NextChar();
}
LabelField(tokens);
checkLabelField = true;
} else {
if (skipLeadingAmpersand_) {
skipLeadingAmpersand_ = false;
Expand All @@ -207,38 +208,42 @@ void Prescanner::Statement() {
} else {
SkipSpaces();
}
// Check for a leading identifier that might be a keyword macro
// that will expand to anything indicating a non-source line, like
// a comment marker or directive sentinel. If so, disable line
// continuation, so that NextToken() won't consume anything from
// following lines.
if (IsLegalIdentifierStart(*at_)) {
// TODO: Only bother with these cases when any keyword macro has
// been defined with replacement text that could begin a comment
// or directive sentinel.
const char *p{at_};
while (IsLegalInIdentifier(*++p)) {
}
CharBlock id{at_, static_cast<std::size_t>(p - at_)};
if (preprocessor_.IsNameDefined(id) &&
!preprocessor_.IsFunctionLikeDefinition(id)) {
TokenSequence toks;
toks.Put(id, GetProvenance(at_));
if (auto replaced{preprocessor_.MacroReplacement(toks, *this)}) {
auto newLineClass{ClassifyLine(*replaced, GetCurrentProvenance())};
if (newLineClass.kind ==
LineClassification::Kind::CompilerDirective) {
directiveSentinel_ = newLineClass.sentinel;
disableSourceContinuation_ = false;
} else {
disableSourceContinuation_ =
newLineClass.kind != LineClassification::Kind::Source;
}
}
// Check for a leading identifier that might be a keyword macro
// that will expand to anything indicating a non-source line, like
// a comment marker or directive sentinel. If so, disable line
// continuation, so that NextToken() won't consume anything from
// following lines.
if (IsLegalIdentifierStart(*at_)) {
// TODO: Only bother with these cases when any keyword macro has
// been defined with replacement text that could begin a comment
// or directive sentinel.
const char *p{at_};
while (IsLegalInIdentifier(*++p)) {
}
CharBlock id{at_, static_cast<std::size_t>(p - at_)};
if (preprocessor_.IsNameDefined(id) &&
!preprocessor_.IsFunctionLikeDefinition(id)) {
checkLabelField = false;
TokenSequence toks;
toks.Put(id, GetProvenance(at_));
if (auto replaced{preprocessor_.MacroReplacement(toks, *this)}) {
auto newLineClass{ClassifyLine(*replaced, GetCurrentProvenance())};
if (newLineClass.kind ==
LineClassification::Kind::CompilerDirective) {
directiveSentinel_ = newLineClass.sentinel;
disableSourceContinuation_ = false;
} else {
disableSourceContinuation_ =
newLineClass.kind != LineClassification::Kind::Source;
}
}
}
}
break;
if (checkLabelField) {
LabelField(tokens);
}
} break;
}

while (NextToken(tokens)) {
Expand Down Expand Up @@ -815,18 +820,33 @@ bool Prescanner::ExponentAndKind(TokenSequence &tokens) {
if (ed != 'e' && ed != 'd') {
return false;
}
EmitCharAndAdvance(tokens, ed);
if (*at_ == '+' || *at_ == '-') {
EmitCharAndAdvance(tokens, *at_);
// Do some look-ahead to ensure that this 'e'/'d' is an exponent,
// not the start of an identifier that could be a macro.
const char *p{at_};
if (int n{IsSpace(++p)}) {
p += n;
}
while (IsDecimalDigit(*at_)) {
EmitCharAndAdvance(tokens, *at_);
if (*p == '+' || *p == '-') {
if (int n{IsSpace(++p)}) {
p += n;
}
}
if (*at_ == '_') {
while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
if (IsDecimalDigit(*p)) { // it's an exponent
EmitCharAndAdvance(tokens, ed);
if (*at_ == '+' || *at_ == '-') {
EmitCharAndAdvance(tokens, *at_);
}
while (IsDecimalDigit(*at_)) {
EmitCharAndAdvance(tokens, *at_);
}
if (*at_ == '_') {
while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
}
}
return true;
} else {
return false;
}
return true;
}

void Prescanner::QuotedCharacterLiteral(
Expand Down
1 change: 0 additions & 1 deletion flang/lib/Parser/type-parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ constexpr Parser<ForallAssignmentStmt> forallAssignmentStmt; // R1053
constexpr Parser<ForallStmt> forallStmt; // R1055
constexpr Parser<Selector> selector; // R1105
constexpr Parser<EndSelectStmt> endSelectStmt; // R1143 & R1151 & R1155
constexpr Parser<LoopControl> loopControl; // R1123
constexpr Parser<ConcurrentHeader> concurrentHeader; // R1125
constexpr Parser<IoUnit> ioUnit; // R1201, R1203
constexpr Parser<FileUnitNumber> fileUnitNumber; // R1202
Expand Down
2 changes: 1 addition & 1 deletion flang/runtime/sum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ template <typename INTERMEDIATE> class RealSumAccumulator {
}
template <typename A> RT_API_ATTRS bool Accumulate(A x) {
// Kahan summation
auto next{x + correction_};
auto next{x - correction_};
auto oldSum{sum_};
sum_ += next;
correction_ = (sum_ - oldSum) - next; // algebraically zero
Expand Down
49 changes: 49 additions & 0 deletions flang/test/Fir/CUDA/cuda-device-context.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// RUN: fir-opt --simplify-intrinsics %s | FileCheck %s

func.func @_QPsum_in_device(%arg0: !fir.ref<!fir.array<?xi32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}, %arg1: i32 {fir.bindc_name = "n"}) attributes {cuf.proc_attr = #cuf.cuda_proc<global>} {
%c5_i32 = arith.constant 5 : i32
%c1 = arith.constant 1 : index
%c0 = arith.constant 0 : index
%c-1 = arith.constant -1 : index
%0 = fir.dummy_scope : !fir.dscope
%1 = fir.shape %c-1 : (index) -> !fir.shape<1>
%2 = fir.declare %arg0(%1) dummy_scope %0 {data_attr = #cuf.cuda<device>, uniq_name = "_QFsum_in_deviceEa"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<?xi32>>
%3 = fir.embox %2(%1) : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
%4 = fir.alloca i32
fir.store %arg1 to %4 : !fir.ref<i32>
%5 = fir.declare %4 dummy_scope %0 {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFsum_in_deviceEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
%12 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsum_in_deviceEi"}
%13 = fir.declare %12 {uniq_name = "_QFsum_in_deviceEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
%14 = fir.address_of(@_QM__fortran_builtinsE__builtin_threadidx) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_dim3{x:i32,y:i32,z:i32}>>
%18 = fir.load %5 : !fir.ref<i32>
%19 = fir.convert %18 : (i32) -> index
%20 = arith.cmpi sgt, %19, %c0 : index
%21 = arith.select %20, %19, %c0 : index
%22 = fir.alloca !fir.array<?xi32>, %21 {bindc_name = "auto", uniq_name = "_QFsum_in_deviceEauto"}
%23 = fir.shape %21 : (index) -> !fir.shape<1>
%24 = fir.declare %22(%23) {uniq_name = "_QFsum_in_deviceEauto"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xi32>>
%25 = fir.embox %24(%23) : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
%26 = fir.undefined index
%27 = fir.slice %c1, %19, %c1 : (index, index, index) -> !fir.slice<1>
%28 = fir.embox %24(%23) [%27] : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
%29 = fir.absent !fir.box<i1>
%30 = fir.address_of(@_QQclX91d13f6e74caa2f03965d7a7c6a8fdd5) : !fir.ref<!fir.char<1,50>>
%31 = fir.convert %28 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
%32 = fir.convert %30 : (!fir.ref<!fir.char<1,50>>) -> !fir.ref<i8>
%33 = fir.convert %c0 : (index) -> i32
%34 = fir.convert %29 : (!fir.box<i1>) -> !fir.box<none>
%35 = fir.call @_FortranASumInteger4(%31, %32, %c5_i32, %33, %34) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
%36 = fir.load %13 : !fir.ref<i32>
%37 = fir.convert %36 : (i32) -> i64
%38 = fir.array_coor %2(%1) %37 : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, i64) -> !fir.ref<i32>
fir.store %35 to %38 : !fir.ref<i32>
return
}

// Check that intrinsic simplification is disabled in CUDA Fortran context. The simplified intrinsic is
// created in the module op but the device func will be migrated into a gpu module op resulting in a
// missing symbol error.
// The simplified intrinsic could also be migrated to the gpu module but the choice has not be made
// at this point.
// CHECK-LABEL: func.func @_QPsum_in_device
// CHECK-NOT: fir.call @_FortranASumInteger4x1_contract_simplified
13 changes: 13 additions & 0 deletions flang/test/Fir/CUDA/cuda-extranal-mangling.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: fir-opt --split-input-file --external-name-interop %s | FileCheck %s

gpu.module @cuda_device_mod {
gpu.func @_QPfoo() {
fir.call @_QPthreadfence() fastmath<contract> : () -> ()
gpu.return
}
func.func private @_QPthreadfence() attributes {cuf.proc_attr = #cuf.cuda_proc<device>}
}

// CHECK-LABEL: gpu.func @_QPfoo
// CHECK: fir.call @threadfence_()
// CHECK: func.func private @threadfence_()
57 changes: 57 additions & 0 deletions flang/test/HLFIR/bufferize-workshare.fir
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// RUN: fir-opt --bufferize-hlfir %s | FileCheck %s

// CHECK-LABEL: func.func @simple(
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>) {
// CHECK: omp.parallel {
// CHECK: omp.workshare {
// CHECK: %[[VAL_1:.*]] = arith.constant 42 : index
// CHECK: %[[VAL_2:.*]] = arith.constant 1 : i32
// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_3]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
// CHECK: %[[VAL_5:.*]] = fir.allocmem !fir.array<42xi32> {bindc_name = ".tmp.array", uniq_name = ""}
// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]](%[[VAL_3]]) {uniq_name = ".tmp.array"} : (!fir.heap<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<42xi32>>, !fir.heap<!fir.array<42xi32>>)
// CHECK: %[[VAL_7:.*]] = arith.constant true
// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index
// CHECK: omp.workshare.loop_wrapper {
// CHECK: omp.loop_nest (%[[VAL_9:.*]]) : index = (%[[VAL_8]]) to (%[[VAL_1]]) inclusive step (%[[VAL_8]]) {
// CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_9]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
// CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
// CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_11]], %[[VAL_2]] : i32
// CHECK: %[[VAL_13:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_9]]) : (!fir.heap<!fir.array<42xi32>>, index) -> !fir.ref<i32>
// CHECK: hlfir.assign %[[VAL_12]] to %[[VAL_13]] temporary_lhs : i32, !fir.ref<i32>
// CHECK: omp.yield
// CHECK: }
// CHECK: }
// CHECK: %[[VAL_14:.*]] = fir.undefined tuple<!fir.heap<!fir.array<42xi32>>, i1>
// CHECK: %[[VAL_15:.*]] = fir.insert_value %[[VAL_14]], %[[VAL_7]], [1 : index] : (tuple<!fir.heap<!fir.array<42xi32>>, i1>, i1) -> tuple<!fir.heap<!fir.array<42xi32>>, i1>
// CHECK: %[[VAL_16:.*]] = fir.insert_value %[[VAL_15]], %[[VAL_6]]#0, [0 : index] : (tuple<!fir.heap<!fir.array<42xi32>>, i1>, !fir.heap<!fir.array<42xi32>>) -> tuple<!fir.heap<!fir.array<42xi32>>, i1>
// CHECK: hlfir.assign %[[VAL_6]]#0 to %[[VAL_4]]#0 : !fir.heap<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>
// CHECK: fir.freemem %[[VAL_6]]#0 : !fir.heap<!fir.array<42xi32>>
// CHECK: omp.terminator
// CHECK: }
// CHECK: omp.terminator
// CHECK: }
// CHECK: return
// CHECK: }
func.func @simple(%arg: !fir.ref<!fir.array<42xi32>>) {
omp.parallel {
omp.workshare {
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
%ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
%val = fir.load %ref : !fir.ref<i32>
%sub = arith.subi %val, %c1_i32 : i32
hlfir.yield_element %sub : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
omp.terminator
}
omp.terminator
}
return
}
34 changes: 34 additions & 0 deletions flang/test/Integration/OpenMP/workshare-array-array-assign.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
!===----------------------------------------------------------------------===!
! This directory can be used to add Integration tests involving multiple
! stages of the compiler (for eg. from Fortran to LLVM IR). It should not
! contain executable tests. We should only add tests here sparingly and only
! if there is no other way to test. Repeat this message in each test that is
! added to this directory and sub-directories.
!===----------------------------------------------------------------------===!

!RUN: %flang_fc1 -emit-hlfir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix HLFIR
!RUN: %flang_fc1 -emit-fir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix FIR

subroutine sb1(x, y)
integer :: x(:)
integer :: y(:)
!$omp parallel workshare
x = y
!$omp end parallel workshare
end subroutine

! HLFIR: omp.parallel {
! HLFIR: omp.workshare {
! HLFIR: hlfir.assign
! HLFIR: omp.terminator
! HLFIR: }
! HLFIR: omp.terminator
! HLFIR: }

! FIR: omp.parallel {
! FIR: omp.wsloop nowait {
! FIR: omp.loop_nest
! FIR: }
! FIR: omp.barrier
! FIR: omp.terminator
! FIR: }
57 changes: 57 additions & 0 deletions flang/test/Integration/OpenMP/workshare-axpy.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
!===----------------------------------------------------------------------===!
! This directory can be used to add Integration tests involving multiple
! stages of the compiler (for eg. from Fortran to LLVM IR). It should not
! contain executable tests. We should only add tests here sparingly and only
! if there is no other way to test. Repeat this message in each test that is
! added to this directory and sub-directories.
!===----------------------------------------------------------------------===!

!RUN: %flang_fc1 -emit-hlfir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix HLFIR
!RUN: %flang_fc1 -emit-fir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix FIR

subroutine sb1(a, x, y, z)
integer :: a
integer :: x(:)
integer :: y(:)
integer :: z(:)
!$omp parallel workshare
z = a * x + y
!$omp end parallel workshare
end subroutine

! HLFIR: func.func @_QPsb1
! HLFIR: omp.parallel {
! HLFIR: omp.workshare {
! HLFIR: hlfir.elemental {{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
! HLFIR: hlfir.elemental {{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
! HLFIR: hlfir.assign
! HLFIR: hlfir.destroy
! HLFIR: hlfir.destroy
! HLFIR-NOT: omp.barrier
! HLFIR: omp.terminator
! HLFIR: }
! HLFIR-NOT: omp.barrier
! HLFIR: omp.terminator
! HLFIR: }
! HLFIR: return
! HLFIR: }
! HLFIR:}


! FIR: func.func private @_workshare_copy_heap_Uxi32(%{{[a-z0-9]+}}: !fir.ref<!fir.heap<!fir.array<?xi32>>>, %{{[a-z0-9]+}}: !fir.ref<!fir.heap<!fir.array<?xi32>>>
! FIR: func.func private @_workshare_copy_i32(%{{[a-z0-9]+}}: !fir.ref<i32>, %{{[a-z0-9]+}}: !fir.ref<i32>

! FIR: func.func @_QPsb1
! FIR: omp.parallel {
! FIR: omp.single copyprivate(%9 -> @_workshare_copy_i32 : !fir.ref<i32>, %10 -> @_workshare_copy_heap_Uxi32 : !fir.ref<!fir.heap<!fir.array<?xi32>>>) {
! FIR: fir.allocmem
! FIR: omp.wsloop {
! FIR: omp.loop_nest
! FIR: omp.single nowait {
! FIR: fir.call @_FortranAAssign
! FIR: fir.freemem
! FIR: omp.terminator
! FIR: }
! FIR: omp.barrier
! FIR: omp.terminator
! FIR: }
45 changes: 45 additions & 0 deletions flang/test/Integration/OpenMP/workshare-scalar-array-assign.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
!===----------------------------------------------------------------------===!
! This directory can be used to add Integration tests involving multiple
! stages of the compiler (for eg. from Fortran to LLVM IR). It should not
! contain executable tests. We should only add tests here sparingly and only
! if there is no other way to test. Repeat this message in each test that is
! added to this directory and sub-directories.
!===----------------------------------------------------------------------===!

!RUN: %flang_fc1 -emit-hlfir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix HLFIR
!RUN: %flang_fc1 -emit-fir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix FIR

subroutine sb1(a, x)
integer :: a
integer :: x(:)
!$omp parallel workshare
x = a
!$omp end parallel workshare
end subroutine

! HLFIR: omp.parallel {
! HLFIR: omp.workshare {
! HLFIR: %[[SCALAR:.*]] = fir.load %1#0 : !fir.ref<i32>
! HLFIR: hlfir.assign %[[SCALAR]] to
! HLFIR: omp.terminator
! HLFIR: }
! HLFIR: omp.terminator
! HLFIR: }

! FIR: omp.parallel {
! FIR: %[[SCALAR_ALLOCA:.*]] = fir.alloca i32
! FIR: omp.single copyprivate(%[[SCALAR_ALLOCA]] -> @_workshare_copy_i32 : !fir.ref<i32>) {
! FIR: %[[SCALAR_LOAD:.*]] = fir.load %{{.*}} : !fir.ref<i32>
! FIR: fir.store %[[SCALAR_LOAD]] to %[[SCALAR_ALLOCA]] : !fir.ref<i32>
! FIR: omp.terminator
! FIR: }
! FIR: %[[SCALAR_RELOAD:.*]] = fir.load %[[SCALAR_ALLOCA]] : !fir.ref<i32>
! FIR: %6:3 = fir.box_dims %3, %c0 : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
! FIR: omp.wsloop nowait {
! FIR: omp.loop_nest (%arg2) : index = (%c1) to (%6#1) inclusive step (%c1) {
! FIR: fir.store %[[SCALAR_RELOAD]]
! FIR: omp.yield
! FIR: }
! FIR: }
! FIR: omp.barrier
! FIR: omp.terminator
65 changes: 65 additions & 0 deletions flang/test/Integration/OpenMP/workshare-scalar-array-mul.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
!===----------------------------------------------------------------------===!
! This directory can be used to add Integration tests involving multiple
! stages of the compiler (for eg. from Fortran to LLVM IR). It should not
! contain executable tests. We should only add tests here sparingly and only
! if there is no other way to test. Repeat this message in each test that is
! added to this directory and sub-directories.
!===----------------------------------------------------------------------===!

!RUN: %flang_fc1 -emit-hlfir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix HLFIR-O3
!RUN: %flang_fc1 -emit-fir -fopenmp -O3 %s -o - | FileCheck %s --check-prefix FIR-O3

!RUN: %flang_fc1 -emit-hlfir -fopenmp -O0 %s -o - | FileCheck %s --check-prefix HLFIR-O0
!RUN: %flang_fc1 -emit-fir -fopenmp -O0 %s -o - | FileCheck %s --check-prefix FIR-O0

program test
real :: arr_01(10)
!$omp parallel workshare
arr_01 = arr_01*2
!$omp end parallel workshare
end program

! HLFIR-O3: omp.parallel {
! HLFIR-O3: omp.workshare {
! HLFIR-O3: hlfir.elemental
! HLFIR-O3: hlfir.assign
! HLFIR-O3: hlfir.destroy
! HLFIR-O3: omp.terminator
! HLFIR-O3: omp.terminator

! FIR-O3: omp.parallel {
! FIR-O3: omp.wsloop nowait {
! FIR-O3: omp.loop_nest
! FIR-O3: omp.barrier
! FIR-O3: omp.terminator

! HLFIR-O0: omp.parallel {
! HLFIR-O0: omp.workshare {
! HLFIR-O0: hlfir.elemental
! HLFIR-O0: hlfir.assign
! HLFIR-O0: hlfir.destroy
! HLFIR-O0: omp.terminator
! HLFIR-O0: omp.terminator

! Check the copyprivate copy function
! FIR-O0: func.func private @_workshare_copy_heap_{{.*}}(%[[DST:.*]]: {{.*}}, %[[SRC:.*]]: {{.*}})
! FIR-O0: fir.load %[[SRC]]
! FIR-O0: fir.store {{.*}} to %[[DST]]

! Check that we properly handle the temporary array
! FIR-O0: omp.parallel {
! FIR-O0: %[[CP:.*]] = fir.alloca !fir.heap<!fir.array<10xf32>>
! FIR-O0: omp.single copyprivate(%[[CP]] -> @_workshare_copy_heap_
! FIR-O0: fir.allocmem
! FIR-O0: fir.store
! FIR-O0: omp.terminator
! FIR-O0: fir.load %[[CP]]
! FIR-O0: omp.wsloop {
! FIR-O0: omp.loop_nest
! FIR-O0: omp.yield
! FIR-O0: omp.single nowait {
! FIR-O0: fir.call @_FortranAAssign
! FIR-O0: fir.freemem
! FIR-O0: omp.terminator
! FIR-O0: omp.barrier
! FIR-O0: omp.terminator
6 changes: 6 additions & 0 deletions flang/test/Parser/recovery07.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
! CHECK: error: expected ':'
! CHECK: in the context: loop control
do concurrent(I = 1, N)
end do
end
24 changes: 24 additions & 0 deletions flang/test/Preprocessing/not-an-exponent.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
#define e eeeee
module m
interface operator(.e.)
module procedure ir,rr
end interface operator(.e.)
contains
function ir(k1,k2)
intent(in)::k1,k2
ir=k1+k2
end function ir
function rr(k1,k2)
real,intent(in)::k1,k2
rr=k1+k2
end function rr
end module m
program main
use m
!CHECK: IF (real((ir(1_4,5_4)),kind=4)/=6._4) ERROR STOP 1_4
!CHECK: IF ((rr(1._4,5.e-1_4))/=1.5_4) ERROR STOP 2_4
if((1.e.5)/=6.e0) error stop 1
if((1..e..5)/=1.5) error stop 2
print *,'pass'
end program main
5 changes: 5 additions & 0 deletions flang/test/Preprocessing/pp046.F
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
! RUN: %flang -E %s 2>&1 | FileCheck %s
! CHECK-NOT: Character in fixed-form label field must be a digit
#define KWM !
KWM a comment
end
162 changes: 162 additions & 0 deletions flang/test/Transforms/OpenMP/should-use-workshare-lowering.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// RUN: fir-opt --bufferize-hlfir %s | FileCheck %s

// Checks that we correctly identify when to use the lowering to
// omp.workshare.loop_wrapper

// CHECK-LABEL: @should_parallelize_0
// CHECK: omp.workshare.loop_wrapper
func.func @should_parallelize_0(%arg: !fir.ref<!fir.array<42xi32>>, %idx : index) {
omp.workshare {
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
hlfir.yield_element %c1_i32 : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
omp.terminator
}
return
}

// CHECK-LABEL: @should_parallelize_1
// CHECK: omp.workshare.loop_wrapper
func.func @should_parallelize_1(%arg: !fir.ref<!fir.array<42xi32>>, %idx : index) {
omp.parallel {
omp.workshare {
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
hlfir.yield_element %c1_i32 : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
omp.terminator
}
omp.terminator
}
return
}


// CHECK-LABEL: @should_not_parallelize_0
// CHECK-NOT: omp.workshare.loop_wrapper
func.func @should_not_parallelize_0(%arg: !fir.ref<!fir.array<42xi32>>, %idx : index) {
omp.workshare {
omp.single {
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
hlfir.yield_element %c1_i32 : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
omp.terminator
}
omp.terminator
}
return
}

// CHECK-LABEL: @should_not_parallelize_1
// CHECK-NOT: omp.workshare.loop_wrapper
func.func @should_not_parallelize_1(%arg: !fir.ref<!fir.array<42xi32>>, %idx : index) {
omp.workshare {
omp.critical {
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
hlfir.yield_element %c1_i32 : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
omp.terminator
}
omp.terminator
}
return
}

// CHECK-LABEL: @should_not_parallelize_2
// CHECK-NOT: omp.workshare.loop_wrapper
func.func @should_not_parallelize_2(%arg: !fir.ref<!fir.array<42xi32>>, %idx : index) {
omp.workshare {
omp.parallel {
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
hlfir.yield_element %c1_i32 : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
omp.terminator
}
omp.terminator
}
return
}

// CHECK-LABEL: @should_not_parallelize_3
// CHECK-NOT: omp.workshare.loop_wrapper
func.func @should_not_parallelize_3(%arg: !fir.ref<!fir.array<42xi32>>, %idx : index) {
omp.workshare {
omp.parallel {
omp.workshare {
omp.parallel {
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
hlfir.yield_element %c1_i32 : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
omp.terminator
}
omp.terminator
}
omp.terminator
}
omp.terminator
}
return
}

// CHECK-LABEL: @should_not_parallelize_4
// CHECK-NOT: omp.workshare.loop_wrapper
func.func @should_not_parallelize_4(%arg: !fir.ref<!fir.array<42xi32>>, %idx : index) {
omp.workshare {
^bb1:
%c42 = arith.constant 42 : index
%c1_i32 = arith.constant 1 : i32
%shape = fir.shape %c42 : (index) -> !fir.shape<1>
%array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
%elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
^bb0(%i: index):
hlfir.yield_element %c1_i32 : i32
}
hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
hlfir.destroy %elemental : !hlfir.expr<42xi32>
cf.br ^bb2
^bb2:
omp.terminator
}
return
}
16 changes: 16 additions & 0 deletions libc/src/__support/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,25 @@
#define LLVM_LIBC_FUNCTION_ATTR
#endif

// Allow each function `func` to have extra attributes specified by defining:
// `LLVM_LIBC_FUNCTION_ATTR_func` macro, which should always start with
// "LLVM_LIBC_EMPTY, "
//
// For examples:
// #define LLVM_LIBC_FUNCTION_ATTR_memcpy LLVM_LIBC_EMPTY, [[gnu::weak]]
// #define LLVM_LIBC_FUNCTION_ATTR_memchr LLVM_LIBC_EMPTY, [[gnu::weak]] \
// [[gnu::visibility("default")]]
#define LLVM_LIBC_EMPTY

#define GET_SECOND(first, second, ...) second
#define EXPAND_THEN_SECOND(name) GET_SECOND(name, LLVM_LIBC_EMPTY)

#define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name)

// MacOS needs to be excluded because it does not support aliasing.
#if defined(LIBC_COPT_PUBLIC_PACKAGING) && (!defined(__APPLE__))
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \
LLVM_LIBC_ATTR(name) \
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \
__##name##_impl__ __asm__(#name); \
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \
Expand Down
2 changes: 1 addition & 1 deletion libc/src/string/string_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
//
// Standalone string utility functions. Utilities requiring memory allocations
// should be placed in allocating_string_utils.h intead.
// should be placed in allocating_string_utils.h instead.
//
//===----------------------------------------------------------------------===//

Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__chrono/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(

case _CharT('Y'):
// Depending on the platform's libc the range of supported years is
// limited. Intead of of testing all conditions use the internal
// limited. Instead of of testing all conditions use the internal
// implementation unconditionally.
__formatter::__format_year(__sstr, __t.tm_year + 1900);
break;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__cxx03/__chrono/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(

case _CharT('Y'):
// Depending on the platform's libc the range of supported years is
// limited. Intead of of testing all conditions use the internal
// limited. Instead of of testing all conditions use the internal
// implementation unconditionally.
__formatter::__format_year(__sstr, __t.tm_year + 1900);
break;
Expand Down
19 changes: 9 additions & 10 deletions libcxx/include/thread
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,17 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);

#if _LIBCPP_HAS_THREADS

# include <__thread/formatter.h>
# include <__thread/jthread.h>
# include <__thread/support.h>
# include <__thread/this_thread.h>
# include <__thread/thread.h>

# if _LIBCPP_STD_VER >= 20
# include <__thread/jthread.h>
# endif

# if _LIBCPP_STD_VER >= 23
# include <__thread/formatter.h>
# endif

# include <version>

// standard-mandated includes
Expand All @@ -108,13 +114,6 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);

#endif // _LIBCPP_HAS_THREADS

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
# include <cstddef>
# include <ctime>
# include <iosfwd>
# include <ratio>
#endif

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
# include <chrono>
#endif
Expand Down
1 change: 1 addition & 0 deletions libcxx/test/benchmarks/atomic_wait.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <atomic>
#include <cstdint>
#include <numeric>
#include <stop_token>
#include <thread>
Expand Down
2 changes: 1 addition & 1 deletion libcxx/test/benchmarks/atomic_wait_vs_mutex_lock.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <atomic>
#include <cstdint>
#include <mutex>
#include <numeric>
#include <stop_token>
#include <thread>

Expand Down
2 changes: 1 addition & 1 deletion libcxx/test/benchmarks/stop_token.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <numeric>
#include <cstdint>
#include <optional>
#include <stop_token>
#include <thread>
Expand Down
2 changes: 1 addition & 1 deletion libcxx/test/configs/cmake-bridge.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ config.substitutions.append(('%{target-include-dir}', '@LIBCXX_TESTING_INSTALL_P
config.substitutions.append(('%{lib-dir}', '@LIBCXX_TESTING_INSTALL_PREFIX@/@LIBCXX_INSTALL_LIBRARY_DIR@'))
config.substitutions.append(('%{module-dir}', '@LIBCXX_TESTING_INSTALL_PREFIX@/@LIBCXX_INSTALL_MODULES_DIR@'))
config.substitutions.append(('%{test-tools-dir}', '@LIBCXX_TEST_TOOLS_PATH@'))
config.substitutions.append(('%{benchmark_flags}', '-I @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/include -L @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/lib -l benchmark'))
config.substitutions.append(('%{benchmark_flags}', '-I @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/include -L @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/lib -L @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/lib64 -l benchmark'))
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <atomic>
#include <cassert>
#include <chrono>
#include <cstdint>
#include <thread>

#include "make_test_thread.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
// These compiler versions don't enable sized deallocation by default.
// UNSUPPORTED: clang-17, clang-18

// Android clang-r536225 identifies as clang-19.0 but it predates the real
// LLVM 19.0.0, so it also leaves sized deallocation off by default.
// UNSUPPORTED: android && clang-19.0

// UNSUPPORTED: sanitizer-new-delete, c++03, c++11
// XFAIL: apple-clang
// XFAIL: using-built-library-before-llvm-11
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
// These compiler versions do not enable sized deallocation by default.
// UNSUPPORTED: clang-17, clang-18

// Android clang-r536225 identifies as clang-19.0 but it predates the real
// LLVM 19.0.0, so it also leaves sized deallocation off by default.
// UNSUPPORTED: android && clang-19.0

// UNSUPPORTED: sanitizer-new-delete, c++03, c++11
// XFAIL: apple-clang
// XFAIL: using-built-library-before-llvm-11
Expand Down
4 changes: 1 addition & 3 deletions libcxx/test/std/thread/thread.semaphore/max.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@

// <semaphore>

#include <cstddef>
#include <semaphore>
#include <thread>

#include "test_macros.h"

int main(int, char**)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,15 @@ typedef void (*FunctionPtr)();
int main(int, char**)
{
test_is_array<char[3]>();
// Android clang-r536225 identifies as clang-19.0, but it predates the
// LLVM 19.0.0 release. It lacks llvm.org/pr86652, which changed __is_array
// to return false for T[0]. llvm.org/pr93037 relies on that change for
// correct handling of std::is_array<T[0]>. This test will pass as long as
// Clang and libc++ come from the same LLVM commit, but we can't detect that
// here.
#if !defined(__ANDROID__) || TEST_CLANG_VER != 1900
test_is_not_array<char[0]>();
#endif
test_is_array<char[]>();
test_is_array<Union[]>();

Expand Down
6 changes: 3 additions & 3 deletions libcxx/utils/ci/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ services:
target: android-buildkite-builder
args:
BASE_IMAGE: ubuntu:noble
ANDROID_CLANG_VERSION: r498229b
ANDROID_CLANG_PREBUILTS_COMMIT: 5186d132c99aa75dc25207c392e3ea5b93d0107e
ANDROID_SYSROOT_BID: 10957860
ANDROID_CLANG_VERSION: r536225
ANDROID_CLANG_PREBUILTS_COMMIT: 3f67b93ee7a50ae2a3cb34cc32d0589415cc0a9c
ANDROID_SYSROOT_BID: 12644632
<<: *compiler_versions
Loading