26 changes: 26 additions & 0 deletions clang/test/SemaCXX/constexpr-never-constant.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify -fcxx-exceptions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -Winvalid-constexpr -verify -fcxx-exceptions %s
// Note: for a diagnostic that defaults to an error, -Wno-foo -Wfoo will
// disable the diagnostic and then re-enable it *as a warning* rather than as
// an error. So we manually enable it as an error again with -Werror to keep
// the diagnostic checks consistent.
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -Wno-invalid-constexpr -Winvalid-constexpr -Werror=invalid-constexpr -verify -fcxx-exceptions %s

// RUN: %clang_cc1 -fsyntax-only -Wno-invalid-constexpr -verify=good -fcxx-exceptions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -verify=good -fcxx-exceptions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -Wno-invalid-constexpr -verify=good -fcxx-exceptions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -Winvalid-constexpr -Wno-invalid-constexpr -verify=good -fcxx-exceptions %s
// RUN: %clang_cc1 -fsyntax-only -Wno-invalid-constexpr -verify=good -fcxx-exceptions %s
// good-no-diagnostics

constexpr void func() { // expected-error {{constexpr function never produces a constant expression}}
throw 12; // expected-note {{subexpression not valid in a constant expression}}
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-constexpr"
constexpr void other_func() {
#pragma clang diagnostic pop

throw 12;
}
38 changes: 38 additions & 0 deletions clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,41 @@ namespace use_self {

int fib(int n) { return FibTree{n}.v; }
}

namespace nested_union {
union Test1 {
union {
int inner { 42 };
};
int outer;
};
static_assert(Test1{}.inner == 42, "");
struct Test2 {
union {
struct {
int inner : 32 { 42 }; // expected-warning {{C++20 extension}}
int inner_no_init;
};
int outer;
};
};
static_assert(Test2{}.inner == 42, "");
static_assert(Test2{}.inner_no_init == 0, "");
struct Int { int x; };
struct Test3 {
int x;
union {
struct { // expected-note {{in implicit initialization}}
const int& y; // expected-note {{uninitialized reference member is here}}
int inner : 32 { 42 }; // expected-warning {{C++20 extension}}
};
int outer;
};
};
Test3 test3 = {1}; // expected-error {{reference member of type 'const int &' uninitialized}}
constexpr char f(Test3) { return 1; } // expected-note {{candidate function}}
constexpr char f(Int) { return 2; } // expected-note {{candidate function}}
// FIXME: This shouldn't be ambiguous; either we should reject the declaration
// of Test3, or we should exclude f(Test3) as a candidate.
static_assert(f({1}) == 2, ""); // expected-error {{call to 'f' is ambiguous}}
}
10 changes: 10 additions & 0 deletions clang/test/SemaCXX/cxx2c-pack-indexing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,13 @@ void f( ) {


}

namespace std {
struct type_info {
const char *name;
};
} // namespace std

namespace GH93650 {
auto func(auto... inputArgs) { return typeid(inputArgs...[0]); }
} // namespace GH93650
75 changes: 75 additions & 0 deletions clang/test/SemaCXX/lambda-unevaluated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,78 @@ void recursive() {

}
}

// GH63845: Test if we have skipped past RequiresExprBodyDecls in tryCaptureVariable().
namespace GH63845 {

template <bool> struct A {};

struct true_type {
constexpr operator bool() noexcept { return true; }
};

constexpr bool foo() {
true_type x{};
return requires { typename A<x>; };
}

static_assert(foo());

} // namespace GH63845

// GH69307: Test if we can correctly handle param decls that have yet to get into the function scope.
namespace GH69307 {

constexpr auto ICE() {
constexpr auto b = 1;
return [=](auto c) -> int
requires requires { b + c; }
{ return 1; };
};

constexpr auto Ret = ICE()(1);

} // namespace GH69307

// GH88081: Test if we evaluate the requires expression with lambda captures properly.
namespace GH88081 {

// Test that ActOnLambdaClosureQualifiers() is called only once.
void foo(auto value)
requires requires { [&] -> decltype(value) {}; }
// expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
{}

struct S { //#S
S(auto value) //#S-ctor
requires requires { [&] -> decltype(value) { return 2; }; } {} // #S-requires

static auto foo(auto value) -> decltype([&]() -> decltype(value) {}()) { return {}; } // #S-foo

// FIXME: 'value' does not constitute an ODR use here. Add a diagnostic for it.
static auto bar(auto value) -> decltype([&] { return value; }()) {
return "a"; // #bar-body
}
};

S s("a"); // #use
// expected-error@#S-requires {{cannot initialize return object of type 'decltype(value)' (aka 'const char *') with an rvalue of type 'int'}}
// expected-error@#use {{no matching constructor}}
// expected-note@#S-requires {{substituting into a lambda expression here}}
// expected-note@#S-requires {{substituting template arguments into constraint expression here}}
// expected-note@#S-requires {{in instantiation of requirement here}}
// expected-note@#use {{checking constraint satisfaction for template 'S<const char *>' required here}}
// expected-note@#use {{requested here}}
// expected-note-re@#S 2{{candidate constructor {{.*}} not viable}}
// expected-note@#S-ctor {{constraints not satisfied}}
// expected-note-re@#S-requires {{because {{.*}} would be invalid}}

void func() {
S::foo(42);
S::bar("str");
S::bar(0.618);
// expected-error-re@#bar-body {{cannot initialize return object of type {{.*}} (aka 'double') with an lvalue of type 'const char[2]'}}
// expected-note@-2 {{requested here}}
}

} // namespace GH88081
29 changes: 21 additions & 8 deletions clang/tools/clang-scan-deps/ClangScanDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,20 @@ static llvm::json::Array toJSONSorted(std::vector<ModuleID> V) {
return Ret;
}

static llvm::json::Array
toJSONSorted(llvm::SmallVector<Module::LinkLibrary, 2> &LinkLibs) {
llvm::sort(LinkLibs, [](const Module::LinkLibrary &lhs,
const Module::LinkLibrary &rhs) {
return lhs.Library < rhs.Library;
});

llvm::json::Array Ret;
for (const Module::LinkLibrary &LL : LinkLibs)
Ret.push_back(llvm::json::Object(
{{"link-name", LL.Library}, {"isFramework", LL.IsFramework}}));
return Ret;
}

// Thread safe.
class FullDeps {
public:
Expand Down Expand Up @@ -439,14 +453,13 @@ class FullDeps {
Array OutModules;
for (auto &&ModID : ModuleIDs) {
auto &MD = Modules[ModID];
Object O{
{"name", MD.ID.ModuleName},
{"context-hash", MD.ID.ContextHash},
{"file-deps", toJSONSorted(MD.FileDeps)},
{"clang-module-deps", toJSONSorted(MD.ClangModuleDeps)},
{"clang-modulemap-file", MD.ClangModuleMapFile},
{"command-line", MD.getBuildArguments()},
};
Object O{{"name", MD.ID.ModuleName},
{"context-hash", MD.ID.ContextHash},
{"file-deps", toJSONSorted(MD.FileDeps)},
{"clang-module-deps", toJSONSorted(MD.ClangModuleDeps)},
{"clang-modulemap-file", MD.ClangModuleMapFile},
{"command-line", MD.getBuildArguments()},
{"link-libraries", toJSONSorted(MD.LinkLibraries)}};
OutModules.push_back(std::move(O));
}

Expand Down
40 changes: 40 additions & 0 deletions clang/unittests/AST/ASTImporterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9674,6 +9674,46 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportInstantiatedFromMember) {
EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
}

AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, ConstName) {
for (EnumConstantDecl *D : Node.enumerators())
if (D->getName() == ConstName)
return true;
return false;
}

TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnum) {
const char *ToCode =
R"(
struct A {
enum { E1, E2} x;
enum { E3, E4} y;
};
)";
Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
auto *ToE1 = FirstDeclMatcher<EnumDecl>().match(
ToTU, enumDecl(hasEnumConstName("E1")));
auto *ToE3 = FirstDeclMatcher<EnumDecl>().match(
ToTU, enumDecl(hasEnumConstName("E3")));
const char *Code =
R"(
struct A {
enum { E1, E2} x;
enum { E3, E4} y;
};
)";
Decl *FromTU = getTuDecl(Code, Lang_CXX11);
auto *FromE1 = FirstDeclMatcher<EnumDecl>().match(
FromTU, enumDecl(hasEnumConstName("E1")));
auto *ImportedE1 = Import(FromE1, Lang_CXX11);
ASSERT_TRUE(ImportedE1);
EXPECT_EQ(ImportedE1, ToE1);
auto *FromE3 = FirstDeclMatcher<EnumDecl>().match(
FromTU, enumDecl(hasEnumConstName("E3")));
auto *ImportedE3 = Import(FromE3, Lang_CXX11);
ASSERT_TRUE(ImportedE3);
EXPECT_EQ(ImportedE3, ToE3);
}

INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions);

Expand Down
56 changes: 56 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3760,6 +3760,62 @@ TEST(TransferTest, AddrOfReference) {
});
}

TEST(TransferTest, Preincrement) {
std::string Code = R"(
void target(int I) {
int &IRef = ++I;
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

EXPECT_EQ(&getLocForDecl(ASTCtx, Env, "IRef"),
&getLocForDecl(ASTCtx, Env, "I"));
});
}

TEST(TransferTest, Postincrement) {
std::string Code = R"(
void target(int I) {
int OldVal = I++;
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

EXPECT_EQ(&getValueForDecl(ASTCtx, Env, "OldVal"),
&getValueForDecl(ASTCtx, Env, "I"));
});
}

// We test just one of the compound assignment operators because we know the
// code for propagating the storage location is shared among all of them.
TEST(TransferTest, AddAssign) {
std::string Code = R"(
void target(int I) {
int &IRef = (I += 1);
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

EXPECT_EQ(&getLocForDecl(ASTCtx, Env, "IRef"),
&getLocForDecl(ASTCtx, Env, "I"));
});
}

TEST(TransferTest, CannotAnalyzeFunctionTemplate) {
std::string Code = R"(
template <typename T>
Expand Down
6 changes: 3 additions & 3 deletions clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -10980,7 +10980,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1862.html">1862</a></td>
<td>CD5</td>
<td>Determining &#8220;corresponding members&#8221; for friendship</td>
<td class="unknown" align="center">Unknown</td>
<td class="none" align="center">No</td>
</tr>
<tr id="1863">
<td><a href="https://cplusplus.github.io/CWG/issues/1863.html">1863</a></td>
Expand Down Expand Up @@ -11316,7 +11316,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1918.html">1918</a></td>
<td>CD5</td>
<td><TT>friend</TT> templates with dependent scopes</td>
<td class="unknown" align="center">Unknown</td>
<td class="none" align="center">No</td>
</tr>
<tr class="open" id="1919">
<td><a href="https://cplusplus.github.io/CWG/issues/1919.html">1919</a></td>
Expand Down Expand Up @@ -11478,7 +11478,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1945.html">1945</a></td>
<td>CD5</td>
<td>Friend declarations naming members of class templates in non-templates</td>
<td class="unknown" align="center">Unknown</td>
<td class="none" align="center">No</td>
</tr>
<tr id="1946">
<td><a href="https://cplusplus.github.io/CWG/issues/1946.html">1946</a></td>
Expand Down
3 changes: 2 additions & 1 deletion compiler-rt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# based on the ability of the host toolchain to target various platforms.

cmake_minimum_required(VERSION 3.20.0)
set(LLVM_SUBPROJECT_TITLE "Compiler-RT")

if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS)
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
Expand Down Expand Up @@ -90,7 +91,7 @@ if (COMPILER_RT_STANDALONE_BUILD)
if (TARGET intrinsics_gen)
# Loading the llvm config causes this target to be imported so place it
# under the appropriate folder in an IDE.
set_target_properties(intrinsics_gen PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(intrinsics_gen PROPERTIES FOLDER "LLVM/Tablegenning")
endif()

find_package(Python3 COMPONENTS Interpreter)
Expand Down
19 changes: 10 additions & 9 deletions compiler-rt/cmake/Modules/AddCompilerRT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function(add_compiler_rt_object_libraries name)
${extra_cflags_${libname}} ${target_flags})
set_property(TARGET ${libname} APPEND PROPERTY
COMPILE_DEFINITIONS ${LIB_DEFS})
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT/Libraries")
if(APPLE)
set_target_properties(${libname} PROPERTIES
OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
Expand All @@ -110,7 +110,7 @@ endmacro()

function(add_compiler_rt_component name)
add_custom_target(${name})
set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT/Components")
if(COMMAND runtime_register_component)
runtime_register_component(${name})
endif()
Expand Down Expand Up @@ -293,7 +293,7 @@ function(add_compiler_rt_runtime name type)
if(NOT TARGET ${LIB_PARENT_TARGET})
add_custom_target(${LIB_PARENT_TARGET})
set_target_properties(${LIB_PARENT_TARGET} PROPERTIES
FOLDER "Compiler-RT Misc")
FOLDER "Compiler-RT/Runtimes")
endif()
endif()

Expand Down Expand Up @@ -348,6 +348,7 @@ function(add_compiler_rt_runtime name type)
DEPENDS ${sources_${libname}}
COMMENT "Building C object ${output_file_${libname}}")
add_custom_target(${libname} DEPENDS ${output_dir_${libname}}/${output_file_${libname}})
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT/Codegenning")
install(FILES ${output_dir_${libname}}/${output_file_${libname}}
DESTINATION ${install_dir_${libname}}
${COMPONENT_OPTION})
Expand All @@ -370,8 +371,8 @@ function(add_compiler_rt_runtime name type)
add_dependencies(${libname} ${LIB_DEPS})
endif()
set_target_properties(${libname} PROPERTIES
OUTPUT_NAME ${output_name_${libname}})
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime")
OUTPUT_NAME ${output_name_${libname}}
FOLDER "Compiler-RT/Runtimes")
if(LIB_LINK_LIBS)
target_link_libraries(${libname} PRIVATE ${LIB_LINK_LIBS})
endif()
Expand Down Expand Up @@ -538,7 +539,7 @@ function(add_compiler_rt_test test_suite test_name arch)
DEPENDS ${TEST_DEPS}
)
add_custom_target(T${test_name} DEPENDS "${output_bin}")
set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT/Tests")

# Make the test suite depend on the binary.
add_dependencies(${test_suite} T${test_name})
Expand All @@ -558,7 +559,7 @@ macro(add_compiler_rt_resource_file target_name file_name component)
COMPONENT ${component})
add_dependencies(${component} ${target_name})

set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT/Resources")
endmacro()

macro(add_compiler_rt_script name)
Expand Down Expand Up @@ -607,7 +608,7 @@ macro(add_custom_libcxx name prefix)
COMMENT "Clobbering ${name} build directories"
USES_TERMINAL
)
set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT/Metatargets")

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
Expand All @@ -619,7 +620,7 @@ macro(add_custom_libcxx name prefix)

add_custom_target(${name}-clobber
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT/Metatargets")

set(PASSTHROUGH_VARIABLES
ANDROID
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ macro(darwin_add_builtin_library name suffix)

list(APPEND ${LIB_OS}_${suffix}_libs ${libname})
list(APPEND ${LIB_OS}_${suffix}_lipo_flags -arch ${arch} $<TARGET_FILE:${libname}>)
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT/Libraries")
endmacro()

function(darwin_lipo_libs name)
Expand All @@ -355,7 +355,7 @@ function(darwin_lipo_libs name)
)
add_custom_target(${name}
DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)
set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT/Misc")
add_dependencies(${LIB_PARENT_TARGET} ${name})

if(CMAKE_CONFIGURATION_TYPES)
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/cmake/Modules/CompilerRTUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,9 @@ function(add_compiler_rt_install_targets name)
-DCMAKE_INSTALL_DO_STRIP=1
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
set_target_properties(install-${ARG_PARENT_TARGET} PROPERTIES
FOLDER "Compiler-RT Misc")
FOLDER "Compiler-RT/Installation")
set_target_properties(install-${ARG_PARENT_TARGET}-stripped PROPERTIES
FOLDER "Compiler-RT Misc")
FOLDER "Compiler-RT/Installation")
add_dependencies(install-compiler-rt install-${ARG_PARENT_TARGET})
add_dependencies(install-compiler-rt-stripped install-${ARG_PARENT_TARGET}-stripped)
endif()
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/cmake/base-config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ endif()
add_custom_target(compiler-rt ALL)
add_custom_target(install-compiler-rt)
add_custom_target(install-compiler-rt-stripped)
set_property(TARGET compiler-rt PROPERTY FOLDER "Compiler-RT/Metatargets")
set_property(
TARGET
compiler-rt
install-compiler-rt
install-compiler-rt-stripped
PROPERTY
FOLDER "Compiler-RT Misc"
FOLDER "Compiler-RT/Installation"
)

# Setting these variables from an LLVM build is sufficient that compiler-rt can
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ endforeach( f )

add_custom_target(compiler-rt-headers ALL DEPENDS ${out_files})
add_dependencies(compiler-rt compiler-rt-headers)
set_target_properties(compiler-rt-headers PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(compiler-rt-headers PROPERTIES FOLDER "Compiler-RT/Resources")

# Install sanitizer headers.
install(FILES ${SANITIZER_HEADERS}
Expand Down
8 changes: 4 additions & 4 deletions compiler-rt/lib/asan/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,15 @@ append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_UNITTEST_NOINST_LIBS)

# Main AddressSanitizer unit tests.
add_custom_target(AsanUnitTests)
set_target_properties(AsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(AsanUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")

# AddressSanitizer unit tests with dynamic runtime (on platforms where it's
# not the default).
add_custom_target(AsanDynamicUnitTests)
set_target_properties(AsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(AsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")
# ASan benchmarks (not actively used now).
add_custom_target(AsanBenchmarks)
set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Compiler-RT/Tests")

set(ASAN_NOINST_TEST_SOURCES
${COMPILER_RT_GTEST_SOURCE}
Expand Down Expand Up @@ -278,7 +278,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")

add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-inline")
add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-calls"
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ set(ve_SOURCES
${GENERIC_SOURCES})

add_custom_target(builtins)
set_target_properties(builtins PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(builtins PROPERTIES FOLDER "Compiler-RT/Metatargets")

option(COMPILER_RT_ENABLE_SOFTWARE_INT128
"Enable the int128 builtin routines for all targets."
Expand Down
17 changes: 5 additions & 12 deletions compiler-rt/lib/builtins/atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,12 @@ static Lock locks[SPINLOCK_COUNT]; // initialized to OS_SPINLOCK_INIT which is 0
#else
_Static_assert(__atomic_always_lock_free(sizeof(uintptr_t), 0),
"Implementation assumes lock-free pointer-size cmpxchg");
typedef _Atomic(uintptr_t) Lock;
#include <pthread.h>
typedef pthread_mutex_t Lock;
/// Unlock a lock. This is a release operation.
__inline static void unlock(Lock *l) {
__c11_atomic_store(l, 0, __ATOMIC_RELEASE);
}
/// Locks a lock. In the current implementation, this is potentially
/// unbounded in the contended case.
__inline static void lock(Lock *l) {
uintptr_t old = 0;
while (!__c11_atomic_compare_exchange_weak(l, &old, 1, __ATOMIC_ACQUIRE,
__ATOMIC_RELAXED))
old = 0;
}
__inline static void unlock(Lock *l) { pthread_mutex_unlock(l); }
/// Locks a lock.
__inline static void lock(Lock *l) { pthread_mutex_lock(l); }
/// locks for atomic operations
static Lock locks[SPINLOCK_COUNT];
#endif
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/lib/fuzzer/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ if (APPLE)
endif()

add_custom_target(FuzzerUnitTests)
set_target_properties(FuzzerUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(FuzzerUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")

add_custom_target(FuzzedDataProviderUnitTests)
set_target_properties(FuzzedDataProviderUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(FuzzedDataProviderUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")

set(LIBFUZZER_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_LINK_FLAGS})
list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS --driver-mode=g++)
Expand Down Expand Up @@ -58,7 +58,7 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH)
${LIBFUZZER_TEST_RUNTIME_OBJECTS})
set_target_properties(${LIBFUZZER_TEST_RUNTIME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")

if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
COMPILER_RT_LIBCXX_PATH AND
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/gwp_asan/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ set(GWP_ASAN_UNIT_TEST_HEADERS
harness.h)

add_custom_target(GwpAsanUnitTests)
set_target_properties(GwpAsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(GwpAsanUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")

set(GWP_ASAN_UNITTEST_LINK_FLAGS
${COMPILER_RT_UNITTEST_LINK_FLAGS} -ldl
Expand Down Expand Up @@ -67,7 +67,7 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST GWP_ASAN_SUPPORTED_ARCH)

set_target_properties(${GWP_ASAN_TEST_RUNTIME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")

set(GwpAsanTestObjects)
generate_compiler_rt_tests(GwpAsanTestObjects
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/interception/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ macro(add_interceptor_lib library)
add_library(${library} STATIC ${ARGN})
set_target_properties(${library} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")
endmacro()

function(get_interception_lib_for_arch arch lib)
Expand All @@ -96,7 +96,7 @@ endfunction()
# Interception unit tests testsuite.
add_custom_target(InterceptionUnitTests)
set_target_properties(InterceptionUnitTests PROPERTIES
FOLDER "Compiler-RT Tests")
FOLDER "Compiler-RT/Tests")

# Adds interception tests for architecture.
macro(add_interception_tests_for_arch arch)
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/memprof/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ macro(add_memprof_tests_for_arch arch)
add_library(${MEMPROF_TEST_RUNTIME} STATIC ${MEMPROF_TEST_RUNTIME_OBJECTS})
set_target_properties(${MEMPROF_TEST_RUNTIME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")
set(MEMPROF_TEST_OBJECTS)
generate_compiler_rt_tests(MEMPROF_TEST_OBJECTS
MemProfUnitTests "MemProf-${arch}-UnitTest" ${arch}
Expand All @@ -78,7 +78,7 @@ endmacro()

# MemProf unit tests testsuite.
add_custom_target(MemProfUnitTests)
set_target_properties(MemProfUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(MemProfUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")
if(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST MEMPROF_SUPPORTED_ARCH)
# MemProf unit tests are only run on the host machine.
foreach(arch ${COMPILER_RT_DEFAULT_TARGET_ARCH})
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/lib/orc/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ include_directories(..)

# Unit tests target.
add_custom_target(OrcRTUnitTests)
set_target_properties(OrcRTUnitTests PROPERTIES FOLDER "OrcRT unittests")
set_target_properties(OrcRTUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")

# Testing tools target.
add_custom_target(OrcRTTools)
set_target_properties(OrcRTTools PROPERTIES FOLDER "OrcRT tools")
set_target_properties(OrcRTTools PROPERTIES FOLDER "Compiler-RT/Tools")

set(ORC_UNITTEST_CFLAGS
# FIXME: This should be set for all unit tests.
Expand All @@ -22,7 +22,7 @@ function(add_orc_lib library)
add_library(${library} STATIC ${ARGN})
set_target_properties(${library} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")
endfunction()

function(get_orc_lib_for_arch arch lib)
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ macro(add_sanitizer_common_lib library)
add_library(${library} STATIC ${ARGN})
set_target_properties(${library} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")
endmacro()

function(get_sanitizer_common_lib_for_arch arch lib)
Expand All @@ -157,7 +157,7 @@ endfunction()

# Sanitizer_common unit tests testsuite.
add_custom_target(SanitizerUnitTests)
set_target_properties(SanitizerUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
set_target_properties(SanitizerUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")

# Adds sanitizer tests for architecture.
macro(add_sanitizer_tests_for_arch arch)
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/stats/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set(STATS_HEADERS
include_directories(..)

add_custom_target(stats)
set_target_properties(stats PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(stats PROPERTIES FOLDER "Compiler-RT/Metatargets")

if(APPLE)
set(STATS_LIB_FLAVOR SHARED)
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/tsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if(COMPILER_RT_LIBCXX_PATH AND
endforeach()

add_custom_target(libcxx_tsan DEPENDS ${libcxx_tsan_deps})
set_target_properties(libcxx_tsan PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(libcxx_tsan PROPERTIES FOLDER "Compiler-RT/Metatargets")
endif()

if(COMPILER_RT_INCLUDE_TESTS)
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/tsan/dd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ append_list_if(COMPILER_RT_HAS_LIBRT rt DD_LINKLIBS)
append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread DD_LINKLIBS)

add_custom_target(dd)
set_target_properties(dd PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(dd PROPERTIES FOLDER "Compiler-RT/Metatargets")

# Deadlock detector is currently supported on 64-bit Linux only.
if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE AND NOT ANDROID)
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/tsan/rtl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ if(APPLE)
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../go
COMMENT "Checking TSan Go runtime..."
VERBATIM)
set_target_properties(GotsanRuntimeCheck PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(GotsanRuntimeCheck PROPERTIES FOLDER "Compiler-RT/Misc")
else()
foreach(arch ${TSAN_SUPPORTED_ARCH})
if(arch STREQUAL "x86_64")
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/xray/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include_directories(..)

add_custom_target(XRayUnitTests)
set_target_properties(XRayUnitTests PROPERTIES FOLDER "XRay unittests")
set_target_properties(XRayUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")

# Sanity check XRAY_ALL_SOURCE_FILES_ABS_PATHS
list(LENGTH XRAY_ALL_SOURCE_FILES_ABS_PATHS XASFAP_LENGTH)
Expand Down Expand Up @@ -34,7 +34,7 @@ function(add_xray_lib library)
add_library(${library} STATIC ${ARGN})
set_target_properties(${library} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
FOLDER "Compiler-RT Runtime tests")
FOLDER "Compiler-RT/Tests/Runtime")
endfunction()

function(get_xray_lib_for_arch arch lib)
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ endif()
# introduce a rule to run to run all of them.
get_property(LLVM_COMPILER_RT_LIT_DEPENDS GLOBAL PROPERTY LLVM_COMPILER_RT_LIT_DEPENDS)
add_custom_target(compiler-rt-test-depends)
set_target_properties(compiler-rt-test-depends PROPERTIES FOLDER "Compiler-RT/Tests")
if(LLVM_COMPILER_RT_LIT_DEPENDS)
add_dependencies(compiler-rt-test-depends ${LLVM_COMPILER_RT_LIT_DEPENDS})
endif()
Expand Down
3 changes: 0 additions & 3 deletions compiler-rt/test/asan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,11 @@ add_lit_testsuite(check-asan "Running the AddressSanitizer tests"
${ASAN_TESTSUITES}
${exclude_from_check_all}
DEPENDS ${ASAN_TEST_DEPS})
set_target_properties(check-asan PROPERTIES FOLDER "Compiler-RT Misc")

if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
add_lit_testsuite(check-asan-dynamic
"Running the AddressSanitizer tests with dynamic runtime"
${ASAN_DYNAMIC_TESTSUITES}
${exclude_from_check_all.g}
DEPENDS ${ASAN_DYNAMIC_TEST_DEPS})
set_target_properties(check-asan-dynamic
PROPERTIES FOLDER "Compiler-RT Misc")
endif()
1 change: 0 additions & 1 deletion compiler-rt/test/asan_abi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,3 @@ add_lit_testsuite(check-asan-abi "Running the AddressSanitizerABI tests"
${ASAN_ABI_TESTSUITES}
${exclude_from_check_all}
DEPENDS ${ASAN_ABI_TEST_DEPS})
set_target_properties(check-asan-abi PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,3 @@ endforeach()
add_lit_testsuite(check-builtins "Running the Builtins tests"
${BUILTINS_TESTSUITES}
DEPENDS ${BUILTINS_TEST_DEPS})
set_target_properties(check-builtins PROPERTIES FOLDER "Compiler-RT Misc")
3 changes: 0 additions & 3 deletions compiler-rt/test/cfi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,3 @@ add_lit_target(check-cfi-and-supported "Running the cfi regression tests"
${CFI_TESTSUITES}
PARAMS check_supported=1
DEPENDS ${CFI_TEST_DEPS})

set_target_properties(check-cfi PROPERTIES FOLDER "Compiler-RT Misc")
set_target_properties(check-cfi-and-supported PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/dfsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ list(APPEND DFSAN_TEST_DEPS dfsan)
add_lit_testsuite(check-dfsan "Running the DataFlowSanitizer tests"
${DFSAN_TESTSUITES}
DEPENDS ${DFSAN_TEST_DEPS})
set_target_properties(check-dfsan PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/fuzzer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ if(LIBFUZZER_TESTSUITES)
add_lit_testsuite(check-fuzzer "Running libFuzzer tests"
${LIBFUZZER_TESTSUITES}
DEPENDS ${LIBFUZZER_TEST_DEPS})
set_target_properties(check-fuzzer PROPERTIES FOLDER "Compiler-RT Tests")
endif()

if (APPLE)
Expand Down
1 change: 0 additions & 1 deletion compiler-rt/test/gwp_asan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,4 @@ if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_SCUDO_STANDALONE AND COMPILER_
add_lit_testsuite(check-gwp_asan "Running the GWP-ASan tests"
${GWP_ASAN_TESTSUITES}
DEPENDS ${GWP_ASAN_TEST_DEPS})
set_target_properties(check-gwp_asan PROPERTIES FOLDER "Compiler-RT Misc")
endif()
2 changes: 0 additions & 2 deletions compiler-rt/test/hwasan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ add_lit_testsuite(check-hwasan "Running the HWAddressSanitizer tests"
DEPENDS ${HWASAN_TEST_DEPS}
PARAMS "HWASAN_ENABLE_ALIASES=1"
)
set_target_properties(check-hwasan PROPERTIES FOLDER "Compiler-RT Misc")

add_lit_testsuite(check-hwasan-lam
"Running the HWAddressSanitizer tests with Intel LAM"
Expand All @@ -42,4 +41,3 @@ add_lit_testsuite(check-hwasan-lam
PARAMS "HWASAN_ENABLE_ALIASES=0"
EXCLUDE_FROM_CHECK_ALL
)
set_target_properties(check-hwasan-lam PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/interception/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@ endif()
add_lit_testsuite(check-interception "Running the Interception tests"
${INTERCEPTION_TESTSUITES}
DEPENDS ${INTERCEPTION_TEST_DEPS})
set_target_properties(check-interception PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/lsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,3 @@ append_list_if(COMPILER_RT_HAS_HWASAN hwasan LSAN_TEST_DEPS)
add_lit_testsuite(check-lsan "Running the LeakSanitizer tests"
${LSAN_TESTSUITES}
DEPENDS ${LSAN_TEST_DEPS})
set_target_properties(check-lsan PROPERTIES FOLDER "Compiler-RT Misc")
3 changes: 0 additions & 3 deletions compiler-rt/test/memprof/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,9 @@ endif()
add_lit_testsuite(check-memprof "Running the MemProfiler tests"
${MEMPROF_TESTSUITES}
DEPENDS ${MEMPROF_TEST_DEPS})
set_target_properties(check-memprof PROPERTIES FOLDER "Compiler-RT Misc")

add_lit_testsuite(check-memprof-dynamic
"Running the MemProfiler tests with dynamic runtime"
${MEMPROF_DYNAMIC_TESTSUITES}
${exclude_from_check_all.g}
DEPENDS ${MEMPROF_DYNAMIC_TEST_DEPS})
set_target_properties(check-memprof-dynamic
PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/metadata/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ if(CAN_TARGET_x86_64)
add_lit_testsuite(check-sanmd "Running the SanitizerBinaryMetadata tests"
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${METADATA_TEST_DEPS})
set_target_properties(check-sanmd PROPERTIES FOLDER "Compiler-RT Misc")
endif()
1 change: 0 additions & 1 deletion compiler-rt/test/msan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,3 @@ add_lit_testsuite(check-msan "Running the MemorySanitizer tests"
${MSAN_TESTSUITES}
DEPENDS ${MSAN_TEST_DEPS}
)
set_target_properties(check-msan PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/orc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,3 @@ endif()
add_lit_testsuite(check-orc-rt "Running the ORC runtime tests"
${ORC_TESTSUITES}
DEPENDS ${ORC_TEST_DEPS})
set_target_properties(check-orc-rt PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/profile/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,3 @@ endforeach()
add_lit_testsuite(check-profile "Running the profile tests"
${PROFILE_TESTSUITES}
DEPENDS ${PROFILE_TEST_DEPS})
set_target_properties(check-profile PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/safestack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,3 @@ configure_lit_site_cfg(
add_lit_testsuite(check-safestack "Running the SafeStack tests"
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${SAFESTACK_TEST_DEPS})
set_target_properties(check-safestack PROPERTIES FOLDER "Compiler-RT Misc")
2 changes: 0 additions & 2 deletions compiler-rt/test/sanitizer_common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,4 @@ if(SANITIZER_COMMON_TESTSUITES)
add_lit_testsuite(check-sanitizer "Running sanitizer_common tests"
${SANITIZER_COMMON_TESTSUITES}
DEPENDS ${SANITIZER_COMMON_TEST_DEPS})
set_target_properties(check-sanitizer PROPERTIES FOLDER
"Compiler-RT Misc")
endif()
1 change: 0 additions & 1 deletion compiler-rt/test/shadowcallstack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@ endforeach()
add_lit_testsuite(check-shadowcallstack "Running the ShadowCallStack tests"
${SHADOWCALLSTACK_TESTSUITES}
DEPENDS ${SANITIZER_COMMON_LIT_TEST_DEPS})
set_target_properties(check-shadowcallstack PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/tsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,4 @@ if(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME)
${TSAN_DYNAMIC_TESTSUITES}
EXCLUDE_FROM_CHECK_ALL
DEPENDS ${TSAN_DYNAMIC_TEST_DEPS})
set_target_properties(check-tsan-dynamic PROPERTIES FOLDER "Compiler-RT Misc")
endif()
2 changes: 0 additions & 2 deletions compiler-rt/test/ubsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,3 @@ endif()
add_lit_testsuite(check-ubsan "Running UndefinedBehaviorSanitizer tests"
${UBSAN_TESTSUITES}
DEPENDS ${UBSAN_TEST_DEPS})
set_target_properties(check-ubsan PROPERTIES FOLDER "Compiler-RT Misc")

1 change: 0 additions & 1 deletion compiler-rt/test/ubsan_minimal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ endforeach()
add_lit_testsuite(check-ubsan-minimal "Running UndefinedBehaviorSanitizerMinimal tests"
${UBSAN_TESTSUITES}
DEPENDS ${UBSAN_TEST_DEPS})
set_target_properties(check-ubsan-minimal PROPERTIES FOLDER "Compiler-RT Misc")
1 change: 0 additions & 1 deletion compiler-rt/test/xray/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ endif()
add_lit_testsuite(check-xray "Running the XRay tests"
${XRAY_TESTSUITES}
DEPENDS ${XRAY_TEST_DEPS})
set_target_properties(check-xray PROPERTIES FOLDER "Compiler-RT Misc")
16 changes: 15 additions & 1 deletion flang/include/flang/Optimizer/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ struct AliasAnalysis {
/// Source definition of a value.
SourceUnion u;

/// A value definition denoting the place where the corresponding
/// source variable was instantiated by the front-end.
/// Currently, it is the result of [hl]fir.declare of the source,
/// if we can reach it.
/// It helps to identify the scope where the corresponding variable
/// was defined in the original Fortran source, e.g. when MLIR
/// inlining happens an inlined fir.declare of the callee's
/// dummy argument identifies the scope where the source
/// may be treated as a dummy argument.
mlir::Value instantiationPoint;

/// Whether the source was reached following data or box reference
bool isData{false};
};
Expand Down Expand Up @@ -168,7 +179,10 @@ struct AliasAnalysis {
mlir::ModRefResult getModRef(mlir::Operation *op, mlir::Value location);

/// Return the memory source of a value.
Source getSource(mlir::Value);
/// If getInstantiationPoint is true, the search for the source
/// will stop at [hl]fir.declare if it represents a dummy
/// argument declaration (i.e. it has the dummy_scope operand).
Source getSource(mlir::Value, bool getInstantiationPoint = false);
};

inline bool operator==(const AliasAnalysis::Source::SourceOrigin &lhs,
Expand Down
14 changes: 14 additions & 0 deletions flang/include/flang/Optimizer/Analysis/TBAAForest.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@ class TBAAForrest {
}
return getFuncTree(func.getSymNameAttr());
}
// Returns the TBAA tree associated with the scope enclosed
// within the given function. With MLIR inlining, there may
// be multiple scopes within a single function. It is the caller's
// responsibility to provide unique name for the scope.
// If the scope string is empty, returns the TBAA tree for the
// "root" scope of the given function.
inline const TBAATree &getFuncTreeWithScope(mlir::func::FuncOp func,
llvm::StringRef scope) {
mlir::StringAttr name = func.getSymNameAttr();
if (!scope.empty())
name = mlir::StringAttr::get(name.getContext(),
llvm::Twine(name) + " - " + scope);
return getFuncTree(name);
}

private:
const TBAATree &getFuncTree(mlir::StringAttr symName) {
Expand Down
1 change: 0 additions & 1 deletion flang/include/flang/Optimizer/CodeGen/CGPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ def TargetRewritePass : Pass<"target-rewrite", "mlir::ModuleOp"> {
}

def BoxedProcedurePass : Pass<"boxed-procedure", "mlir::ModuleOp"> {
let constructor = "::fir::createBoxedProcedurePass()";
let options = [
Option<"useThunks", "use-thunks",
"bool", /*default=*/"true",
Expand Down
5 changes: 0 additions & 5 deletions flang/include/flang/Optimizer/CodeGen/CodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ std::unique_ptr<mlir::Pass> createLLVMDialectToLLVMPass(
LLVMIRLoweringPrinter printer =
[](llvm::Module &m, llvm::raw_ostream &out) { m.print(out, nullptr); });

/// Convert boxproc values to a lower level representation. The default is to
/// use function pointers and thunks.
std::unique_ptr<mlir::Pass> createBoxedProcedurePass();
std::unique_ptr<mlir::Pass> createBoxedProcedurePass(bool useThunks);

/// Populate the given list with patterns that convert from FIR to LLVM.
void populateFIRToLLVMConversionPatterns(fir::LLVMTypeConverter &converter,
mlir::RewritePatternSet &patterns,
Expand Down
3 changes: 2 additions & 1 deletion flang/include/flang/Optimizer/Dialect/FIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2800,7 +2800,8 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> {
OptionalAttr<UnitAttr>:$constant,
OptionalAttr<UnitAttr>:$target,
OptionalAttr<StrAttr>:$linkName,
OptionalAttr<cuf_DataAttributeAttr>:$data_attr
OptionalAttr<cuf_DataAttributeAttr>:$data_attr,
OptionalAttr<I64Attr>:$alignment
);

let regions = (region AtMostRegion<1>:$region);
Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Evaluate/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,9 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"associated",
{{"pointer", AnyPointer, Rank::anyOrAssumedRank, Optionality::required,
common::Intent::In, {ArgFlag::canBeNull}},
{"target", Addressable, Rank::known, Optionality::optional,
common::Intent::In, {ArgFlag::canBeNull}}},
{"target", Addressable, Rank::anyOrAssumedRank,
Optionality::optional, common::Intent::In,
{ArgFlag::canBeNull}}},
DefaultLogical, Rank::elemental, IntrinsicClass::inquiryFunction},
{"atan", {{"x", SameFloating}}, SameFloating},
{"atan", {{"y", OperandReal}, {"x", OperandReal}}, OperandReal},
Expand Down
7 changes: 6 additions & 1 deletion flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,9 @@ declareCommonBlock(Fortran::lower::AbstractConverter &converter,
getCommonMembersWithInitAliases(common);
mlir::Location loc = converter.genLocation(common.name());
mlir::StringAttr linkage = builder.createCommonLinkage();
const auto *details =
common.detailsIf<Fortran::semantics::CommonBlockDetails>();
assert(details && "Expect CommonBlockDetails on the common symbol");
if (!commonBlockHasInit(cmnBlkMems)) {
// A COMMON block sans initializers is initialized to zero.
// mlir::Vector types must have a strictly positive size, so at least
Expand All @@ -1307,7 +1310,8 @@ declareCommonBlock(Fortran::lower::AbstractConverter &converter,
auto vecTy = mlir::VectorType::get(sz, i8Ty);
mlir::Attribute zero = builder.getIntegerAttr(i8Ty, 0);
auto init = mlir::DenseElementsAttr::get(vecTy, llvm::ArrayRef(zero));
builder.createGlobal(loc, commonTy, commonName, linkage, init);
global = builder.createGlobal(loc, commonTy, commonName, linkage, init);
global.setAlignment(details->alignment());
// No need to add any initial value later.
return std::nullopt;
}
Expand All @@ -1320,6 +1324,7 @@ declareCommonBlock(Fortran::lower::AbstractConverter &converter,
getTypeOfCommonWithInit(converter, cmnBlkMems, commonSize);
// Create the global object, the initial value will be added later.
global = builder.createGlobal(loc, commonTy, commonName);
global.setAlignment(details->alignment());
return std::make_tuple(global, std::move(cmnBlkMems), loc);
}

Expand Down
34 changes: 31 additions & 3 deletions flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ bool AliasAnalysis::Source::isRecordWithPointerComponent() const {
}

AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
// TODO: alias() has to be aware of the function scopes.
// After MLIR inlining, the current implementation may
// not recognize non-aliasing entities.
auto lhsSrc = getSource(lhs);
auto rhsSrc = getSource(rhs);
bool approximateSource = lhsSrc.approximateSource || rhsSrc.approximateSource;
Expand Down Expand Up @@ -232,7 +235,8 @@ getAttrsFromVariable(fir::FortranVariableOpInterface var) {
return attrs;
}

AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
bool getInstantiationPoint) {
auto *defOp = v.getDefiningOp();
SourceKind type{SourceKind::Unknown};
mlir::Type ty;
Expand All @@ -244,6 +248,7 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
bool followingData = !isBoxRef;
mlir::SymbolRefAttr global;
Source::Attributes attributes;
mlir::Value instantiationPoint;
while (defOp && !breakFromLoop) {
ty = defOp->getResultTypes()[0];
llvm::TypeSwitch<Operation *>(defOp)
Expand Down Expand Up @@ -334,6 +339,21 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
breakFromLoop = true;
return;
}
if (getInstantiationPoint) {
// Fetch only the innermost instantiation point.
if (!instantiationPoint)
instantiationPoint = op->getResult(0);

if (op.getDummyScope()) {
// Do not track past DeclareOp that has the dummy_scope
// operand. This DeclareOp is known to represent
// a dummy argument for some runtime instantiation
// of a procedure.
type = SourceKind::Argument;
breakFromLoop = true;
return;
}
}
// TODO: Look for the fortran attributes present on the operation
// Track further through the operand
v = op.getMemref();
Expand Down Expand Up @@ -372,9 +392,17 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
}

if (type == SourceKind::Global) {
return {{global, followingData}, type, ty, attributes, approximateSource};
return {{global, instantiationPoint, followingData},
type,
ty,
attributes,
approximateSource};
}
return {{v, followingData}, type, ty, attributes, approximateSource};
return {{v, instantiationPoint, followingData},
type,
ty,
attributes,
approximateSource};
}

} // namespace fir
9 changes: 4 additions & 5 deletions flang/lib/Optimizer/Builder/FIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,10 @@ mlir::Block *fir::FirOpBuilder::getAllocaBlock() {
.getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>()) {
return ompOutlineableIface.getAllocaBlock();
}
if (getRegion().getParentOfType<mlir::omp::DeclareReductionOp>())
return &getRegion().front();
if (auto accRecipeIface =
getRegion().getParentOfType<mlir::acc::RecipeInterface>()) {
return accRecipeIface.getAllocaBlock(getRegion());

if (auto recipeIface =
getRegion().getParentOfType<mlir::accomp::RecipeInterface>()) {
return recipeIface.getAllocaBlock(getRegion());
}

return getEntryBlock();
Expand Down
11 changes: 1 addition & 10 deletions flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,7 @@ class BoxprocTypeRewriter : public mlir::TypeConverter {
class BoxedProcedurePass
: public fir::impl::BoxedProcedurePassBase<BoxedProcedurePass> {
public:
BoxedProcedurePass() { options = {true}; }
BoxedProcedurePass(bool useThunks) { options = {useThunks}; }
using BoxedProcedurePassBase<BoxedProcedurePass>::BoxedProcedurePassBase;

inline mlir::ModuleOp getModule() { return getOperation(); }

Expand Down Expand Up @@ -397,11 +396,3 @@ class BoxedProcedurePass
BoxedProcedureOptions options;
};
} // namespace

std::unique_ptr<mlir::Pass> fir::createBoxedProcedurePass() {
return std::make_unique<BoxedProcedurePass>();
}

std::unique_ptr<mlir::Pass> fir::createBoxedProcedurePass(bool useThunks) {
return std::make_unique<BoxedProcedurePass>(useThunks);
}
3 changes: 3 additions & 0 deletions flang/lib/Optimizer/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2742,6 +2742,9 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
loc, tyAttr, isConst, linkage, global.getSymName(), initAttr, 0, 0,
false, false, comdat, attrs, dbgExpr);

if (global.getAlignment() && *global.getAlignment() > 0)
g.setAlignment(*global.getAlignment());

auto module = global->getParentOfType<mlir::ModuleOp>();
// Add comdat if necessary
if (fir::getTargetTriple(module).supportsCOMDAT() &&
Expand Down
32 changes: 32 additions & 0 deletions flang/lib/Optimizer/CodeGen/TBAABuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,38 @@ TBAABuilder::TBAABuilder(MLIRContext *context, bool applyTBAA,
bool forceUnifiedTree)
: enableTBAA(applyTBAA && !disableTBAA),
trees(/*separatePerFunction=*/perFunctionTBAATrees && !forceUnifiedTree) {
// TODO: the TBAA tags created here are rooted in the root scope
// of the enclosing function. This does not work best with MLIR inlining.
// A better approach is to root them according to the scopes they belong to
// and that were used by AddAliasTagsPass to create TBAA tags before
// the CodeGen. For example:
// subroutine caller(a, b, ptr)
// real, target :: a(:), b(:)
// integer, pointer :: ptr(:)
// call callee(a, b, ptr)
// end
// subroutine callee(a, b, ptr)
// real :: a(:), b(:)
// integer, pointer :: ptr(:)
// do i=...
// a(ptr(i)) = b(ptr(i))
// end do
// end
//
// When callee is inlined, the dummy arguments 'a' and 'b' will
// be rooted in TBAA tree corresponding to the `call callee` call site,
// saying that the references to 'a' and 'b' cannot alias each other.
// These tags will be created by AddAliasTagsPass, but it will not be able
// to create any tags for 'ptr' references.
// During the CodeGen, we create 'any data access' tags for the
// 'ptr' acceses. If they are rooted within the root scope of `caller`,
// they end up in a different TBAA tree with the 'a' and 'b' access
// tags, so 'ptr', 'a' and 'b' references MayAlias. Moreover,
// the box access of 'ptr' will also be in a different TBAA tree
// with 'a' and 'b' tags, meaning they can also alias.
// This will prevent LLVM vectorization even with memory conflict checks.
// It seems that we'd better move all TBAA tags assignment to
// AddAliasTagsPass, which can at least rely on the dummy arguments scopes.
if (!enableTBAA)
return;
}
Expand Down
9 changes: 8 additions & 1 deletion flang/lib/Optimizer/Dialect/FIROps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3910,8 +3910,15 @@ std::optional<std::int64_t> fir::getIntIfConstant(mlir::Value value) {

bool fir::isDummyArgument(mlir::Value v) {
auto blockArg{mlir::dyn_cast<mlir::BlockArgument>(v)};
if (!blockArg)
if (!blockArg) {
auto defOp = v.getDefiningOp();
if (defOp) {
if (auto declareOp = mlir::dyn_cast<fir::DeclareOp>(defOp))
if (declareOp.getDummyScope())
return true;
}
return false;
}

auto *owner{blockArg.getOwner()};
return owner->isEntryBlock() &&
Expand Down
101 changes: 94 additions & 7 deletions flang/lib/Optimizer/Transforms/AddAliasTags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/FirAliasTagOpInterface.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "mlir/IR/Dominance.h"
#include "mlir/Pass/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
Expand Down Expand Up @@ -54,24 +56,85 @@ namespace {
/// Shared state per-module
class PassState {
public:
PassState(mlir::DominanceInfo &domInfo) : domInfo(domInfo) {}
/// memoised call to fir::AliasAnalysis::getSource
inline const fir::AliasAnalysis::Source &getSource(mlir::Value value) {
if (!analysisCache.contains(value))
analysisCache.insert({value, analysis.getSource(value)});
analysisCache.insert(
{value, analysis.getSource(value, /*getInstantiationPoint=*/true)});
return analysisCache[value];
}

/// get the per-function TBAATree for this function
inline const fir::TBAATree &getFuncTree(mlir::func::FuncOp func) {
return forrest[func];
}
inline const fir::TBAATree &getFuncTreeWithScope(mlir::func::FuncOp func,
fir::DummyScopeOp scope) {
auto &scopeMap = scopeNames.at(func);
return forrest.getFuncTreeWithScope(func, scopeMap.lookup(scope));
}

void processFunctionScopes(mlir::func::FuncOp func);
fir::DummyScopeOp getDeclarationScope(fir::DeclareOp declareOp);

private:
mlir::DominanceInfo &domInfo;
fir::AliasAnalysis analysis;
llvm::DenseMap<mlir::Value, fir::AliasAnalysis::Source> analysisCache;
fir::TBAAForrest forrest;
// Unique names for fir.dummy_scope operations within
// the given function.
llvm::DenseMap<mlir::func::FuncOp,
llvm::DenseMap<fir::DummyScopeOp, std::string>>
scopeNames;
// A map providing a vector of fir.dummy_scope operations
// for the given function. The vectors are sorted according
// to the dominance information.
llvm::DenseMap<mlir::func::FuncOp, llvm::SmallVector<fir::DummyScopeOp, 16>>
sortedScopeOperations;
};

// Process fir.dummy_scope operations in the given func:
// sort them according to the dominance information, and
// associate a unique (within the current function) scope name
// with each of them.
void PassState::processFunctionScopes(mlir::func::FuncOp func) {
if (scopeNames.contains(func))
return;

auto &scopeMap = scopeNames.getOrInsertDefault(func);
auto &scopeOps = sortedScopeOperations.getOrInsertDefault(func);
func.walk([&](fir::DummyScopeOp op) { scopeOps.push_back(op); });
llvm::stable_sort(scopeOps, [&](const fir::DummyScopeOp &op1,
const fir::DummyScopeOp &op2) {
return domInfo.properlyDominates(&*op1, &*op2);
});
unsigned scopeId = 0;
for (auto scope : scopeOps) {
if (scopeId != 0) {
std::string name = (llvm::Twine("Scope ") + llvm::Twine(scopeId)).str();
LLVM_DEBUG(llvm::dbgs() << "Creating scope '" << name << "':\n"
<< scope << "\n");
scopeMap.insert({scope, std::move(name)});
}
++scopeId;
}
}

// For the given fir.declare returns the dominating fir.dummy_scope
// operation.
fir::DummyScopeOp PassState::getDeclarationScope(fir::DeclareOp declareOp) {
auto func = declareOp->getParentOfType<mlir::func::FuncOp>();
assert(func && "fir.declare does not have parent func.func");
auto &scopeOps = sortedScopeOperations.at(func);
for (auto II = scopeOps.rbegin(), IE = scopeOps.rend(); II != IE; ++II) {
if (domInfo.dominates(&**II, &*declareOp))
return *II;
}
return nullptr;
}

class AddAliasTagsPass : public fir::impl::AddAliasTagsBase<AddAliasTagsPass> {
public:
void runOnOperation() override;
Expand All @@ -85,6 +148,9 @@ class AddAliasTagsPass : public fir::impl::AddAliasTagsBase<AddAliasTagsPass> {
} // namespace

static fir::DeclareOp getDeclareOp(mlir::Value arg) {
if (auto declare =
mlir::dyn_cast_or_null<fir::DeclareOp>(arg.getDefiningOp()))
return declare;
for (mlir::Operation *use : arg.getUsers())
if (fir::DeclareOp declare = mlir::dyn_cast<fir::DeclareOp>(use))
return declare;
Expand All @@ -94,7 +160,7 @@ static fir::DeclareOp getDeclareOp(mlir::Value arg) {
/// Get the name of a function argument using the "fir.bindc_name" attribute,
/// or ""
static std::string getFuncArgName(mlir::Value arg) {
// first try getting the name from the hlfir.declare
// first try getting the name from the fir.declare
if (fir::DeclareOp declare = getDeclareOp(arg))
return declare.getUniqName().str();

Expand Down Expand Up @@ -139,6 +205,23 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
return;
}

// Process the scopes, if not processed yet.
state.processFunctionScopes(func);

fir::DummyScopeOp scopeOp;
if (auto declVal = source.origin.instantiationPoint) {
// If the source is a dummy argument within some fir.dummy_scope,
// then find the corresponding innermost scope to be used for finding
// the right TBAA tree.
auto declareOp =
mlir::dyn_cast_or_null<fir::DeclareOp>(declVal.getDefiningOp());
assert(declareOp && "Instantiation point must be fir.declare");
if (auto dummyScope = declareOp.getDummyScope())
scopeOp = mlir::cast<fir::DummyScopeOp>(dummyScope.getDefiningOp());
if (!scopeOp)
scopeOp = state.getDeclarationScope(declareOp);
}

mlir::LLVM::TBAATagAttr tag;
// TBAA for dummy arguments
if (enableDummyArgs &&
Expand All @@ -147,7 +230,8 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
<< "Found reference to dummy argument at " << *op << "\n");
std::string name = getFuncArgName(source.origin.u.get<mlir::Value>());
if (!name.empty())
tag = state.getFuncTree(func).dummyArgDataTree.getTag(name);
tag = state.getFuncTreeWithScope(func, scopeOp)
.dummyArgDataTree.getTag(name);
else
LLVM_DEBUG(llvm::dbgs().indent(2)
<< "WARN: couldn't find a name for dummy argument " << *op
Expand All @@ -161,7 +245,7 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
const char *name = glbl.getRootReference().data();
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to global " << name
<< " at " << *op << "\n");
tag = state.getFuncTree(func).globalDataTree.getTag(name);
tag = state.getFuncTreeWithScope(func, scopeOp).globalDataTree.getTag(name);

// TBAA for SourceKind::Direct
} else if (enableDirect &&
Expand All @@ -172,7 +256,8 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
const char *name = glbl.getRootReference().data();
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to direct " << name
<< " at " << *op << "\n");
tag = state.getFuncTree(func).directDataTree.getTag(name);
tag =
state.getFuncTreeWithScope(func, scopeOp).directDataTree.getTag(name);
} else {
// SourceKind::Direct is likely to be extended to cases which are not a
// SymbolRefAttr in the future
Expand All @@ -193,7 +278,8 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
if (name) {
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to allocation "
<< name << " at " << *op << "\n");
tag = state.getFuncTree(func).allocatedDataTree.getTag(*name);
tag = state.getFuncTreeWithScope(func, scopeOp)
.allocatedDataTree.getTag(*name);
} else {
LLVM_DEBUG(llvm::dbgs().indent(2)
<< "WARN: couldn't find a name for allocation " << *op
Expand All @@ -219,7 +305,8 @@ void AddAliasTagsPass::runOnOperation() {
// Instead this pass stores state per mlir::ModuleOp (which is what MLIR
// thinks the pass operates on), then the real work of the pass is done in
// runOnAliasInterface
PassState state;
auto &domInfo = getAnalysis<mlir::DominanceInfo>();
PassState state(domInfo);

mlir::ModuleOp mod = getOperation();
mod.walk(
Expand Down
9 changes: 7 additions & 2 deletions flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,13 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,

// FIXME: There may be cases where an argument is processed a bit before
// DeclareOp is generated. In that case, DeclareOp may point to an
// intermediate op and not to BlockArgument. We need to find those cases and
// walk the chain to get to the actual argument.
// intermediate op and not to BlockArgument.
// Moreover, with MLIR inlining we cannot use the BlockArgument
// position to identify the original number of the dummy argument.
// If we want to keep running AddDebugInfoPass late, the dummy argument
// position in the argument list has to be expressed in FIR (e.g. as a
// constant attribute of [hl]fir.declare/fircg.ext_declare operation that has
// a dummy_scope operand).
unsigned argNo = 0;
if (fir::isDummyArgument(declOp.getMemref())) {
auto arg = llvm::cast<mlir::BlockArgument>(declOp.getMemref());
Expand Down
13 changes: 12 additions & 1 deletion flang/lib/Semantics/check-call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
if ((arg.isPercentRef() || arg.isPercentVal()) &&
dummy.IsPassedByDescriptor(procedure.IsBindC())) {
messages.Say(
"%VAL or %REF are not allowed for %s that must be passed by means of a descriptor"_err_en_US,
"%%VAL or %%REF are not allowed for %s that must be passed by means of a descriptor"_err_en_US,
dummyName);
}
if (arg.isPercentVal() &&
Expand Down Expand Up @@ -1499,6 +1499,17 @@ static void CheckAssociated(evaluate::ActualArguments &arguments,
"POINTER= argument '%s' is an object pointer but the TARGET= argument '%s' is not a variable"_err_en_US,
pointerExpr->AsFortran(), targetExpr->AsFortran());
}
if (!IsAssumedRank(*pointerExpr)) {
if (IsAssumedRank(*targetExpr)) {
messages.Say(
"TARGET= argument '%s' may not be assumed-rank when POINTER= argument is not"_err_en_US,
pointerExpr->AsFortran());
} else if (pointerExpr->Rank() != targetExpr->Rank()) {
messages.Say(
"POINTER= argument and TARGET= argument have incompatible ranks %d and %d"_err_en_US,
pointerExpr->Rank(), targetExpr->Rank());
}
}
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions flang/test/Lower/OpenMP/declare-target-data.f90
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,25 @@ module test_0
end module test_0

PROGRAM commons
!CHECK-DAG: fir.global @numbers_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
!CHECK-DAG: fir.global @numbers_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
REAL :: one = 1
REAL :: two = 2
COMMON /numbers/ one, two
!$omp declare target(/numbers/)

!CHECK-DAG: fir.global @numbers_link_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : tuple<f32, f32> {
!CHECK-DAG: fir.global @numbers_link_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : tuple<f32, f32> {
REAL :: one_link = 1
REAL :: two_link = 2
COMMON /numbers_link/ one_link, two_link
!$omp declare target link(/numbers_link/)

!CHECK-DAG: fir.global @numbers_to_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
!CHECK-DAG: fir.global @numbers_to_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
REAL :: one_to = 1
REAL :: two_to = 2
COMMON /numbers_to/ one_to, two_to
!$omp declare target to(/numbers_to/)

!CHECK-DAG: fir.global @numbers_enter_ {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : tuple<f32, f32> {
!CHECK-DAG: fir.global @numbers_enter_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : tuple<f32, f32> {
REAL :: one_enter = 1
REAL :: two_enter = 2
COMMON /numbers_enter/ one_enter, two_enter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
! Test delayed privatization for allocatables: `firstprivate`.

! RUN: split-file %s %t

! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
! RUN: -o - %s 2>&1 | FileCheck %s
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %s 2>&1 |\
! RUN: -o - %t/test_ir.f90 2>&1 | FileCheck %s
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %t/test_ir.f90 2>&1 |\
! RUN: FileCheck %s

!--- test_ir.f90
subroutine delayed_privatization_allocatable
implicit none
integer, allocatable :: var1
Expand Down Expand Up @@ -34,3 +37,26 @@ subroutine delayed_privatization_allocatable
! CHECK-NEXT: %[[ORIG_BASE_LD:.*]] = fir.load %[[ORIG_BASE_ADDR]]
! CHECK-NEXT: hlfir.assign %[[ORIG_BASE_LD]] to %[[PRIV_BASE_BOX]] temporary_lhs
! CHECK-NEXT: }

! RUN: %flang -c -emit-llvm -fopenmp -mmlir --openmp-enable-delayed-privatization \
! RUN: -o - %t/test_compilation_to_obj.f90 | \
! RUN: llvm-dis 2>&1 |\
! RUN: FileCheck %s -check-prefix=LLVM

!--- test_compilation_to_obj.f90

program compilation_to_obj
real, allocatable :: t(:)

!$omp parallel firstprivate(t)
t(1) = 3.14
!$omp end parallel

end program compilation_to_obj

! LLVM: @[[GLOB_VAR:[^[:space:]]+]]t = internal global

! LLVM: define internal void @_QQmain..omp_par
! LLVM: %[[LOCAL_VAR:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8
! LLVM-NEXT: %[[GLOB_VAL:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr @[[GLOB_VAR]]t, align 8
! LLVM-NEXT: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[GLOB_VAL]], ptr %[[LOCAL_VAR]], align 8
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/lastprivate-commonblock.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s

!CHECK: fir.global common @[[CB_C:.*]](dense<0> : vector<8xi8>) : !fir.array<8xi8>
!CHECK: fir.global common @[[CB_C:.*]](dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8>
!CHECK-LABEL: func.func @_QPlastprivate_common
!CHECK: %[[CB_C_REF:.*]] = fir.address_of(@[[CB_C]]) : !fir.ref<!fir.array<8xi8>>
!CHECK: %[[CB_C_REF_CVT:.*]] = fir.convert %[[CB_C_REF]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/threadprivate-commonblock-use.f90
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s

!CHECK: fir.global common @cmn_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
!CHECK: fir.global common @cmn_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
module m0
common /cmn/ k1
!$omp threadprivate(/cmn/)
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/threadprivate-commonblock.f90
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module test

!$omp threadprivate(/blk/)

!CHECK: fir.global common @blk_(dense<0> : vector<103xi8>) : !fir.array<103xi8>
!CHECK: fir.global common @blk_(dense<0> : vector<103xi8>) {alignment = 8 : i64} : !fir.array<103xi8>

contains
subroutine sub()
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/threadprivate-use-association.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s

!CHECK-DAG: fir.global common @blk_(dense<0> : vector<24xi8>) : !fir.array<24xi8>
!CHECK-DAG: fir.global common @blk_(dense<0> : vector<24xi8>) {alignment = 4 : i64} : !fir.array<24xi8>
!CHECK-DAG: fir.global @_QMtestEy : f32 {

module test
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/common-block-2.f90
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
! - A blank common that is initialized
! - A common block that is initialized outside of a BLOCK DATA.

! CHECK-LABEL: fir.global @__BLNK__ : tuple<i32, !fir.array<8xi8>> {
! CHECK-LABEL: fir.global @__BLNK__ {alignment = 4 : i64} : tuple<i32, !fir.array<8xi8>> {
! CHECK: %[[undef:.*]] = fir.zero_bits tuple<i32, !fir.array<8xi8>>
! CHECK: %[[init:.*]] = fir.insert_value %[[undef]], %c42{{.*}}, [0 : index] : (tuple<i32, !fir.array<8xi8>>, i32) -> tuple<i32, !fir.array<8xi8>>
! CHECK: fir.has_value %[[init]] : tuple<i32, !fir.array<8xi8>>

! CHECK-LABEL: fir.global @a_ : tuple<i32, !fir.array<8xi8>> {
! CHECK-LABEL: fir.global @a_ {alignment = 4 : i64} : tuple<i32, !fir.array<8xi8>> {
! CHECK: %[[undef:.*]] = fir.zero_bits tuple<i32, !fir.array<8xi8>>
! CHECK: %[[init:.*]] = fir.insert_value %[[undef]], %c42{{.*}}, [0 : index] : (tuple<i32, !fir.array<8xi8>>, i32) -> tuple<i32, !fir.array<8xi8>>
! CHECK: fir.has_value %[[init]] : tuple<i32, !fir.array<8xi8>>
Expand Down
7 changes: 7 additions & 0 deletions flang/test/Lower/common-block.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
! RUN: %flang -emit-llvm -S -mmlir -disable-external-name-interop %s -o - | FileCheck %s

! CHECK: @__BLNK__ = common global [8 x i8] zeroinitializer
! CHECK: @co1_ = common global [16 x i8] zeroinitializer, align 16
! CHECK: @rien_ = common global [1 x i8] zeroinitializer
! CHECK: @with_empty_equiv_ = common global [8 x i8] zeroinitializer
! CHECK: @x_ = global { float, float } { float 1.0{{.*}}, float 2.0{{.*}} }
Expand Down Expand Up @@ -72,3 +73,9 @@ subroutine s6
common /with_empty_equiv/ x, r1, y
equivalence(r1, r2)
end subroutine s6

subroutine s7()
real(16) r16
common /co1/ r16
end subroutine

6 changes: 3 additions & 3 deletions flang/test/Lower/module_definition.f90
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ module modCommonNoInit1
real :: x_named1
common /named1/ x_named1
end module
! CHECK-LABEL: fir.global common @__BLNK__(dense<0> : vector<4xi8>) : !fir.array<4xi8>
! CHECK-LABEL: fir.global common @named1_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
! CHECK-LABEL: fir.global common @__BLNK__(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
! CHECK-LABEL: fir.global common @named1_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>

! Module defines variable in common block with initialization
module modCommonInit1
integer :: i_named2 = 42
common /named2/ i_named2
end module
! CHECK-LABEL: fir.global @named2_ : tuple<i32> {
! CHECK-LABEL: fir.global @named2_ {alignment = 4 : i64} : tuple<i32> {
! CHECK: %[[init:.*]] = fir.insert_value %{{.*}}, %c42{{.*}}, [0 : index] : (tuple<i32>, i32) -> tuple<i32>
! CHECK: fir.has_value %[[init]] : tuple<i32>

Expand Down
6 changes: 3 additions & 3 deletions flang/test/Lower/module_use.f90
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
! The modules are defined in module_definition.f90
! The first runs ensures the module file is generated.

! CHECK: fir.global common @__BLNK__(dense<0> : vector<4xi8>) : !fir.array<4xi8>
! CHECK-NEXT: fir.global common @named1_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
! CHECK-NEXT: fir.global common @named2_(dense<0> : vector<4xi8>) : !fir.array<4xi8>
! CHECK: fir.global common @__BLNK__(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
! CHECK-NEXT: fir.global common @named1_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>
! CHECK-NEXT: fir.global common @named2_(dense<0> : vector<4xi8>) {alignment = 4 : i64} : !fir.array<4xi8>

! CHECK-LABEL: func @_QPm1use()
real function m1use()
Expand Down
8 changes: 4 additions & 4 deletions flang/test/Lower/pointer-initial-target-2.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
real, save, target :: b
common /a/ p
data p /b/
! CHECK-LABEL: fir.global @a_ : tuple<!fir.box<!fir.ptr<f32>>>
! CHECK-LABEL: fir.global @a_ {alignment = 8 : i64} : tuple<!fir.box<!fir.ptr<f32>>>
! CHECK: %[[undef:.*]] = fir.zero_bits tuple<!fir.box<!fir.ptr<f32>>>
! CHECK: %[[b:.*]] = fir.address_of(@_QEb) : !fir.ref<f32>
! CHECK: %[[box:.*]] = fir.embox %[[b]] : (!fir.ref<f32>) -> !fir.box<f32>
Expand All @@ -29,9 +29,9 @@ block data tied
real, pointer :: p2 => x1
common /c1/ x1, p1
common /c2/ x2, p2
! CHECK-LABEL: fir.global @c1_ : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
! CHECK-LABEL: fir.global @c1_ {alignment = 8 : i64} : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
! CHECK: fir.address_of(@c2_) : !fir.ref<tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>>
! CHECK-LABEL: fir.global @c2_ : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
! CHECK-LABEL: fir.global @c2_ {alignment = 8 : i64} : tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>
! CHECK: fir.address_of(@c1_) : !fir.ref<tuple<f32, !fir.array<4xi8>, !fir.box<!fir.ptr<f32>>>>
end block data

Expand All @@ -40,7 +40,7 @@ block data bdsnake
integer, target :: b = 42
integer, pointer :: p => b
common /snake/ p, b
! CHECK-LABEL: fir.global @snake_ : tuple<!fir.box<!fir.ptr<i32>>, i32>
! CHECK-LABEL: fir.global @snake_ {alignment = 8 : i64} : tuple<!fir.box<!fir.ptr<i32>>, i32>
! CHECK: %[[tuple0:.*]] = fir.zero_bits tuple<!fir.box<!fir.ptr<i32>>, i32>
! CHECK: %[[snakeAddr:.*]] = fir.address_of(@snake_) : !fir.ref<tuple<!fir.box<!fir.ptr<i32>>, i32>>
! CHECK: %[[byteView:.*]] = fir.convert %[[snakeAddr:.*]] : (!fir.ref<tuple<!fir.box<!fir.ptr<i32>>, i32>>) -> !fir.ref<!fir.array<?xi8>>
Expand Down
15 changes: 9 additions & 6 deletions flang/test/Semantics/associated.f90
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,21 @@ subroutine test(assumedRank)
integer, pointer :: intPointerArr(:)
procedure(objPtrFunc), pointer :: objPtrFuncPointer

!ERROR: Assumed-rank array cannot be forwarded to 'target=' argument
lvar = associated(assumedRank, assumedRank)
lvar = associated(assumedRank, assumedRank) ! ok
!ERROR: TARGET= argument 'realscalarptr' may not be assumed-rank when POINTER= argument is not
lvar = associated(realScalarPtr, assumedRank)
!ERROR: TARGET= argument 'realvecptr' may not be assumed-rank when POINTER= argument is not
lvar = associated(realVecPtr, assumedRank)
lvar = associated(assumedRank, targetRealVar) ! ok
lvar = associated(assumedRank, targetRealMat) ! ok
lvar = associated(realScalarPtr, targetRealVar) ! ok
!ERROR: 'target=' argument has unacceptable rank 0
!ERROR: POINTER= argument and TARGET= argument have incompatible ranks 1 and 0
lvar = associated(realVecPtr, targetRealVar)
!ERROR: 'target=' argument has unacceptable rank 0
!ERROR: POINTER= argument and TARGET= argument have incompatible ranks 2 and 0
lvar = associated(realMatPtr, targetRealVar)
!ERROR: 'target=' argument has unacceptable rank 2
!ERROR: POINTER= argument and TARGET= argument have incompatible ranks 0 and 2
lvar = associated(realScalarPtr, targetRealMat)
!ERROR: 'target=' argument has unacceptable rank 2
!ERROR: POINTER= argument and TARGET= argument have incompatible ranks 1 and 2
lvar = associated(realVecPtr, targetRealMat)
lvar = associated(realMatPtr, targetRealMat) ! ok
!ERROR: missing mandatory 'pointer=' argument
Expand Down
238 changes: 238 additions & 0 deletions flang/test/Transforms/tbaa-with-dummy-scope.fir
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
// RUN: fir-opt --fir-add-alias-tags --split-input-file %s | FileCheck %s

// subroutine test(x, y)
// real, target :: x, y
// x = y ! the load/store do not have TBAA due to TARGET
// call inner(x, y) ! the inlined load/store go to Scope 1
// call inner(x, y) ! the inlined load/store go to Scope 2
// contains
// subroutine inner(x, y)
// real :: x, y
// x = y
// end subroutine inner
// end subroutine test

// CHECK: #[[$ATTR_0:.+]] = #llvm.tbaa_root<id = "Flang function root test1 - Scope 1">
// CHECK: #[[$ATTR_1:.+]] = #llvm.tbaa_root<id = "Flang function root test1 - Scope 2">
// CHECK: #[[$ATTR_2:.+]] = #llvm.tbaa_type_desc<id = "any access", members = {<#tbaa_root, 0>}>
// CHECK: #[[$ATTR_3:.+]] = #llvm.tbaa_type_desc<id = "any access", members = {<#tbaa_root1, 0>}>
// CHECK: #[[$ATTR_4:.+]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#tbaa_type_desc, 0>}>
// CHECK: #[[$ATTR_5:.+]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#tbaa_type_desc1, 0>}>
// CHECK: #[[$ATTR_6:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data", members = {<#tbaa_type_desc2, 0>}>
// CHECK: #[[$ATTR_7:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data", members = {<#tbaa_type_desc3, 0>}>
// CHECK: #[[$ATTR_8:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data/_QFtestFinnerEy", members = {<#tbaa_type_desc4, 0>}>
// CHECK: #[[$ATTR_9:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data/_QFtestFinnerEx", members = {<#tbaa_type_desc4, 0>}>
// CHECK: #[[$ATTR_10:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data/_QFtestFinnerEy", members = {<#tbaa_type_desc5, 0>}>
// CHECK: #[[$ATTR_11:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data/_QFtestFinnerEx", members = {<#tbaa_type_desc5, 0>}>
// CHECK: #[[$ATTR_12:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc6, access_type = #tbaa_type_desc6, offset = 0>
// CHECK: #[[$ATTR_13:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc7, access_type = #tbaa_type_desc7, offset = 0>
// CHECK: #[[$ATTR_14:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc8, access_type = #tbaa_type_desc8, offset = 0>
// CHECK: #[[$ATTR_15:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc9, access_type = #tbaa_type_desc9, offset = 0>
// CHECK: func.func @test1(
// CHECK: %[[VAL_5:.*]] = fir.load %{{.*}} : !fir.ref<f32>
// CHECK: fir.store %{{.*}} : !fir.ref<f32>
// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.load %{{.*}} {tbaa = [#[[$ATTR_12]]]} : !fir.ref<f32>
// CHECK: fir.store %{{.*}} {tbaa = [#[[$ATTR_13]]]} : !fir.ref<f32>
// CHECK: %[[VAL_10:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} {tbaa = [#[[$ATTR_14]]]} : !fir.ref<f32>
// CHECK: fir.store %{{.*}} {tbaa = [#[[$ATTR_15]]]} : !fir.ref<f32>
func.func @test1(%arg0: !fir.ref<f32> {fir.bindc_name = "x", fir.target}, %arg1: !fir.ref<f32> {fir.bindc_name = "y", fir.target}) {
%scope_out = fir.dummy_scope : !fir.dscope
%0 = fir.declare %arg0 dummy_scope %scope_out {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEx"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%1 = fir.declare %arg1 dummy_scope %scope_out {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEy"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%2 = fir.load %1 : !fir.ref<f32>
fir.store %2 to %0 : !fir.ref<f32>
%scope_in1 = fir.dummy_scope : !fir.dscope
%3 = fir.declare %0 dummy_scope %scope_in1 {uniq_name = "_QFtestFinnerEx"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%4 = fir.declare %1 dummy_scope %scope_in1 {uniq_name = "_QFtestFinnerEy"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%5 = fir.load %4 : !fir.ref<f32>
fir.store %5 to %3 : !fir.ref<f32>
%scope_in2 = fir.dummy_scope : !fir.dscope
%6 = fir.declare %0 dummy_scope %scope_in2 {uniq_name = "_QFtestFinnerEx"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%7 = fir.declare %1 dummy_scope %scope_in2 {uniq_name = "_QFtestFinnerEy"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%8 = fir.load %7 : !fir.ref<f32>
fir.store %8 to %6 : !fir.ref<f32>
return
}

// -----

// Check that without proper fir.dummy_scope placement
// we just put everything into the root scope.

// CHECK: #[[$ATTR_16:.+]] = #llvm.tbaa_root<id = "Flang function root test2">
// CHECK: #[[$ATTR_17:.+]] = #llvm.tbaa_type_desc<id = "any access", members = {<#tbaa_root, 0>}>
// CHECK: #[[$ATTR_18:.+]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#tbaa_type_desc, 0>}>
// CHECK: #[[$ATTR_19:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data", members = {<#tbaa_type_desc1, 0>}>
// CHECK: #[[$ATTR_20:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data/_QFtestEy", members = {<#tbaa_type_desc2, 0>}>
// CHECK: #[[$ATTR_21:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data/_QFtestEx", members = {<#tbaa_type_desc2, 0>}>
// CHECK: #[[$ATTR_22:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc3, access_type = #tbaa_type_desc3, offset = 0>
// CHECK: #[[$ATTR_23:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc4, access_type = #tbaa_type_desc4, offset = 0>
// CHECK: func.func @test2(
// CHECK: %[[VAL_4:.*]] = fir.load %{{.*}} {tbaa = [#[[$ATTR_22]]]} : !fir.ref<f32>
// CHECK: fir.store %{{.*}} {tbaa = [#[[$ATTR_23]]]} : !fir.ref<f32>
// CHECK: %[[VAL_5:.*]] = fir.declare
// CHECK: %[[VAL_6:.*]] = fir.declare
// CHECK: %[[VAL_7:.*]] = fir.load %{{.*}} {tbaa = [#[[$ATTR_22]]]} : !fir.ref<f32>
// CHECK: fir.store %{{.*}} {tbaa = [#[[$ATTR_23]]]} : !fir.ref<f32>
func.func @test2(%arg0: !fir.ref<f32> {fir.bindc_name = "x"}, %arg1: !fir.ref<f32> {fir.bindc_name = "y"}) {
%0 = fir.declare %arg0 {uniq_name = "_QFtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
%1 = fir.declare %arg1 {uniq_name = "_QFtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
%2 = fir.load %1 : !fir.ref<f32>
fir.store %2 to %0 : !fir.ref<f32>
%3 = fir.declare %0 {uniq_name = "_QFtestFinnerEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
%4 = fir.declare %1 {uniq_name = "_QFtestFinnerEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
%5 = fir.load %4 : !fir.ref<f32>
fir.store %5 to %3 : !fir.ref<f32>
return
}

// -----

// module test
// real :: x, y
// contains
// subroutine caller
// x = y ! the load/store go to the root scope
// call callee
// end subroutine caller
// subroutine callee
// x = y ! the load/store go to the root scope
// ! Since there are no dummy arguments in callee,
// ! it is better to put the load/store into the
// ! enclosing root scope, so that they can be
// ! disambiguated using TBAA with the loads/stores
// ! in the enclosing scope.
// end subroutine callee
// end module test

// CHECK: #[[$ATTR_24:.+]] = #llvm.tbaa_root<id = "Flang function root _QMtestPcaller">
// CHECK: #[[$ATTR_25:.+]] = #llvm.tbaa_type_desc<id = "any access", members = {<#tbaa_root, 0>}>
// CHECK: #[[$ATTR_26:.+]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#tbaa_type_desc, 0>}>
// CHECK: #[[$ATTR_27:.+]] = #llvm.tbaa_type_desc<id = "global data", members = {<#tbaa_type_desc1, 0>}>
// CHECK: #[[$ATTR_28:.+]] = #llvm.tbaa_type_desc<id = "global data/_QMtestEy", members = {<#tbaa_type_desc2, 0>}>
// CHECK: #[[$ATTR_29:.+]] = #llvm.tbaa_type_desc<id = "global data/_QMtestEx", members = {<#tbaa_type_desc2, 0>}>
// CHECK: #[[$ATTR_30:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc3, access_type = #tbaa_type_desc3, offset = 0>
// CHECK: #[[$ATTR_31:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc4, access_type = #tbaa_type_desc4, offset = 0>
// CHECK: func.func @_QMtestPcaller() {
// CHECK: %[[VAL_0:.*]] = fir.address_of(@_QMtestEx) : !fir.ref<f32>
// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_2:.*]] = fir.address_of(@_QMtestEy) : !fir.ref<f32>
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_2]] {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] {tbaa = [#[[$ATTR_30]]]} : !fir.ref<f32>
// CHECK: fir.store %[[VAL_4]] to %[[VAL_1]] {tbaa = [#[[$ATTR_31]]]} : !fir.ref<f32>
// CHECK: %[[VAL_5:.*]] = fir.address_of(@_QMtestEx) : !fir.ref<f32>
// CHECK: %[[VAL_6:.*]] = fir.declare %[[VAL_5]] {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_7:.*]] = fir.address_of(@_QMtestEy) : !fir.ref<f32>
// CHECK: %[[VAL_8:.*]] = fir.declare %[[VAL_7]] {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]] {tbaa = [#[[$ATTR_30]]]} : !fir.ref<f32>
// CHECK: fir.store %[[VAL_9]] to %[[VAL_6]] {tbaa = [#[[$ATTR_31]]]} : !fir.ref<f32>
func.func @_QMtestPcaller() {
%0 = fir.address_of(@_QMtestEx) : !fir.ref<f32>
%1 = fir.declare %0 {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
%2 = fir.address_of(@_QMtestEy) : !fir.ref<f32>
%3 = fir.declare %2 {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
%4 = fir.load %3 : !fir.ref<f32>
fir.store %4 to %1 : !fir.ref<f32>
%5 = fir.address_of(@_QMtestEx) : !fir.ref<f32>
%6 = fir.declare %5 {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
%7 = fir.address_of(@_QMtestEy) : !fir.ref<f32>
%8 = fir.declare %7 {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
%9 = fir.load %8 : !fir.ref<f32>
fir.store %9 to %6 : !fir.ref<f32>
return
}
fir.global @_QMtestEx : f32 {
%0 = fir.zero_bits f32
fir.has_value %0 : f32
}
fir.global @_QMtestEy : f32 {
%0 = fir.zero_bits f32
fir.has_value %0 : f32
}

// -----

// module test
// real :: x, y
// contains
// subroutine caller(z)
// real :: z
// x = y ! the load/store go to the root scope
// call callee(z)
// end subroutine caller
// subroutine callee(z)
// x = y ! the load/store go to Scope 1
// y = z ! the load/store go to Scope 1
// end subroutine callee
// end module test

// CHECK: #[[$ATTR_32:.+]] = #llvm.tbaa_root<id = "Flang function root _QMtestPcaller">
// CHECK: #[[$ATTR_33:.+]] = #llvm.tbaa_root<id = "Flang function root _QMtestPcaller - Scope 1">
// CHECK: #[[$ATTR_34:.+]] = #llvm.tbaa_type_desc<id = "any access", members = {<#tbaa_root, 0>}>
// CHECK: #[[$ATTR_35:.+]] = #llvm.tbaa_type_desc<id = "any access", members = {<#tbaa_root1, 0>}>
// CHECK: #[[$ATTR_36:.+]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#tbaa_type_desc, 0>}>
// CHECK: #[[$ATTR_37:.+]] = #llvm.tbaa_type_desc<id = "any data access", members = {<#tbaa_type_desc1, 0>}>
// CHECK: #[[$ATTR_38:.+]] = #llvm.tbaa_type_desc<id = "global data", members = {<#tbaa_type_desc2, 0>}>
// CHECK: #[[$ATTR_39:.+]] = #llvm.tbaa_type_desc<id = "global data", members = {<#tbaa_type_desc3, 0>}>
// CHECK: #[[$ATTR_40:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data", members = {<#tbaa_type_desc3, 0>}>
// CHECK: #[[$ATTR_41:.+]] = #llvm.tbaa_type_desc<id = "global data/_QMtestEy", members = {<#tbaa_type_desc4, 0>}>
// CHECK: #[[$ATTR_42:.+]] = #llvm.tbaa_type_desc<id = "global data/_QMtestEx", members = {<#tbaa_type_desc4, 0>}>
// CHECK: #[[$ATTR_43:.+]] = #llvm.tbaa_type_desc<id = "global data/_QMtestEy", members = {<#tbaa_type_desc5, 0>}>
// CHECK: #[[$ATTR_44:.+]] = #llvm.tbaa_type_desc<id = "global data/_QMtestEx", members = {<#tbaa_type_desc5, 0>}>
// CHECK: #[[$ATTR_45:.+]] = #llvm.tbaa_type_desc<id = "dummy arg data/_QMtestFcalleeEz", members = {<#tbaa_type_desc6, 0>}>
// CHECK: #[[$ATTR_46:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc7, access_type = #tbaa_type_desc7, offset = 0>
// CHECK: #[[$ATTR_47:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc8, access_type = #tbaa_type_desc8, offset = 0>
// CHECK: #[[$ATTR_48:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc9, access_type = #tbaa_type_desc9, offset = 0>
// CHECK: #[[$ATTR_49:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc10, access_type = #tbaa_type_desc10, offset = 0>
// CHECK: #[[$ATTR_50:.+]] = #llvm.tbaa_tag<base_type = #tbaa_type_desc11, access_type = #tbaa_type_desc11, offset = 0>
// CHECK: func.func @_QMtestPcaller(
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f32> {fir.bindc_name = "z"}) {
// CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_2:.*]] = fir.address_of(@_QMtestEx) : !fir.ref<f32>
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_2]] {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_4:.*]] = fir.address_of(@_QMtestEy) : !fir.ref<f32>
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_4]] {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_6:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QMtestFcallerEz"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
// CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]] {tbaa = [#[[$ATTR_46]]]} : !fir.ref<f32>
// CHECK: fir.store %[[VAL_7]] to %[[VAL_3]] {tbaa = [#[[$ATTR_47]]]} : !fir.ref<f32>
// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.address_of(@_QMtestEx) : !fir.ref<f32>
// CHECK: %[[VAL_10:.*]] = fir.declare %[[VAL_9]] {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_11:.*]] = fir.address_of(@_QMtestEy) : !fir.ref<f32>
// CHECK: %[[VAL_12:.*]] = fir.declare %[[VAL_11]] {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
// CHECK: %[[VAL_13:.*]] = fir.declare %[[VAL_6]] dummy_scope %[[VAL_8]] {uniq_name = "_QMtestFcalleeEz"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_12]] {tbaa = [#[[$ATTR_48]]]} : !fir.ref<f32>
// CHECK: fir.store %[[VAL_14]] to %[[VAL_10]] {tbaa = [#[[$ATTR_49]]]} : !fir.ref<f32>
// CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_13]] {tbaa = [#[[$ATTR_50]]]} : !fir.ref<f32>
// CHECK: fir.store %[[VAL_15]] to %[[VAL_12]] {tbaa = [#[[$ATTR_48]]]} : !fir.ref<f32>
func.func @_QMtestPcaller(%arg0: !fir.ref<f32> {fir.bindc_name = "z"}) {
%0 = fir.dummy_scope : !fir.dscope
%1 = fir.address_of(@_QMtestEx) : !fir.ref<f32>
%2 = fir.declare %1 {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
%3 = fir.address_of(@_QMtestEy) : !fir.ref<f32>
%4 = fir.declare %3 {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
%5 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QMtestFcallerEz"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%6 = fir.load %4 : !fir.ref<f32>
fir.store %6 to %2 : !fir.ref<f32>
%7 = fir.dummy_scope : !fir.dscope
%8 = fir.address_of(@_QMtestEx) : !fir.ref<f32>
%9 = fir.declare %8 {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> !fir.ref<f32>
%10 = fir.address_of(@_QMtestEy) : !fir.ref<f32>
%11 = fir.declare %10 {uniq_name = "_QMtestEy"} : (!fir.ref<f32>) -> !fir.ref<f32>
%12 = fir.declare %5 dummy_scope %7 {uniq_name = "_QMtestFcalleeEz"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%13 = fir.load %11 : !fir.ref<f32>
fir.store %13 to %9 : !fir.ref<f32>
%14 = fir.load %12 : !fir.ref<f32>
fir.store %14 to %11 : !fir.ref<f32>
return
}
fir.global @_QMtestEx : f32 {
%0 = fir.zero_bits f32
fir.has_value %0 : f32
}
fir.global @_QMtestEy : f32 {
%0 = fir.zero_bits f32
fir.has_value %0 : f32
}
36 changes: 22 additions & 14 deletions flang/test/Transforms/tbaa.fir
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
func.func @_QPonearg(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}) {
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%0 = fir.declare %arg0 {uniq_name = "_QFoneargEa"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%dscope = fir.dummy_scope : !fir.dscope
%0 = fir.declare %arg0 dummy_scope %dscope {uniq_name = "_QFoneargEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
%1 = fir.rebox %0 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%2 = fir.array_coor %1 %c2 : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
%3 = fir.load %2 : !fir.ref<i32>
Expand All @@ -27,7 +28,8 @@
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}) {
// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {uniq_name = "_QFoneargEa"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFoneargEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_4:.*]] = fir.rebox %[[VAL_3]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_5:.*]] = fir.array_coor %[[VAL_4]] %[[VAL_2]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_5]] {tbaa = [#[[ONE_ARG_A_TAG]]]} : !fir.ref<i32>
Expand All @@ -44,9 +46,10 @@
// end subroutine
func.func @_QPtwoarg(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %arg1: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "b"}) {
%c1 = arith.constant 1 : index
%0 = fir.declare %arg0 {uniq_name = "_QFtwoargEa"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%dscope = fir.dummy_scope : !fir.dscope
%0 = fir.declare %arg0 dummy_scope %dscope {uniq_name = "_QFtwoargEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
%1 = fir.rebox %0 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%2 = fir.declare %arg1 {uniq_name = "_QFtwoargEb"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%2 = fir.declare %arg1 dummy_scope %dscope {uniq_name = "_QFtwoargEb"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
%3 = fir.rebox %2 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%4 = fir.array_coor %3 %c1 : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
%5 = fir.load %4 : !fir.ref<i32>
Expand All @@ -68,9 +71,10 @@
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"},
// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "b"}) {
// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {uniq_name = "_QFtwoargEa"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFtwoargEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_4:.*]] = fir.rebox %[[VAL_3]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_1]] {uniq_name = "_QFtwoargEb"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_1]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFtwoargEb"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_6:.*]] = fir.rebox %[[VAL_5]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_7:.*]] = fir.array_coor %[[VAL_6]] %[[VAL_2]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]] {tbaa = [#[[TWO_ARG_B_TAG]]]} : !fir.ref<i32>
Expand All @@ -88,9 +92,10 @@
// end subroutine
func.func @_QPtargetarg(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a", fir.target}, %arg1: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "b"}) {
%c1 = arith.constant 1 : index
%0 = fir.declare %arg0 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtargetargEa"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%dscope = fir.dummy_scope : !fir.dscope
%0 = fir.declare %arg0 dummy_scope %dscope {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtargetargEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
%1 = fir.rebox %0 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%2 = fir.declare %arg1 {uniq_name = "_QFtargetargEb"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%2 = fir.declare %arg1 dummy_scope %dscope {uniq_name = "_QFtargetargEb"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
%3 = fir.rebox %2 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%4 = fir.array_coor %3 %c1 : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
%5 = fir.load %4 : !fir.ref<i32>
Expand All @@ -111,9 +116,10 @@
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a", fir.target},
// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "b"}) {
// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #{{.*}}<target>, uniq_name = "_QFtargetargEa"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {fortran_attrs = #{{.*}}<target>, uniq_name = "_QFtargetargEa"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_4:.*]] = fir.rebox %[[VAL_3]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_1]] {uniq_name = "_QFtargetargEb"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_1]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFtargetargEb"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_6:.*]] = fir.rebox %[[VAL_5]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_7:.*]] = fir.array_coor %[[VAL_6]] %[[VAL_2]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]] {tbaa = [#[[TARGET_B_TAG]]]} : !fir.ref<i32>
Expand All @@ -133,8 +139,9 @@
func.func @_QPpointerarg(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "a"}, %arg1: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "b"}) {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%0 = fir.declare %arg0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFpointerargEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
%1 = fir.declare %arg1 {uniq_name = "_QFpointerargEb"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%dscope = fir.dummy_scope : !fir.dscope
%0 = fir.declare %arg0 dummy_scope %dscope {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFpointerargEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
%1 = fir.declare %arg1 dummy_scope %dscope {uniq_name = "_QFpointerargEb"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
%2 = fir.rebox %1 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
%3 = fir.array_coor %2 %c1 : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
%4 = fir.load %3 : !fir.ref<i32>
Expand All @@ -159,8 +166,9 @@
// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "b"}) {
// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
// CHECK: %[[VAL_4:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #{{.*}}<pointer>, uniq_name = "_QFpointerargEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_1]] {uniq_name = "_QFpointerargEb"} : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_4:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {fortran_attrs = #{{.*}}<pointer>, uniq_name = "_QFpointerargEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_1]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFpointerargEb"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_6:.*]] = fir.rebox %[[VAL_5]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
// CHECK: %[[VAL_7:.*]] = fir.array_coor %[[VAL_6]] %[[VAL_3]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]] {tbaa = [#[[POINTER_B_TAG]]]} : !fir.ref<i32>
Expand Down
14 changes: 8 additions & 6 deletions flang/test/Transforms/tbaa2.fir
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c1_i32 = arith.constant 1 : i32
%dscope = fir.dummy_scope : !fir.dscope
%0 = fir.address_of(@_QMmodEa) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
%1 = fir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmodEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
%2 = fir.address_of(@_QMmodEb) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
Expand Down Expand Up @@ -107,10 +108,10 @@
%25 = fir.declare %24 {uniq_name = "_QMmodFcalleeEj"} : (!fir.ref<i32>) -> !fir.ref<i32>
%26 = fir.alloca i32 {bindc_name = "k", uniq_name = "_QMmodFcalleeEk"}
%27 = fir.declare %26 {uniq_name = "_QMmodFcalleeEk"} : (!fir.ref<i32>) -> !fir.ref<i32>
%28 = fir.declare %arg2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmodFcalleeElow"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>
%29 = fir.declare %arg1 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMmodFcalleeEy"} : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
%28 = fir.declare %arg2 dummy_scope %dscope {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmodFcalleeElow"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>
%29 = fir.declare %arg1 dummy_scope %dscope {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMmodFcalleeEy"} : (!fir.box<!fir.array<?x?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?x?xf32>>
%30 = fir.rebox %29 : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
%31 = fir.declare %arg0 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMmodFcalleeEz"} : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
%31 = fir.declare %arg0 dummy_scope %dscope {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMmodFcalleeEz"} : (!fir.box<!fir.array<?x?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?x?xf32>>
%32 = fir.rebox %31 : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
%33 = fir.load %15 : !fir.ref<i32>
%34 = arith.addi %33, %c1_i32 : i32
Expand Down Expand Up @@ -232,6 +233,7 @@
// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
// CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32
// CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_7:.*]] = fir.address_of(@_QMmodEa) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
// CHECK: %[[VAL_8:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #{{.*}}<allocatable>, uniq_name = "_QMmodEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
// CHECK: %[[VAL_9:.*]] = fir.address_of(@_QMmodEb) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
Expand Down Expand Up @@ -260,10 +262,10 @@
// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_31]] {uniq_name = "_QMmodFcalleeEj"} : (!fir.ref<i32>) -> !fir.ref<i32>
// CHECK: %[[VAL_33:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QMmodFcalleeEk"}
// CHECK: %[[VAL_34:.*]] = fir.declare %[[VAL_33]] {uniq_name = "_QMmodFcalleeEk"} : (!fir.ref<i32>) -> !fir.ref<i32>
// CHECK: %[[VAL_35:.*]] = fir.declare %[[VAL_2]] {fortran_attrs = #{{.*}}<allocatable>, uniq_name = "_QMmodFcalleeElow"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>
// CHECK: %[[VAL_36:.*]] = fir.declare %[[VAL_1]] {fortran_attrs = #{{.*}}<intent_in>, uniq_name = "_QMmodFcalleeEy"} : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
// CHECK: %[[VAL_35:.*]] = fir.declare %[[VAL_2]] dummy_scope %[[DSCOPE]] {fortran_attrs = #{{.*}}<allocatable>, uniq_name = "_QMmodFcalleeElow"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xf32>>>>
// CHECK: %[[VAL_36:.*]] = fir.declare %[[VAL_1]] dummy_scope %[[DSCOPE]] {fortran_attrs = #{{.*}}<intent_in>, uniq_name = "_QMmodFcalleeEy"} : (!fir.box<!fir.array<?x?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?x?xf32>>
// CHECK: %[[VAL_37:.*]] = fir.rebox %[[VAL_36]] : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
// CHECK: %[[VAL_38:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #{{.*}}<intent_in>, uniq_name = "_QMmodFcalleeEz"} : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
// CHECK: %[[VAL_38:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {fortran_attrs = #{{.*}}<intent_in>, uniq_name = "_QMmodFcalleeEz"} : (!fir.box<!fir.array<?x?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?x?xf32>>
// CHECK: %[[VAL_39:.*]] = fir.rebox %[[VAL_38]] : (!fir.box<!fir.array<?x?x?xf32>>) -> !fir.box<!fir.array<?x?x?xf32>>
// CHECK: %[[VAL_40:.*]] = fir.load %[[VAL_22]] {tbaa = [#[[GLBL_ZSTART_TAG]]]} : !fir.ref<i32>
// CHECK: %[[VAL_41:.*]] = arith.addi %[[VAL_40]], %[[VAL_6]] : i32
Expand Down
Loading