[libclc] [libclc] use default paths with find_program when possible (PR #105969)
hvdijk wrote: > > Apologies, but I'm having a bit of trouble understanding the scenario that > > this PR addresses. > > Nixpkgs adds the tools being used to `$PATH` so find program needs to use > path. This PR enables inadvertent errors on non-Nix systems though. When a specific LLVM path is used, and a binary is missing there, but a different binary with the same name is available in `$PATH`, we don't normally want that other binary to be used, it is quite possibly from a wrong version of LLVM. Right now, this is detected early at CMake time, and with this PR, it would no longer be. If standalone builds continue to be used, could this be avoided by changing the Nixpkgs build to install symlinks to all needed tools in a single directory (possibly a temporary directory populated during the libclc build), and making that directory available as `LLVM_TOOLS_BINARY_DIR`? https://github.com/llvm/llvm-project/pull/105969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libclc] [libclc] use default paths with find_program when possible (PR #105969)
hvdijk wrote: Apologies, but I'm having a bit of trouble understanding the scenario that this PR addresses. It looks like it's meant to handle the case where `LLVM_TOOLS_BINARY_DIR` does not contain the LLVM binaries, is that right? In that case, why can `LLVM_TOOLS_BINARY_DIR` not instead be set to a path that does contain the LLVM binaries? https://github.com/llvm/llvm-project/pull/105969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libclc] [libclc] use default paths with find_program when possible (PR #105969)
@@ -55,7 +55,7 @@ if( LIBCLC_STANDALONE_BUILD OR CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DI # Import required tools if( NOT EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) foreach( tool IN ITEMS clang llvm-as llvm-link opt ) - find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) +find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} ) hvdijk wrote: At https://github.com/RossComputerGuy/llvm-project/blob/056e0f9b7c7b788ad0d85a1479000fd1af4f98ce/libclc/CMakeLists.txt#L100-L104 there is a check for missing tools. This check would not work if using the imported targets if LLVM CMake files are installed, but the binaries are missing, which because of the way LLVM is split in distros is something that can easily happen. https://github.com/llvm/llvm-project/pull/105969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libclc] [llvm] [libclc] More cross compilation fixes (PR #97811)
hvdijk wrote: Both buildbot failures appear to be unrelated to this PR: neither fails in libclc, the first has resolved itself and passes in later attempts, the second looks like the builder has just run out of disk space. If I am wrong and there is something I should look into please let me know, otherwise I will leave it. https://github.com/llvm/llvm-project/pull/97811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libclc] [llvm] [libclc] More cross compilation fixes (PR #97811)
https://github.com/hvdijk closed https://github.com/llvm/llvm-project/pull/97811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libclc] [llvm] [libclc] More cross compilation fixes (PR #97811)
hvdijk wrote: ping https://github.com/llvm/llvm-project/pull/97811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libclc] [llvm] [libclc] More cross compilation fixes (PR #97811)
hvdijk wrote: The SPIRV-LLVM-Translator change that this depended on has been merged, so this PR no longer depends on external changes. https://github.com/llvm/llvm-project/pull/97811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libclc] [llvm] [libclc] More cross compilation fixes (PR #97811)
https://github.com/hvdijk edited https://github.com/llvm/llvm-project/pull/97811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libclc] [llvm] [libclc] More cross compilation fixes (PR #97811)
https://github.com/hvdijk created https://github.com/llvm/llvm-project/pull/97811 * Move the setup_host_tool calls to the directories of their tool. Although it works to call it in libclc, it can only appear in a single location so it fails the "what if everyone did this?" test and causes problems for downstream code that also wants to use native versions of these tools from other projects. * Correct the TARGET "${${tool}_target}" check. "${${tool}_target}" may be set to the path to the executable, which works in dependencies but cannot be tested using if(TARGET). For lack of a better alternative, just check that "${${tool}_target}" is non-empty and trust that if it is, it is set to a meaningful value. If somehow it turns out to be a valid target, its value will still show up in error messages anyway. * Account for llvm-spirv possibly being provided in-tree. Per https://github.com/KhronosGroup/SPIRV-LLVM-Translator?tab=readme-ov-file#llvm-in-tree-build it is possible to drop llvm-spirv into LLVM and have it built as part of LLVM's build. In this configuration, cross builds of LLVM require a native version of llvm-spirv to be built. Note: having this work in cross builds also requires a change to SPIRV-LLVM-Translator. >From 8c16c7d759cc9113e2c045c8b7a76cc61c19064a Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Fri, 5 Jul 2024 11:24:45 +0100 Subject: [PATCH] [libclc] More cross compilation fixes * Move the setup_host_tool calls to the directories of their tool. Although it works to call it in libclc, it can only appear in a single location so it fails the "what if everyone did this?" test and causes problems for downstream code that also wants to use native versions of these tools from other projects. * Correct the TARGET "${${tool}_target}" check. "${${tool}_target}" may be set to the path to the executable, which works in dependencies but cannot be tested using if(TARGET). For lack of a better alternative, just check that "${${tool}_target}" is non-empty and trust that if it is, it is set to a meaningful value. If somehow it turns out to be a valid target, its value will still show up in error messages anyway. * Account for llvm-spirv possibly being provided in-tree. Per https://github.com/KhronosGroup/SPIRV-LLVM-Translator?tab=readme-ov-file#llvm-in-tree-build it is possible to drop llvm-spirv into LLVM and have it built as part of LLVM's build. In this configuration, cross builds of LLVM require a native version of llvm-spirv to be built. Note: having this work in cross builds also requires a change to SPIRV-LLVM-Translator. --- clang/tools/driver/CMakeLists.txt | 2 ++ libclc/CMakeLists.txt | 30 +++-- llvm/tools/llvm-as/CMakeLists.txt | 2 ++ llvm/tools/llvm-link/CMakeLists.txt | 2 ++ llvm/tools/opt/CMakeLists.txt | 2 ++ 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/clang/tools/driver/CMakeLists.txt b/clang/tools/driver/CMakeLists.txt index 290bf2a42536d..f9e71223f47c4 100644 --- a/clang/tools/driver/CMakeLists.txt +++ b/clang/tools/driver/CMakeLists.txt @@ -38,6 +38,8 @@ add_clang_tool(clang GENERATE_DRIVER ) +setup_host_tool(clang CLANG clang_exe clang_target) + clang_target_link_libraries(clang PRIVATE clangBasic diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 4f5625ff94916..35136648d3591 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -73,10 +73,10 @@ else() endif() if( NOT EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) -setup_host_tool( clang CLANG clang_exe clang_target ) -setup_host_tool( llvm-as LLVM_AS llvm-as_exe llvm-as_target ) -setup_host_tool( llvm-link LLVM_LINK llvm-link_exe llvm-link_target ) -setup_host_tool( opt OPT opt_exe opt_target ) +get_host_tool_path( clang CLANG clang_exe clang_target ) +get_host_tool_path( llvm-as LLVM_AS llvm-as_exe llvm-as_target ) +get_host_tool_path( llvm-link LLVM_LINK llvm-link_exe llvm-link_target ) +get_host_tool_path( opt OPT opt_exe opt_target ) endif() endif() @@ -97,17 +97,19 @@ if( EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) endif() foreach( tool IN ITEMS clang opt llvm-as llvm-link ) - if( NOT EXISTS "${${tool}_exe}" AND NOT TARGET "${${tool}_target}" ) + if( NOT EXISTS "${${tool}_exe}" AND "${tool}_target" STREQUAL "" ) message( FATAL_ERROR "libclc toolchain incomplete - missing tool ${tool}!" ) endif() endforeach() # llvm-spirv is an optional dependency, used to build spirv-* targets. -find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) - -if( LLVM_SPIRV ) - add_executable( libclc::llvm-spirv IMPORTED GLOBAL ) - set_target_properties( libclc::llvm-spirv PROPERTIES IMPORTED_LOCATION ${LLVM_SPIRV} ) +# It may be provided in-tree or externally. +if( TARGET llvm-spirv ) + get_host_tool_path( llvm-spirv LLVM_SPIRV llvm-spirv_exe llvm-spirv_target ) +else() + find_p
[libclc] [libclc] Fix cross in-tree builds (PR #97392)
https://github.com/hvdijk closed https://github.com/llvm/llvm-project/pull/97392 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libclc] [libclc] Fix cross in-tree builds (PR #97392)
https://github.com/hvdijk created https://github.com/llvm/llvm-project/pull/97392 When performing cross in-tree builds, we need native versions of various tools, we cannot assume the cross builds that are part of the current build are executable. LLVM provides the setup_host_tool function to handle this, either picking up versions of tools from LLVM_NATIVE_TOOL_DIR, or implicitly building native versions as needed. Use it for libclc too. LLVM's setup_host_tool function assumes the project is LLVM, so this also needs libclc's project() to be conditional on it being built standalone. Luckily, the only change this needs is using CMAKE_CURRENT_SOURCE_DIR instead of PROJECT_SOURCE_DIR. >From 273d5c86afd1418565d563825f38d6ec340ee00f Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Fri, 28 Jun 2024 13:41:16 +0100 Subject: [PATCH 1/2] [libclc][NFC] Do not set project in in-tree builds. This is NFC at the moment because nothing relies on ${PROJECT_*} being set to the LLVM values. --- libclc/CMakeLists.txt | 24 +--- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index ef8d21b167623..42a1fe46ea9ac 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -1,11 +1,13 @@ cmake_minimum_required(VERSION 3.20.0) -project( libclc VERSION 0.2.0 LANGUAGES CXX C) +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + project(libclc VERSION 0.2.0 LANGUAGES CXX C) +endif() set(CMAKE_CXX_STANDARD 17) # Add path for custom modules -list( INSERT CMAKE_MODULE_PATH 0 "${PROJECT_SOURCE_DIR}/cmake/modules" ) +list( INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ) set( LIBCLC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) set( LIBCLC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ) @@ -211,7 +213,7 @@ if( ENABLE_RUNTIME_SUBNORMAL ) foreach( file IN ITEMS subnormal_use_default subnormal_disable ) link_bc( TARGET ${file} - INPUTS ${PROJECT_SOURCE_DIR}/generic/lib/${file}.ll + INPUTS ${CMAKE_CURRENT_SOURCE_DIR}/generic/lib/${file}.ll ) install( FILES $ ARCHIVE DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" ) @@ -219,7 +221,7 @@ if( ENABLE_RUNTIME_SUBNORMAL ) endif() find_package( Python3 REQUIRED COMPONENTS Interpreter ) -file( TO_CMAKE_PATH ${PROJECT_SOURCE_DIR}/generic/lib/gen_convert.py script_loc ) +file( TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/generic/lib/gen_convert.py script_loc ) add_custom_command( OUTPUT convert.cl COMMAND ${Python3_EXECUTABLE} ${script_loc} > convert.cl @@ -264,7 +266,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) foreach( l ${dirs} ${DARCH} ${DARCH}-${OS} ${DARCH}-${VENDOR}-${OS} ) foreach( s "SOURCES" "SOURCES_${LLVM_MAJOR}.${LLVM_MINOR}" ) file( TO_CMAKE_PATH ${l}/lib/${s} file_loc ) - file( TO_CMAKE_PATH ${PROJECT_SOURCE_DIR}/${file_loc} loc ) + file( TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file_loc} loc ) # Prepend the location to give higher priority to # specialized implementation if( EXISTS ${loc} ) @@ -339,7 +341,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) list( APPEND build_flags -D__CLC_INTERNAL -D${CLC_TARGET_DEFINE} - -I${PROJECT_SOURCE_DIR}/generic/include + -I${CMAKE_CURRENT_SOURCE_DIR}/generic/include # FIXME: Fix libclc to not require disabling this noisy warning -Wno-bitwise-conditional-parentheses ) @@ -360,9 +362,9 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) # the path (e.g., ironing out any ".."), then make it relative to the # root directory again, and use that relative path component for the # binary path. -get_filename_component( abs_path ${file} ABSOLUTE BASE_DIR ${PROJECT_SOURCE_DIR} ) -file( RELATIVE_PATH root_rel_path ${PROJECT_SOURCE_DIR} ${abs_path} ) -set( input_file ${PROJECT_SOURCE_DIR}/${file} ) +get_filename_component( abs_path ${file} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) +file( RELATIVE_PATH root_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${abs_path} ) +set( input_file ${CMAKE_CURRENT_SOURCE_DIR}/${file} ) set( output_file "${LIBCLC_ARCH_OBJFILE_DIR}/${root_rel_path}.bc" ) endif() @@ -373,7 +375,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) INPUT ${input_file} OUTPUT ${output_file} EXTRA_OPTS "${mcpu}" -fno-builtin -nostdlib - "${build_flags}" -I${PROJECT_SOURCE_DIR}/${file_dir} + "${build_flags}" -I${CMAKE_CURRENT_SOURCE_DIR}/${file_dir} DEPENDENCIES generate_convert.cl clspv-generate_convert.cl ) list( APPEND bytecode_files ${output_file} ) @@ -431,7 +433,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) if( NOT clang_triple MATCHES ".*ptx.*--$" ) add_test( NAME external-calls-${obj_suffix} COMMAND ./check_external_calls.sh ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} ${LLVM_TOOLS_BINARY
[clang] [AArch64] Extend SVE diagnostics. (PR #94976)
https://github.com/hvdijk closed https://github.com/llvm/llvm-project/pull/94976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64] Extend SVE diagnostics. (PR #94976)
https://github.com/hvdijk created https://github.com/llvm/llvm-project/pull/94976 The SVE diagnostics were guarded by a FD->hasBody() check that prevented the diagnostic from being emitted for code that still triggered the backend crashes that the errors were meant to avoid, because FD->hasBody() returns false for a function that Clang is currently processing. This is not done for the equivalent RISC-V code, and is not needed for AArch64 either, so remove it. Errors were also emitted in the wrong location, errors were emitted at the called function's location, rather than at the caller's, which meant that just removing the FD->hasBody() check resulted in incomprehensible errors. Change this as well. The aarch64-mangle-sve-vectors.cpp test was using -target-feature wrong which was exposed as a result of these changes. Different target features need to be passed in as different -target-feature options. aarch64-targetattr-arch.c has a test_errors() function that needs to be split in two. Now that svundef_s8() is diagnosed for its use of svint8_t, the "needs target feature sve" diagnostic is no longer emitted, but this affects all calls in the same function. To ensure we still check this for its __crc32cd call, move that into a separate function. Fixes #94766. >From 9bd0b577a3a70abb6e27b389c3bc7cc1e0191cc3 Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Mon, 10 Jun 2024 14:14:46 +0100 Subject: [PATCH] [AArch64] Extend SVE diagnostics. The SVE diagnostics were guarded by a FD->hasBody() check that prevented the diagnostic from being emitted for code that still triggered the backend crashes that the errors were meant to avoid, because FD->hasBody() returns false for a function that Clang is currently processing. This is not done for the equivalent RISC-V code, and is not needed for AArch64 either, so remove it. Errors were also emitted in the wrong location, errors were emitted at the called function's location, rather than at the caller's, which meant that just removing the FD->hasBody() check resulted in incomprehensible errors. Change this as well. The aarch64-mangle-sve-vectors.cpp test was using -target-feature wrong which was exposed as a result of these changes. Different target features need to be passed in as different -target-feature options. aarch64-targetattr-arch.c has a test_errors() function that needs to be split in two. Now that svundef_s8() is diagnosed for its use of svint8_t, the "needs target feature sve" diagnostic is no longer emitted, but this affects all calls in the same function. To ensure we still check this for its __crc32cd call, move that into a separate function. Fixes #94766. --- clang/lib/Sema/Sema.cpp | 7 ++--- clang/test/CodeGen/aarch64-targetattr-arch.c | 8 -- .../target.c | 28 --- .../CodeGenCXX/aarch64-mangle-sve-vectors.cpp | 4 +-- .../Sema/aarch64-sme2-sve2p1-diagnostics.c| 3 ++ clang/test/Sema/arm-sve-target.cpp| 2 +- 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index a612dcd4b4d03..907a05a5d1b49 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -2093,16 +2093,15 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { } // Don't allow SVE types in functions without a SVE target. -if (Ty->isSVESizelessBuiltinType() && FD && FD->hasBody()) { +if (Ty->isSVESizelessBuiltinType() && FD) { llvm::StringMap CallerFeatureMap; Context.getFunctionFeatureMap(CallerFeatureMap, FD); if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) { if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap)) - Diag(D->getLocation(), diag::err_sve_vector_in_non_sve_target) << Ty; + Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty; else if (!IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true)) { - Diag(D->getLocation(), diag::err_sve_vector_in_non_streaming_function) - << Ty; + Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty; } } } diff --git a/clang/test/CodeGen/aarch64-targetattr-arch.c b/clang/test/CodeGen/aarch64-targetattr-arch.c index ed731d0378625..5de73d6027845 100644 --- a/clang/test/CodeGen/aarch64-targetattr-arch.c +++ b/clang/test/CodeGen/aarch64-targetattr-arch.c @@ -29,14 +29,18 @@ float16_t test_fp16_on_v9(float16_t x, float16_t y) return vabdh_f16(x, y); } -void test_errors() +void test_error1() { #ifdef HAS8 // expected-error@+2{{always_inline function '__crc32cd' requires target feature 'crc'}} #endif __crc32cd(1, 1); +} + +void test_error2() +{ #if defined(HAS8) || defined(HAS81) -// expected-error@+2{{'svundef_s8' needs target feature sve}} +// expected-error@+2{{SVE vector type 'svint8_t'
[clang] [SYCL] Allow neon attributes for ARM host (PR #94229)
https://github.com/hvdijk updated https://github.com/llvm/llvm-project/pull/94229 >From 895f71d5f890a3988014e0d779586b9f142be90f Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Mon, 3 Jun 2024 15:03:17 +0100 Subject: [PATCH] [SYCL] Allow neon attributes for ARM host We permit neon attributes in CUDA device code, but this permission was only for CUDA device code. The same permission makes sense for SYCL device code as well, especially now that neon attributes are used in glibc headers. --- clang/lib/Sema/SemaType.cpp| 12 ++-- clang/test/SemaSYCL/neon-attrs.cpp | 15 +++ 2 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 clang/test/SemaSYCL/neon-attrs.cpp diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7cec82c701028..a8a1463522d03 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8077,10 +8077,10 @@ static bool verifyValidIntegerConstantExpr(Sema &S, const ParsedAttr &Attr, /// match one of the standard Neon vector types. static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, Sema &S, VectorKind VecKind) { - bool IsTargetCUDAAndHostARM = false; - if (S.getLangOpts().CUDAIsDevice) { + bool IsTargetDeviceAndHostARM = false; + if (S.getLangOpts().CUDAIsDevice || S.getLangOpts().SYCLIsDevice) { const TargetInfo *AuxTI = S.getASTContext().getAuxTargetInfo(); -IsTargetCUDAAndHostARM = +IsTargetDeviceAndHostARM = AuxTI && (AuxTI->getTriple().isAArch64() || AuxTI->getTriple().isARM()); } @@ -8090,7 +8090,7 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, S.Context.getTargetInfo().hasFeature("mve") || S.Context.getTargetInfo().hasFeature("sve") || S.Context.getTargetInfo().hasFeature("sme") || -IsTargetCUDAAndHostARM) && +IsTargetDeviceAndHostARM) && VecKind == VectorKind::Neon) { S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr << "'neon', 'mve', 'sve' or 'sme'"; @@ -8099,7 +8099,7 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, } if (!(S.Context.getTargetInfo().hasFeature("neon") || S.Context.getTargetInfo().hasFeature("mve") || -IsTargetCUDAAndHostARM) && +IsTargetDeviceAndHostARM) && VecKind == VectorKind::NeonPoly) { S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr << "'neon' or 'mve'"; @@ -8121,7 +8121,7 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, // Only certain element types are supported for Neon vectors. if (!isPermittedNeonBaseType(CurType, VecKind, S) && - !IsTargetCUDAAndHostARM) { + !IsTargetDeviceAndHostARM) { S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; Attr.setInvalid(); return; diff --git a/clang/test/SemaSYCL/neon-attrs.cpp b/clang/test/SemaSYCL/neon-attrs.cpp new file mode 100644 index 0..b1fd947d4a888 --- /dev/null +++ b/clang/test/SemaSYCL/neon-attrs.cpp @@ -0,0 +1,15 @@ +// Host compilation on ARM with neon enabled (no errors expected). +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fsyntax-only -verify=quiet %s + +// Host compilation on ARM with neon disabled. +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature -neon -fsyntax-only -verify %s + +// Device compilation on ARM (no errors expected). +// RUN: %clang_cc1 -triple spirv64 -aux-triple aarch64-linux-gnu -fsycl-is-device -fsyntax-only -verify=quiet %s + +// quiet-no-diagnostics +typedef __attribute__((neon_vector_type(4))) float float32x4_t; +// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'}} +typedef unsigned char poly8_t; +typedef __attribute__((neon_polyvector_type(8))) poly8_t poly8x8_t; +// expected-error@-1 {{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SYCL] Allow neon attributes for ARM host (PR #94229)
https://github.com/hvdijk created https://github.com/llvm/llvm-project/pull/94229 We permit neon attributes in CUDA device code, but this permission was only for CUDA device code. The same permission makes sense for SYCL device code as well, especially now that neon attributes are used in glibc headers. >From 13fb2b9d867d353ec67aab96159b8eea690e87d0 Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Mon, 3 Jun 2024 14:47:15 +0100 Subject: [PATCH] [SYCL] Allow neon attributes for ARM host We permit neon attributes in CUDA device code, but this permission was only for CUDA device code. The same permission makes sense for SYCL device code as well, especially now that neon attributes are used in glibc headers. --- clang/lib/Sema/SemaType.cpp| 12 ++-- clang/test/SemaSYCL/neon-attrs.cpp | 16 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 clang/test/SemaSYCL/neon-attrs.cpp diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7cec82c701028..a8a1463522d03 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8077,10 +8077,10 @@ static bool verifyValidIntegerConstantExpr(Sema &S, const ParsedAttr &Attr, /// match one of the standard Neon vector types. static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, Sema &S, VectorKind VecKind) { - bool IsTargetCUDAAndHostARM = false; - if (S.getLangOpts().CUDAIsDevice) { + bool IsTargetDeviceAndHostARM = false; + if (S.getLangOpts().CUDAIsDevice || S.getLangOpts().SYCLIsDevice) { const TargetInfo *AuxTI = S.getASTContext().getAuxTargetInfo(); -IsTargetCUDAAndHostARM = +IsTargetDeviceAndHostARM = AuxTI && (AuxTI->getTriple().isAArch64() || AuxTI->getTriple().isARM()); } @@ -8090,7 +8090,7 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, S.Context.getTargetInfo().hasFeature("mve") || S.Context.getTargetInfo().hasFeature("sve") || S.Context.getTargetInfo().hasFeature("sme") || -IsTargetCUDAAndHostARM) && +IsTargetDeviceAndHostARM) && VecKind == VectorKind::Neon) { S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr << "'neon', 'mve', 'sve' or 'sme'"; @@ -8099,7 +8099,7 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, } if (!(S.Context.getTargetInfo().hasFeature("neon") || S.Context.getTargetInfo().hasFeature("mve") || -IsTargetCUDAAndHostARM) && +IsTargetDeviceAndHostARM) && VecKind == VectorKind::NeonPoly) { S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr << "'neon' or 'mve'"; @@ -8121,7 +8121,7 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, // Only certain element types are supported for Neon vectors. if (!isPermittedNeonBaseType(CurType, VecKind, S) && - !IsTargetCUDAAndHostARM) { + !IsTargetDeviceAndHostARM) { S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; Attr.setInvalid(); return; diff --git a/clang/test/SemaSYCL/neon-attrs.cpp b/clang/test/SemaSYCL/neon-attrs.cpp new file mode 100644 index 0..ec79fa5033308 --- /dev/null +++ b/clang/test/SemaSYCL/neon-attrs.cpp @@ -0,0 +1,16 @@ +// Host compilation on ARM with neon enabled (no errors expected). +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fsyntax-only -verify=quiet %s + +// Host compilation on ARM with neon disabled. +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature -neon -fsyntax-only -verify %s + +// Device compilation on ARM (no errors expected). +// RUN: %clang_cc1 -triple spirv64 -aux-triple aarch64-linux-gnu -fsycl-is-device -fsyntax-only -verify=quiet %s + +// quiet-no-diagnostics +typedef __attribute__((neon_vector_type(4))) float float32x4_t; +// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'}} +// expect +typedef unsigned char poly8_t; +typedef __attribute__((neon_polyvector_type(8))) poly8_t poly8x8_t; +// expected-error@-1 {{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)
hvdijk wrote: Thanks for doing this, it's unfortunate that Clang is in a rather broken state with these types right now and it will be good to see improvement. I think the approach you're taking here is the only approach that will work. https://github.com/llvm/llvm-project/pull/91364 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)
@@ -1989,6 +1989,14 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, return EmitAtomicLoad(AtomicLValue, Loc).getScalarVal(); } + if (const auto *BIT = Ty->getAs()) { +if (BIT->getNumBits() > 128) { hvdijk wrote: For a number of bits >64, <=128, LLVM's `iN` type will have identical representation to Clang `_BitInt(N)` but different alignment. I think this is fine, I think nothing needs their alignment to match Clang's, but could you double-check to make sure you agree? https://github.com/llvm/llvm-project/pull/91364 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ValueTracking] Restore isKnownNonZero parameter order. (PR #88873)
https://github.com/hvdijk closed https://github.com/llvm/llvm-project/pull/88873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ValueTracking] Convert `isKnownNonZero` to use SimplifyQuery (PR #85863)
@@ -645,7 +645,7 @@ LazyValueInfoImpl::solveBlockValueImpl(Value *Val, BasicBlock *BB) { // instruction is placed, even if it could legally be hoisted much higher. // That is unfortunate. PointerType *PT = dyn_cast(BBI->getType()); - if (PT && isKnownNonZero(BBI, DL)) + if (PT && isKnownNonZero(BBI, /*Depth=*/0, DL)) hvdijk wrote: Created #88873 for it. https://github.com/llvm/llvm-project/pull/85863 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ValueTracking] Restore isKnownNonZero parameter order. (PR #88873)
https://github.com/hvdijk created https://github.com/llvm/llvm-project/pull/88873 Prior to #85863, the required parameters of llvm::isKnownNonZero were Value and DataLayout. After, they are Value, Depth, and SimplifyQuery, where SimplifyQuery is implicitly constructible from DataLayout. The change to move Depth before SimplifyQuery needed callers to be updated unnecessarily, and as commented in #85863, we actually want Depth to be after SimplifyQuery anyway so that it can be defaulted and the caller does not need to specify it. >From 6763d8cce44be02e9065c9c640736ac85ffcf8a2 Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Tue, 16 Apr 2024 12:06:31 +0100 Subject: [PATCH] [ValueTracking] Restore isKnownNonZero parameter order. Prior to #85863, the required parameters of llvm::isKnownNonZero were Value and DataLayout. After, they are Value, Depth, and SimplifyQuery, where SimplifyQuery is implicitly constructible from DataLayout. The change to move Depth before SimplifyQuery needed callers to be updated unnecessarily, and as commented in #85863, we actually want Depth to be after SimplifyQuery anyway so that it can be defaulted and the caller does not need to specify it. --- clang/lib/CodeGen/CGCall.cpp | 3 +- llvm/include/llvm/Analysis/ValueTracking.h| 2 +- llvm/lib/Analysis/BasicAliasAnalysis.cpp | 3 +- llvm/lib/Analysis/InstructionSimplify.cpp | 25 ++--- llvm/lib/Analysis/LazyValueInfo.cpp | 5 +- llvm/lib/Analysis/Loads.cpp | 4 +- llvm/lib/Analysis/ScalarEvolution.cpp | 2 +- llvm/lib/Analysis/ValueTracking.cpp | 106 +- llvm/lib/CodeGen/CodeGenPrepare.cpp | 2 +- .../Transforms/IPO/AttributorAttributes.cpp | 2 +- llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 2 +- .../InstCombine/InstCombineAddSub.cpp | 2 +- .../InstCombine/InstCombineAndOrXor.cpp | 4 +- .../InstCombine/InstCombineCalls.cpp | 11 +- .../InstCombine/InstCombineCompares.cpp | 18 +-- .../Transforms/InstCombine/InstCombinePHI.cpp | 3 +- .../InstCombine/InstructionCombining.cpp | 2 +- .../Instrumentation/MemorySanitizer.cpp | 4 +- .../Utils/PromoteMemoryToRegister.cpp | 2 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 20 ++-- .../Transforms/Vectorize/VectorCombine.cpp| 2 +- llvm/unittests/Analysis/ValueTrackingTest.cpp | 13 +-- 22 files changed, 113 insertions(+), 124 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 7a0bc6fa77b889..3f5463a9a70e9d 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4124,8 +4124,7 @@ static bool isProvablyNull(llvm::Value *addr) { } static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) { - return llvm::isKnownNonZero(Addr.getBasePointer(), /*Depth=*/0, - CGF.CGM.getDataLayout()); + return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout()); } /// Emit the actual writing-back of a writeback. diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index 9db0894162afca..e1c41b3b55ccfb 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -124,7 +124,7 @@ bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI); /// specified, perform context-sensitive analysis and return true if the /// pointer couldn't possibly be null at the specified instruction. /// Supports values with integer or pointer type and vectors of integers. -bool isKnownNonZero(const Value *V, unsigned Depth, const SimplifyQuery &Q); +bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth = 0); /// Return true if the two given values are negation. /// Currently can recoginze Value pair: diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index b082dfe8fbd217..16ee2ca49d0ece 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1283,8 +1283,7 @@ AliasResult BasicAAResult::aliasGEP( // VarIndex = Scale*V. const VariableGEPIndex &Var = DecompGEP1.VarIndices[0]; if (Var.Val.TruncBits == 0 && -isKnownNonZero(Var.Val.V, /*Depth=*/0, - SimplifyQuery(DL, DT, &AC, Var.CxtI))) { +isKnownNonZero(Var.Val.V, SimplifyQuery(DL, DT, &AC, Var.CxtI))) { // Check if abs(V*Scale) >= abs(Scale) holds in the presence of // potentially wrapping math. auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) { diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 4e6e666922671d..8955de6375dec4 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -1586,10 +1586,10 @@ static Value *simplifyUnsignedRang
[clang] [llvm] [ValueTracking] Convert `isKnownNonZero` to use SimplifyQuery (PR #85863)
@@ -645,7 +645,7 @@ LazyValueInfoImpl::solveBlockValueImpl(Value *Val, BasicBlock *BB) { // instruction is placed, even if it could legally be hoisted much higher. // That is unfortunate. PointerType *PT = dyn_cast(BBI->getType()); - if (PT && isKnownNonZero(BBI, DL)) + if (PT && isKnownNonZero(BBI, /*Depth=*/0, DL)) hvdijk wrote: Thanks, I had been slightly optimistic that this was just going to be a few days, but it sounds like it's going to be longer. In that case I will check what is easiest for us (which might be to submit that LLVM change ourselves). https://github.com/llvm/llvm-project/pull/85863 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ValueTracking] Convert `isKnownNonZero` to use SimplifyQuery (PR #85863)
@@ -645,7 +645,7 @@ LazyValueInfoImpl::solveBlockValueImpl(Value *Val, BasicBlock *BB) { // instruction is placed, even if it could legally be hoisted much higher. // That is unfortunate. PointerType *PT = dyn_cast(BBI->getType()); - if (PT && isKnownNonZero(BBI, DL)) + if (PT && isKnownNonZero(BBI, /*Depth=*/0, DL)) hvdijk wrote: The fact that this PR changes it so that `isKnownNonZero(BBI, DL)` is valid in LLVM 18, used to be valid in LLVM 19, is currently an error in LLVM 19, but will become valid in LLVM 19 again is unfortunate and difficult to account for in downstream projects. @goldsteinn If you are going to change that, do you think it is worth updating downstream code to support the current API, or is that change going to go in fast enough that we can just wait? https://github.com/llvm/llvm-project/pull/85863 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Introduce `SemaSYCL` (PR #88086)
@@ -0,0 +1,66 @@ +//===- SemaOpenACC.h 000- Semantic Analysis for SYCL constructs ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +/// \file +/// This file declares semantic analysis for SYCL constructs. +/// +//===--===// + +#ifndef LLVM_CLANG_SEMA_SEMASYCL_H +#define LLVM_CLANG_SEMA_SEMASYCL_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Sema/Ownership.h" +#include "clang/Sema/SemaBase.h" +#include "llvm/ADT/DenseSet.h" + +namespace clang { + +class SemaSYCL : public SemaBase { +public: + SemaSYCL(Sema &S); + + /// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current + /// context is "used as device code". + /// + /// - If CurLexicalContext is a kernel function or it is known that the + /// function will be emitted for the device, emits the diagnostics + /// immediately. + /// - If CurLexicalContext is a function and we are compiling + /// for the device, but we don't know that this function will be codegen'ed + /// for devive yet, creates a diagnostic which is emitted if and when we hvdijk wrote: This took me a moment longer to parse than it should. I realise you only moved it, this is not newly written by you, but maybe good to update at the same time by moving the "yet" to the front to make it clear and unambiguous that it applies to the "know", not to the "emitted": ```suggestion /// for the device, but we don't know yet that this function will be codegen'ed /// for the device, creates a diagnostic which is emitted if and when we ``` https://github.com/llvm/llvm-project/pull/88086 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Allow flexible arrays in unions and alone in structs (PR #84428)
@@ -271,6 +271,9 @@ Improvements to Clang's diagnostics - Clang now correctly diagnoses no arguments to a variadic macro parameter as a C23/C++20 extension. Fixes #GH84495. +- ``-Wmicrosoft`` or ``-Wgnu`` is now required to diagnose C99 flexible + array members in a union or alone in a struct. Fixes #GB84565. hvdijk wrote: Should be #GH rather than #GB. https://github.com/llvm/llvm-project/pull/84428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Allow flexible arrays in unions and alone in structs (PR #84428)
https://github.com/hvdijk approved this pull request. Looks good to me, thanks, aside from one typo in the release notes. Let me pre-emptively mark this as approved. Just to confirm, the warnings are also enabled by `-pedantic`? Is that worth mentioning in the release notes too? I'm fine if you want to leave that though. https://github.com/llvm/llvm-project/pull/84428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Allow flexible arrays in unions and alone in structs (PR #84428)
@@ -21,10 +27,76 @@ struct __attribute((packed, aligned(4))) { char a; int x; char z[]; } e = { 1, 2 struct { int x; char y[]; } f = { 1, { 13, 15 } }; // CHECK: @f ={{.*}} global <{ i32, [2 x i8] }> <{ i32 1, [2 x i8] c"\0D\0F" }> -union { - struct { -int a; -char b[]; - } x; -} in_union = {}; -// CHECK: @in_union ={{.*}} global %union.anon zeroinitializer +struct __attribute((packed)) { short a; char z[]; } g = { 2, { 11, 13, 15 } }; +// CHECK: @g ={{.*}} <{ i16, [3 x i8] }> <{ i16 2, [3 x i8] c"\0B\0D\0F" }>, + +// Last member is the potential flexible array, unnamed initializer skips it. +struct { int a; union { int b; short x; }; int c; int d; } h = {1, 2, {}, 3}; +// CHECK: @h = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, i32 3 } +struct { int a; union { int b; short x[0]; }; int c; int d; } h0 = {1, 2, {}, 3}; +// CHECK: @h0 = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, i32 3 } +struct { int a; union { int b; short x[1]; }; int c; int d; } h1 = {1, 2, {}, 3}; +// CHECK: @h1 = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, i32 3 } +struct { + int a; + union { +int b; +struct { + struct { } __ununsed; + short x[]; +}; + }; + int c; + int d; +} hiding = {1, 2, {}, 3}; +// CHECK: @hiding = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, i32 3 } +struct { int a; union { int b; short x[]; }; int c; int d; } hf = {1, 2, {}, 3}; +// CHECK: @hf = global %struct.anon{{.*}} { i32 1, %union.anon{{.*}} { i32 2 }, i32 0, i32 3 } + +// First member is the potential flexible array, initialization requires braces. +struct { int a; union { short x; int b; }; int c; int d; } i = {1, 2, {}, 3}; +// CHECK: @i = global { i32, { i16, [2 x i8] }, i32, i32 } { i32 1, { i16, [2 x i8] } { i16 2, [2 x i8] undef }, i32 0, i32 3 } +struct { int a; union { short x[0]; int b; }; int c; int d; } i0 = {1, {}, 2, 3}; +// CHECK: @i0 = global { i32, { [0 x i16], [4 x i8] }, i32, i32 } { i32 1, { [0 x i16], [4 x i8] } { [0 x i16] zeroinitializer, [4 x i8] undef }, i32 2, i32 3 } +struct { int a; union { short x[1]; int b; }; int c; int d; } i1 = {1, {2}, {}, 3}; +// CHECK: @i1 = global { i32, { [1 x i16], [2 x i8] }, i32, i32 } { i32 1, { [1 x i16], [2 x i8] } { [1 x i16] [i16 2], [2 x i8] undef }, i32 0, i32 3 } +struct { int a; union { short x[]; int b; }; int c; int d; } i_f = {4, {}, {}, 6}; +// CHECK: @i_f = global { i32, { [0 x i16], [4 x i8] }, i32, i32 } { i32 4, { [0 x i16], [4 x i8] } { [0 x i16] zeroinitializer, [4 x i8] undef }, i32 0, i32 6 } + +// Named initializers; order doesn't matter. +struct { int a; union { int b; short x; }; int c; int d; } hn = {.a = 1, .x = 2, .c = 3}; +// CHECK: @hn = global { i32, { i16, [2 x i8] }, i32, i32 } { i32 1, { i16, [2 x i8] } { i16 2, [2 x i8] undef }, i32 3, i32 0 } +struct { int a; union { int b; short x[0]; }; int c; int d; } hn0 = {.a = 1, .x = {2}, .c = 3}; +// CHECK: @hn0 = global { i32, { [0 x i16], [4 x i8] }, i32, i32 } { i32 1, { [0 x i16], [4 x i8] } { [0 x i16] zeroinitializer, [4 x i8] undef }, i32 3, i32 0 } +struct { int a; union { int b; short x[1]; }; int c; int d; } hn1 = {.a = 1, .x = {2}, .c = 3}; +// CHECK: @hn1 = global { i32, { [1 x i16], [2 x i8] }, i32, i32 } { i32 1, { [1 x i16], [2 x i8] } { [1 x i16] [i16 2], [2 x i8] undef }, i32 3, i32 0 } + +struct { char a[]; } empty_struct = {}; +// CHECK: @empty_struct ={{.*}} global %struct.anon{{.*}} zeroinitializer, align 1 + +struct { char a[]; } empty_struct0 = {0}; +// CHECK: @empty_struct0 = global { [1 x i8] } zeroinitializer, align 1 + +union { struct { int a; char b[]; }; } struct_in_union = {}; +// CHECK: @struct_in_union = global %union.anon{{.*}} zeroinitializer, align 4 + +union { struct { int a; char b[]; }; } struct_in_union0 = {0}; +// CHECK: @struct_in_union0 = global %union.anon{{.*}} zeroinitializer, align 4 + +union { int a; char b[]; } trailing_in_union = {}; +// CHECK: @trailing_in_union = global %union.anon{{.*}} zeroinitializer, align 4 + +union { int a; char b[]; } trailing_in_union0 = {0}; +// CHECK: @trailing_in_union0 = global %union.anon{{.*}} zeroinitializer, align 4 + +union { char a[]; } only_in_union = {}; +// CHECK: @only_in_union = global %union.anon{{.*}} zeroinitializer, align 1 + +union { char a[]; } only_in_union0 = {0}; +// CHECK: @only_in_union0 = global { [1 x i8] } zeroinitializer, align 1 + +union { char a[]; int b; } first_in_union = {}; +// CHECK: @first_in_union = global { [0 x i8], [4 x i8] } { [0 x i8] zeroinitializer, [4 x i8] undef }, align 4 + +union { char a[]; int b; } first_in_union0 = {}; +// CHECK: @first_in_union0 = global { [0 x i8], [4 x i8] } { [0 x i8] zeroinitializer, [4 x i8] undef }, align 4 hvdijk wrote: This is identical to the `first_in_union` test, I think you want ```suggestion union { char a[]; int b; } first_in_union0 = {0}; // CHECK: @first
[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)
hvdijk wrote: Flexible array initialization is, roughly, implemented as building a different type in which the flexible array member is replaced by an array of the right size, initializing that, and then pretending it was the original type. It does not surprise me too much that this does not work in constant expressions, that generally does not play well with any form of type punning, even otherwise well-defined type punning. https://github.com/llvm/llvm-project/pull/84428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)
hvdijk wrote: The problem with `union { char x[]; } x = {0};` is in `ConstStructBuilder::Build` ( `clang/lib/CodeGen/CGExprConstant.cpp`). It does: ```diff // If this is a union, skip all the fields that aren't being initialized. if (RD->isUnion() && !declaresSameEntity(ILE->getInitializedFieldInUnion(), Field)) continue; ``` But `ILE->getInitializedFieldInUnion()` returns `nullptr` so this skips all fields. `nullptr` is returned because `InitListChecker::CheckStructUnionTypes` never calls `StructuredList->setInitializedFieldInUnion`. If that gets called, then things work. I think things can be simplified a bit further: if we do ```diff diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 79cf2eed46fe..3fcdf9118468 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2332,7 +2332,7 @@ void InitListChecker::CheckStructUnionTypes( // We've already initialized a member of a union. We're done. if (InitializedSomething && RD->isUnion()) - break; + return; // If we've hit the flexible array member at the end, we're done. if (Field->getType()->isIncompleteArrayType()) ``` Then the tests still pass and we can remove or simplify some of the later checks for unions. https://github.com/llvm/llvm-project/pull/84428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)
@@ -1,13 +1,158 @@ -// RUN: %clang_cc1 %s -verify=c -fsyntax-only -// RUN: %clang_cc1 %s -verify -fsyntax-only -x c++ -// RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility -// RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility -x c++ +// RUN: %clang_cc1 %s -verify=stock,c -fsyntax-only +// RUN: %clang_cc1 %s -verify=stock,cpp -fsyntax-only -x c++ +// RUN: %clang_cc1 %s -verify=stock,cpp -fsyntax-only -fms-compatibility -x c++ +// RUN: %clang_cc1 %s -verify=stock,c,gnu -fsyntax-only -Wgnu-flexible-array-union-member -Wgnu-empty-struct +// RUN: %clang_cc1 %s -verify=stock,c,microsoft -fsyntax-only -fms-compatibility -Wmicrosoft // The test checks that an attempt to initialize union with flexible array // member with an initializer list doesn't crash clang. -union { char x[]; } r = {0}; // c-error {{flexible array member 'x' in a union is not allowed}} +union { char x[]; } r = {0}; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} +microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} + */ +struct _name1 { + int a; + union { +int b; +char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} + microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} + */ + }; +} name1 = { + 10, + 42,/* initializes "b" */ +}; -// expected-no-diagnostics +struct _name1i { + int a; + union { +int b; +char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} + microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} + */ + }; +} name1i = { + .a = 10, + .b = 42, +}; + +/* Initialization of flexible array in a union is never allowed. */ +struct _name2 { + int a; + union { +int b; +char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} + microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} + stock-note {{initialized flexible array member 'x' is here}} + */ + }; +} name2 = { + 12, + 13, + { 'c' }, /* stock-error {{initialization of flexible array member is not allowed}} */ hvdijk wrote: I think this is more than just a confusing error message. Consider `struct S { int a; union { int b; char x[]; }; int c; } s = {1, 2, 3};`. If `x` is given type `char[0]`, or `char[1]`, or `char[2]`, the `3` initializer applies to `s.c`. Yet inexplicably, if `x` has type `char[]`, the `3` initializer applies to `s.x` and any initializer is an error? That looks like a bug. We can even turn this into wrong-code: `struct S { int a; union { int b; char x[]; }; int c; int d; } s = {1, 2, {}, 3};`. This should initialise `a`, `b`, `c`, `d`, to `1`, `2`, `0`, `3`, but instead initialises them to `1`, `2`, `3`, `0`. https://github.com/llvm/llvm-project/pull/84428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)
@@ -1,13 +1,58 @@ -// RUN: %clang_cc1 %s -verify=c -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only // RUN: %clang_cc1 %s -verify -fsyntax-only -x c++ -// RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility // RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility -x c++ +// RUN: %clang_cc1 %s -verify=gnu -fsyntax-only -Wgnu-flexible-array-union-member -Wgnu-empty-struct +// RUN: %clang_cc1 %s -verify=microsoft -fsyntax-only -fms-compatibility -Wmicrosoft // The test checks that an attempt to initialize union with flexible array // member with an initializer list doesn't crash clang. -union { char x[]; } r = {0}; // c-error {{flexible array member 'x' in a union is not allowed}} +union { char x[]; } r = {0}; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} +microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} + */ hvdijk wrote: I do not see any obvious cases where the code does the wrong thing, sure, I agree with you on that, but as far as I can find, we do not have *any* test for "initialization of flexible array member is not allowed" being correctly emitted for nested unions containing flexible array members, either currently or after this PR. `flexible-array-init.c` contains tests for this for nested structs containing flexible array members, but not for unions. Previously, these would have implicitly been handled by flexible array members being disallowed in unions in the first place, at least for C, but as you are enabling them now, that no longer applies. https://github.com/llvm/llvm-project/pull/84428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)
@@ -1,13 +1,58 @@ -// RUN: %clang_cc1 %s -verify=c -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only // RUN: %clang_cc1 %s -verify -fsyntax-only -x c++ -// RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility // RUN: %clang_cc1 %s -verify -fsyntax-only -fms-compatibility -x c++ +// RUN: %clang_cc1 %s -verify=gnu -fsyntax-only -Wgnu-flexible-array-union-member -Wgnu-empty-struct +// RUN: %clang_cc1 %s -verify=microsoft -fsyntax-only -fms-compatibility -Wmicrosoft // The test checks that an attempt to initialize union with flexible array // member with an initializer list doesn't crash clang. -union { char x[]; } r = {0}; // c-error {{flexible array member 'x' in a union is not allowed}} +union { char x[]; } r = {0}; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} +microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} + */ hvdijk wrote: If this is no longer an error, and the primary use case of this is for unions that are members of other structures, what are the semantics for initialization of flexible array members in unions in other structures? Is this covered sufficiently by existing tests? https://github.com/llvm/llvm-project/pull/84428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[X86][clang] Lift _BitInt() supported max width." (PR #81175)
https://github.com/hvdijk closed https://github.com/llvm/llvm-project/pull/81175 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[X86][clang] Lift _BitInt() supported max width." (PR #81175)
hvdijk wrote: > I would really like to avoid Clang 18 being released in this broken state, if > possible, and I see no way short of a revert to realistically achieve that. It's too late for that now, it's out there, and it's now everybody else's problem regardless of what Clang does in the future. Because of that, this PR no longer serves its purpose. I cannot imagine that even a single user will be happy with this, but this is what you decided. So be it. https://github.com/llvm/llvm-project/pull/81175 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[X86][clang] Lift _BitInt() supported max width." (PR #81175)
hvdijk wrote: That would be nice, but that will take time, and I did wait months already before creating this PR. Leaving Clang in its current state until someone steps up to fix it, in my opinion, does a massive disservice to users. If code is written to use `_BitInt`, and it correctly uses configure or CMake checks to try to detect compiler support, and fall back to some other implementation if `_BitInt` is unavailable, such code would, with Clang, use the non-working implementation. In which case the configure or CMake check would end up amended to "and if Clang, don't bother". From experience, such checks remain for far too long after the original problem is fixed; leaving Clang in its current state, I suspect, ensures that once Clang behaves correctly, still `_BitInt` will not be used. I'm happy if someone is willing to step up to fix the implementation, but I am not able to do it, and I would really like to avoid Clang 18 being released in this broken state, if possible, and I see no way short of a revert to realistically achieve that. https://github.com/llvm/llvm-project/pull/81175 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[X86][clang] Lift _BitInt() supported max width." (PR #81175)
hvdijk wrote: > At least that shouldn't be a problem: LLVM has separate concepts of "store > size" and "alloc size" where only the latter rounds up to alignment. So `load > i129` is specified to access only 9 bytes, not 16 bytes. Sure, but when it appears inside a struct, the memory reserved is based on the alloc size, not the store size, see `StructLayout`. That applies even for a packed struct. https://github.com/llvm/llvm-project/pull/81175 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[X86][clang] Lift _BitInt() supported max width." (PR #81175)
hvdijk wrote: > It should be technically possible for Clang to give _BitInt(N) an alignment > that is independent from LLVM's alignment I'm not sure it's even technically possible: if loading a `_BitInt(129)` from memory should load 3 bytes, but it is translated to an LLVM IR load of `i129` that loads 4 bytes, then even if the last byte is ignored, simply attempting to load it may access memory out of bounds and crash the program. Storing `i129`, it would clobber the next byte of memory. https://github.com/llvm/llvm-project/pull/81175 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[X86][clang] Lift _BitInt() supported max width." (PR #81175)
hvdijk wrote: > I find your PR description very vague. Please be more specific about which > ICEs and miscompilations you are concerned about (godbolt please). Is this > _just_ about the open alignment question, or also something else? I linked to where one major example had already been provided, but let me put it in here as well. https://godbolt.org/z/4jTrW4fcP ``` clang++: /root/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp:759: void {anonymous}::CGRecordLowering::clipTailPadding(): Assertion `Prior->FD->hasAttr() && "should not have reused this field's tail padding"' failed. PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics 1. parser at end of file 2. :9:3: LLVM IR generation of declaration 'g' 3. :9:3: Generating code for declaration 'g' #0 0x0389ed98 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x389ed98) #1 0x0389ca7c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x389ca7c) #2 0x037e4f58 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0 #3 0x7f7cec242520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520) #4 0x7f7cec2969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc) #5 0x7f7cec242476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476) #6 0x7f7cec2287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3) #7 0x7f7cec22871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b) #8 0x7f7cec239e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96) #9 0x03baa784 (anonymous namespace)::CGRecordLowering::clipTailPadding() CGRecordLayoutBuilder.cpp:0:0 #10 0x03bb0253 (anonymous namespace)::CGRecordLowering::lower(bool) CGRecordLayoutBuilder.cpp:0:0 ``` Here's another: https://godbolt.org/z/eKahY86Yd ``` _BitInt(129) *f(_BitInt(129) *p) { return p + 1; } char *f(char *p) { return p + sizeof(_BitInt(129)); } ``` These should obviously produce identical code, but it results in ``` f(_BitInt(129)*):# @f(_BitInt(129)*) lea rax, [rdi + 32] ret f(char*): # @f(char*) lea rax, [rdi + 24] ret ``` The codegen is just completely broken, and the fact that it passes Clang's testing is simply due to the fact that we have close to zero tests that it works in any capacity. Note that this revert doesn't remove the support entirely, it only moves it back behind the same `-fexperimental-max-bitint-width=` option that was already there before. https://github.com/llvm/llvm-project/pull/81175 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[X86][clang] Lift _BitInt() supported max width." (PR #81175)
https://github.com/hvdijk created https://github.com/llvm/llvm-project/pull/81175 This reverts commit def720726b73e0d7ab139376ab3ea955f25f4d89. As noted in #60925 and in D86310, with the current implementation of `_BitInt` in Clang, we can have either a correct `__int128` implementation, or a correct `_BitInt(128)` implementation, but not both: having a correct `__int128` implementation results in a mostly-working `_BitInt(65-128)` type, but internal compiler errors and seriously wrong code for `_BitInt(129+)`. The currently specified ABI is not implementable on top of LLVM's integer types, and attempts to get the ABI changed to something we can implement have resulted in nothing, so I think the safest thing to do at this time is to make sure Clang reports this as an error in exactly the same way that it does for all other architectures. I think it was simply too soon to lift that restriction. cc @FreddyLeaf >From 7b8f198b3bb00ca0624e7de061a977e1d3b87c00 Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Thu, 8 Feb 2024 19:06:14 + Subject: [PATCH] Revert "[X86][clang] Lift _BitInt() supported max width." This reverts commit def720726b73e0d7ab139376ab3ea955f25f4d89. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Basic/Targets/X86.h | 6 -- clang/test/Analysis/bitint-no-crash.c | 5 ++--- clang/test/CodeGen/ext-int-cc.c | 16 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 32440ee64e3eb..a52e0c0112ba2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -239,6 +239,8 @@ AMDGPU Support X86 Support ^^^ +- Revert _BitInt() supported max width increase, which does not work properly. + Arm and AArch64 Support ^^^ diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index d2232c7d5275a..7010c1fbb5a4e 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -507,9 +507,6 @@ class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo { ArrayRef getTargetBuiltins() const override; bool hasBitIntType() const override { return true; } - size_t getMaxBitIntWidth() const override { -return llvm::IntegerType::MAX_INT_BITS; - } }; class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo @@ -820,9 +817,6 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo { ArrayRef getTargetBuiltins() const override; bool hasBitIntType() const override { return true; } - size_t getMaxBitIntWidth() const override { -return llvm::IntegerType::MAX_INT_BITS; - } }; // x86-64 Windows target diff --git a/clang/test/Analysis/bitint-no-crash.c b/clang/test/Analysis/bitint-no-crash.c index 0a367fa930dc9..aa9bd61e7e421 100644 --- a/clang/test/Analysis/bitint-no-crash.c +++ b/clang/test/Analysis/bitint-no-crash.c @@ -1,10 +1,9 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core \ // RUN: -analyzer-checker=debug.ExprInspection \ - // RUN: -triple x86_64-pc-linux-gnu \ + // RUN: -fexperimental-max-bitint-width=256 \ // RUN: -verify %s -// Don't crash when using _BitInt(). Pin to the x86_64 triple for now, -// since not all architectures support _BitInt() +// Don't crash when using _BitInt(). // expected-no-diagnostics _BitInt(256) a; _BitInt(129) b; diff --git a/clang/test/CodeGen/ext-int-cc.c b/clang/test/CodeGen/ext-int-cc.c index 001e866d34b45..b233285ea36da 100644 --- a/clang/test/CodeGen/ext-int-cc.c +++ b/clang/test/CodeGen/ext-int-cc.c @@ -131,10 +131,10 @@ void ParamPassing3(_BitInt(15) a, _BitInt(31) b) {} // are negated. This will give an error when a target does support larger // _BitInt widths to alert us to enable the test. void ParamPassing4(_BitInt(129) a) {} -// LIN64: define{{.*}} void @ParamPassing4(ptr byval(i129) align 8 %{{.+}}) -// WIN64: define dso_local void @ParamPassing4(ptr %{{.+}}) -// LIN32: define{{.*}} void @ParamPassing4(ptr %{{.+}}) -// WIN32: define dso_local void @ParamPassing4(ptr %{{.+}}) +// LIN64-NOT: define{{.*}} void @ParamPassing4(ptr byval(i129) align 8 %{{.+}}) +// WIN64-NOT: define dso_local void @ParamPassing4(ptr %{{.+}}) +// LIN32-NOT: define{{.*}} void @ParamPassing4(ptr %{{.+}}) +// WIN32-NOT: define dso_local void @ParamPassing4(ptr %{{.+}}) // NACL-NOT: define{{.*}} void @ParamPassing4(ptr byval(i129) align 8 %{{.+}}) // NVPTX64-NOT: define{{.*}} void @ParamPassing4(ptr byval(i129) align 8 %{{.+}}) // NVPTX-NOT: define{{.*}} void @ParamPassing4(ptr byval(i129) align 8 %{{.+}}) @@ -290,10 +290,10 @@ _BitInt(128) ReturnPassing4(void){} #if __BITINT_MAXWIDTH__ > 128 _BitInt(129) ReturnPassing5(void){} -// LIN64: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret -// WIN64: define dso_local void @ReturnPassing5(ptr dead_on_unwind noalias writable sret -// LIN32: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias wri
[clang] 6b86813 - [SYCL] Always set NoUnwind attribute for SYCL.
Author: Harald van Dijk Date: 2023-03-30T02:18:52+01:00 New Revision: 6b868139458d258c1ed4c0279e8f4374556c1c1e URL: https://github.com/llvm/llvm-project/commit/6b868139458d258c1ed4c0279e8f4374556c1c1e DIFF: https://github.com/llvm/llvm-project/commit/6b868139458d258c1ed4c0279e8f4374556c1c1e.diff LOG: [SYCL] Always set NoUnwind attribute for SYCL. Like CUDA and OpenCL, the SYCL specification says that throwing and catching exceptions in device functions is not supported, so this change extends the logic for adding the NoUnwind attribute to SYCL. The existing convergent.cpp test, which tests that the convergent attribute is added to functions by default, is renamed and reused to test that the nounwind attribute is added by default. This test now has -fexceptions added to it, which the driver adds by default as well. The obvious question here is why not simply change the driver to remove -fexceptions. This change follows the direction given by the TODO comment because removing -fexceptions would also disable the __EXCEPTIONS macro, which should reflect whether exceptions are enabled on the host, rather than on the device, to avoid conflicts in types shared between host and device. Reviewed By: bader Differential Revision: https://reviews.llvm.org/D147097 Added: clang/test/CodeGenSYCL/function-attrs.cpp Modified: clang/lib/CodeGen/CGCall.cpp Removed: clang/test/CodeGenSYCL/convergent.cpp diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index aaa5d4e70d7db..63296aeec5b9f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1971,10 +1971,9 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, } // TODO: NoUnwind attribute should be added for other GPU modes HIP, - // SYCL, OpenMP offload. AFAIK, none of them support exceptions in device - // code. + // OpenMP offload. AFAIK, neither of them support exceptions in device code. if ((getLangOpts().CUDA && getLangOpts().CUDAIsDevice) || - getLangOpts().OpenCL) { + getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) { FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); } diff --git a/clang/test/CodeGenSYCL/convergent.cpp b/clang/test/CodeGenSYCL/convergent.cpp deleted file mode 100644 index 779f1592da0e0..0 --- a/clang/test/CodeGenSYCL/convergent.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -disable-llvm-passes \ -// RUN: -triple spir64 -emit-llvm %s -o - | FileCheck %s - -// CHECK-DAG: Function Attrs: -// CHECK-DAG-SAME: convergent -// CHECK-DAG-NEXT: define void @_Z3foov -void foo() { - int a = 1; -} - -template -__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) { - kernelFunc(); -} - -int main() { - kernel_single_task([] { foo(); }); - return 0; -} diff --git a/clang/test/CodeGenSYCL/function-attrs.cpp b/clang/test/CodeGenSYCL/function-attrs.cpp new file mode 100644 index 0..8f5c0ea5c512c --- /dev/null +++ b/clang/test/CodeGenSYCL/function-attrs.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -disable-llvm-passes \ +// RUN: -triple spir64 -fexceptions -emit-llvm %s -o - | FileCheck %s + +int foo(); + +// CHECK: define dso_local spir_func void @_Z3barv() [[BAR:#[0-9]+]] +// CHECK: attributes [[BAR]] = +// CHECK-SAME: convergent +// CHECK-SAME: nounwind +void bar() { + int a = foo(); +} + +int foo() { + return 1; +} + +template +__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) { + kernelFunc(); +} + +int main() { + kernel_single_task([] { bar(); }); + return 0; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fed7be0 - Mark identifier prefixes as substitutable
Author: Harald van Dijk Date: 2022-05-02T18:07:47+01:00 New Revision: fed7be096f8ed5d70029acd712ac19ffc61e04e5 URL: https://github.com/llvm/llvm-project/commit/fed7be096f8ed5d70029acd712ac19ffc61e04e5 DIFF: https://github.com/llvm/llvm-project/commit/fed7be096f8ed5d70029acd712ac19ffc61e04e5.diff LOG: Mark identifier prefixes as substitutable The Itanium C++ ABI says prefixes are substitutable. For most prefixes we already handle this: the manglePrefix(const DeclContext *, bool) and manglePrefix(QualType) overloads explicitly handles substitutions or defer to functions that handle substitutions on their behalf. The manglePrefix(NestedNameSpecifier *) overload, however, is different and handles some cases implicitly, but not all. The Identifier case was not handled; this change adds handling for it, as well as a test case. Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D122663 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/LangOptions.h clang/lib/AST/ItaniumMangle.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenCXX/clang-abi-compat.cpp clang/test/CodeGenCXX/mangle.cpp Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 839a7035a94fd..855d1a6c41468 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -265,6 +265,10 @@ C++ Language Changes in Clang ``std::move_if_noexcept``, ``std::addressof``, and ``std::as_const``. These are now treated as compiler builtins and implemented directly, rather than instantiating the definition from the standard library. +- Fixed mangling of nested dependent names such as ``T::a::b``, where ``T`` is a + template parameter, to conform to the Itanium C++ ABI and be compatible with + GCC. This breaks binary compatibility with code compiled with earlier versions + of clang; use the ``-fclang-abi-compat=14`` option to get the old mangling. C++20 Feature Support ^ diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index eb4c7c4c7d93e..83b8c062aa65c 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -218,6 +218,10 @@ class LangOptions : public LangOptionsBase { /// This causes clang to not pack non-POD members of packed structs. Ver13, +/// Attempt to be ABI-compatible with code generated by Clang 14.0.x. +/// This causes clang to mangle dependent nested names incorrectly. +Ver14, + /// Conform to the underlying platform's C and C++ ABIs as closely /// as we can. Latest diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 75f072168858b..f72789da526c1 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -443,6 +443,7 @@ class CXXNameMangler { private: bool mangleSubstitution(const NamedDecl *ND); + bool mangleSubstitution(NestedNameSpecifier *NNS); bool mangleSubstitution(QualType T); bool mangleSubstitution(TemplateName Template); bool mangleSubstitution(uintptr_t Ptr); @@ -456,6 +457,11 @@ class CXXNameMangler { addSubstitution(reinterpret_cast(ND)); } + void addSubstitution(NestedNameSpecifier *NNS) { +NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + +addSubstitution(reinterpret_cast(NNS)); + } void addSubstitution(QualType T); void addSubstitution(TemplateName Template); void addSubstitution(uintptr_t Ptr); @@ -2036,12 +2042,21 @@ void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) { return; case NestedNameSpecifier::Identifier: +// Clang 14 and before did not consider this substitutable. +bool Clang14Compat = getASTContext().getLangOpts().getClangABICompat() <= + LangOptions::ClangABI::Ver14; +if (!Clang14Compat && mangleSubstitution(qualifier)) + return; + // Member expressions can have these without prefixes, but that // should end up in mangleUnresolvedPrefix instead. assert(qualifier->getPrefix()); manglePrefix(qualifier->getPrefix()); mangleSourceName(qualifier->getAsIdentifier()); + +if (!Clang14Compat) + addSubstitution(qualifier); return; } @@ -6009,6 +6024,14 @@ bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) { return mangleSubstitution(reinterpret_cast(ND)); } +bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) { + assert(NNS->getKind() == NestedNameSpecifier::Identifier && + "mangleSubstitution(NestedNameSpecifier *) is only used for " + "identifier nested name specifiers."); + NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS); + return mangleSubstitution(reinterpret_cast(NNS)); +} + /// Determine whether the given type has any qualifiers
[clang] 66ab856 - [Driver] Fix compiler-rt lookup for x32
Author: Harald van Dijk Date: 2021-07-15T20:52:25+01:00 New Revision: 66ab8568c485c4dd7461f1acf0e55cd4a7a3b4a0 URL: https://github.com/llvm/llvm-project/commit/66ab8568c485c4dd7461f1acf0e55cd4a7a3b4a0 DIFF: https://github.com/llvm/llvm-project/commit/66ab8568c485c4dd7461f1acf0e55cd4a7a3b4a0.diff LOG: [Driver] Fix compiler-rt lookup for x32 x86_64-linux-gnu and x86_64-linux-gnux32 use different ABIs and objects built for one cannot be used for the other. In order to build and use compiler-rt for x32, we need to treat x32 as a new arch there. This updates the driver to search using the new arch name. Reviewed By: glaubitz Differential Revision: https://reviews.llvm.org/D100148 Added: Modified: clang/lib/Driver/ToolChain.cpp clang/test/Driver/sanitizer-ld.c Removed: diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 5791805a6711b..63ddd2acbec15 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -383,6 +383,9 @@ static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid()) return "i686"; + if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32()) +return "x32"; + return llvm::Triple::getArchTypeName(TC.getArch()); } diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c index 46f8729e18676..5e89552345f67 100644 --- a/clang/test/Driver/sanitizer-ld.c +++ b/clang/test/Driver/sanitizer-ld.c @@ -284,28 +284,28 @@ // CHECK-MSAN-NO-LINK-RUNTIME-LINUX-NOT: libclang_rt.msan // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \ -// RUN: -target i386-unknown-linux -fuse-ld=ld \ +// RUN: -target x86_64-unknown-linux-gnux32 -fuse-ld=ld \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s // RUN: %clang -fsanitize=float-divide-by-zero %s -### -o %t.o 2>&1 \ -// RUN: -target i386-unknown-linux -fuse-ld=ld \ +// RUN: -target x86_64-unknown-linux-gnux32 -fuse-ld=ld \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \ -// RUN: -target i386-unknown-linux -fuse-ld=ld \ +// RUN: -target x86_64-unknown-linux-gnux32 -fuse-ld=ld \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: -static-libsan \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s // CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-LINUX-NOT: libclang_rt.asan // CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx -// CHECK-UBSAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone-i386.a" "--no-whole-archive" +// CHECK-UBSAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone-x32.a" "--no-whole-archive" // CHECK-UBSAN-LINUX-NOT: libclang_rt.asan // CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx // CHECK-UBSAN-LINUX-NOT: "-lstdc++" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 75521bd - [X32] Add Triple::isX32(), use it.
Author: Harald van Dijk Date: 2021-06-07T20:48:39+01:00 New Revision: 75521bd9d8d1e39b1a765a14d95c49291d2adde5 URL: https://github.com/llvm/llvm-project/commit/75521bd9d8d1e39b1a765a14d95c49291d2adde5 DIFF: https://github.com/llvm/llvm-project/commit/75521bd9d8d1e39b1a765a14d95c49291d2adde5.diff LOG: [X32] Add Triple::isX32(), use it. So far, support for x86_64-linux-gnux32 has been handled by explicit comparisons of Triple.getEnvironment() to GNUX32. This worked as long as x86_64-linux-gnux32 was the only X32 environment to worry about, but we now have x86_64-linux-muslx32 as well. To support this, this change adds an isX32() function and uses it. It replaces all checks for GNUX32 or MuslX32 by isX32(), except for the following: - Triple::isGNUEnvironment() and Triple::isMusl() are supposed to treat GNUX32 and MuslX32 differently. - computeTargetTriple() needs to be able to transform triples to add or remove X32 from the environment and needs to map GNU to GNUX32, and Musl to MuslX32. - getMultiarchTriple() completely lacks any Musl support and retains the explicit check for GNUX32 as it can only return x86_64-linux-gnux32. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D103777 Added: Modified: clang/lib/Basic/Targets/X86.h clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/Gnu.cpp clang/lib/Driver/ToolChains/Linux.cpp clang/test/Driver/linux-cross.cpp llvm/include/llvm/ADT/Triple.h llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp llvm/lib/Target/X86/X86AsmPrinter.cpp llvm/lib/Target/X86/X86RegisterInfo.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/x32-lea-1.ll Removed: diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 0ba2fd6ba024..7639ea835ebc 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -661,7 +661,7 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo { public: X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : X86TargetInfo(Triple, Opts) { -const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32; +const bool IsX32 = getTriple().isX32(); bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 287b21864154..cd2c8c9b1916 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -519,14 +519,21 @@ static llvm::Triple computeTargetTriple(const Driver &D, AT = Target.get64BitArchVariant().getArch(); if (Target.getEnvironment() == llvm::Triple::GNUX32) Target.setEnvironment(llvm::Triple::GNU); + else if (Target.getEnvironment() == llvm::Triple::MuslX32) +Target.setEnvironment(llvm::Triple::Musl); } else if (A->getOption().matches(options::OPT_mx32) && Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) { AT = llvm::Triple::x86_64; - Target.setEnvironment(llvm::Triple::GNUX32); + if (Target.getEnvironment() == llvm::Triple::Musl) +Target.setEnvironment(llvm::Triple::MuslX32); + else +Target.setEnvironment(llvm::Triple::GNUX32); } else if (A->getOption().matches(options::OPT_m32)) { AT = Target.get32BitArchVariant().getArch(); if (Target.getEnvironment() == llvm::Triple::GNUX32) Target.setEnvironment(llvm::Triple::GNU); + else if (Target.getEnvironment() == llvm::Triple::MuslX32) +Target.setEnvironment(llvm::Triple::Musl); } else if (A->getOption().matches(options::OPT_m16) && Target.get32BitArchVariant().getArch() == llvm::Triple::x86) { AT = llvm::Triple::x86; diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index a27841dc5985..517ba60e0b77 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -294,7 +294,7 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { case llvm::Triple::systemz: return "elf64_s390"; case llvm::Triple::x86_64: -if (T.getEnvironment() == llvm::Triple::GNUX32) +if (T.isX32()) return "elf32_x86_64"; return "elf_x86_64"; case llvm::Triple::ve: @@ -725,7 +725,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, CmdArgs.push_back("--32"); break; case llvm::Triple::x86_64: -if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32) +if (getToolChain().getTriple().isX32()) CmdArgs.push_back("--x32"); else
[clang-tools-extra] 7907c46 - Make clangd CompletionModel not depend on directory layout.
Author: Harald van Dijk Date: 2021-05-05T19:25:34+01:00 New Revision: 7907c46fe6195728fafd843b8c0fb19a3e68e9ad URL: https://github.com/llvm/llvm-project/commit/7907c46fe6195728fafd843b8c0fb19a3e68e9ad DIFF: https://github.com/llvm/llvm-project/commit/7907c46fe6195728fafd843b8c0fb19a3e68e9ad.diff LOG: Make clangd CompletionModel not depend on directory layout. The current code accounts for two possible layouts, but there is at least a third supported layout: clang-tools-extra may also be checked out as clang/tools/extra with the releases, which was not yet handled. Rather than treating that as a special case, use the location of CompletionModel.cmake to handle all three cases. This should address the problems that prompted D96787 and the problems that prompted the proposed revert D100625. Reviewed By: usaxena95 Differential Revision: https://reviews.llvm.org/D101851 Added: Modified: clang-tools-extra/clangd/quality/CompletionModel.cmake Removed: diff --git a/clang-tools-extra/clangd/quality/CompletionModel.cmake b/clang-tools-extra/clangd/quality/CompletionModel.cmake index 41bc2ed1890b0..dc0c0cde4dabb 100644 --- a/clang-tools-extra/clangd/quality/CompletionModel.cmake +++ b/clang-tools-extra/clangd/quality/CompletionModel.cmake @@ -4,8 +4,9 @@ # ${CMAKE_CURRENT_BINARY_DIR}. The generated header # will define a C++ class called ${cpp_class} - which may be a # namespace-qualified class name. +set(CLANGD_COMPLETION_MODEL_COMPILER ${CMAKE_CURRENT_LIST_DIR}/CompletionModelCodegen.py) function(gen_decision_forest model filename cpp_class) - set(model_compiler ${LLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR}/clangd/quality/CompletionModelCodegen.py) + set(model_compiler ${CLANGD_COMPLETION_MODEL_COMPILER}) set(output_dir ${CMAKE_CURRENT_BINARY_DIR}) set(header_file ${output_dir}/${filename}.h) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 1d463c2 - [Driver] Fix architecture triplets and search paths for Linux x32
Author: Harald van Dijk Date: 2021-04-01T09:47:56+01:00 New Revision: 1d463c2a386099597a8e2d26b9b964bc8fda8042 URL: https://github.com/llvm/llvm-project/commit/1d463c2a386099597a8e2d26b9b964bc8fda8042 DIFF: https://github.com/llvm/llvm-project/commit/1d463c2a386099597a8e2d26b9b964bc8fda8042.diff LOG: [Driver] Fix architecture triplets and search paths for Linux x32 Currently, support for the x32 ABI is handled as a multilib to the x86_64 target only. However, full self-hosting x32 systems treating it as a separate architecture with its own architecture triplets as well as search paths exist as well, in Debian's x32 port and elsewhere. This adds the missing architecture triplets and search paths so that clang can work as a native compiler on x32, and updates the tests so that they pass when using an x32 libdir suffix. Additionally, we would previously also assume that objects from any x86_64-linux-gnu GCC installation could be used to target x32. This changes the logic so that only GCC installations that include x32 support are used when targetting x32, meaning x86_64-linux-gnux32 GCC installations, and x86_64-linux-gnu and i686-linux-gnu GCC installations that include x32 multilib support. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D52050 Added: clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/10.2.0/crtbegin.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtbegin.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtbeginT.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/crtfastmath.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtbegin.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtbeginT.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/10.2.0/x32/crtfastmath.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/crtbegin.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/10.2.0/crtbegin.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbegin.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbeginT.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtfastmath.o clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/64/crtbegin.o clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/10.2.0/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/32/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/10.2.0/x32/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/32/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/10.2.0/x32/crtbegin.o Modified: clang/lib/Driver/ToolChains/Gnu.cpp clang/test/Driver/baremetal.cpp clang/test/Driver/cl-options.c clang/test/Driver/cross-linux.c clang/test/Driver/env.c clang/test/Driver/linux-ld.c clang/test/Preprocessor/iwithprefix.c Removed: clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/i386-unknown-linux-gnu/4.6.0/crtbegin.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtbegin.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtbeginT.o clang/test/Driver/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/crtfastmath.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/crtbegin.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/i686-unknown-linux/4.6.0/crtbegin.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbegin.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtbeginT.o clang/test/Driver/Inputs/basic_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/crtfastmath.o clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/64/crtbegin.o clang/test/Driver/Inputs/multilib_32bit_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32/crtbegin.o clang/test/Driver/Inputs/multilib_64bit_linux_
[clang] f453793 - Suppress non-conforming GNU paste extension in all standard-conforming modes
Author: Harald van Dijk Date: 2021-01-25T00:56:45Z New Revision: f4537935dcdbf390c863591cf556e76c3abab9c1 URL: https://github.com/llvm/llvm-project/commit/f4537935dcdbf390c863591cf556e76c3abab9c1 DIFF: https://github.com/llvm/llvm-project/commit/f4537935dcdbf390c863591cf556e76c3abab9c1.diff LOG: Suppress non-conforming GNU paste extension in all standard-conforming modes The GNU token paste extension that removes the comma in , ## __VA_ARGS__ conflicts with C99/C++11's requirements when a variadic macro has no named parameters: according to the standard, an invocation as FOO() gives it a single empty argument, and concatenation of anything with an empty argument is well-defined. For this reason, the GNU extension was already disabled in C99 standard-conforming mode. It was not yet disabled in C++11 standard-conforming mode. The associated comment suggested that GCC keeps this extension enabled in C90/C++03 standard-conforming mode, but it actually does not, so rather than adding a check for C++ language version, this change simply removes the check for C language version. Reviewed By: rsmith Differential Revision: https://reviews.llvm.org/D91913 Added: Modified: clang/lib/Lex/TokenLexer.cpp clang/test/Preprocessor/macro_fn_comma_swallow2.c Removed: diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index da5681aaf478..6e962dfa2c34 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -148,12 +148,11 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs( return false; // GCC removes the comma in the expansion of " ... , ## __VA_ARGS__ " if - // __VA_ARGS__ is empty, but not in strict C99 mode where there are no - // named arguments, where it remains. In all other modes, including C99 - // with GNU extensions, it is removed regardless of named arguments. + // __VA_ARGS__ is empty, but not in strict mode where there are no + // named arguments, where it remains. With GNU extensions, it is removed + // regardless of named arguments. // Microsoft also appears to support this extension, unofficially. - if (PP.getLangOpts().C99 && !PP.getLangOpts().GNUMode -&& Macro->getNumParams() < 2) + if (!PP.getLangOpts().GNUMode && Macro->getNumParams() < 2) return false; // Is a comma available to be removed? diff --git a/clang/test/Preprocessor/macro_fn_comma_swallow2.c b/clang/test/Preprocessor/macro_fn_comma_swallow2.c index 93ab2b83664a..89ef8c0579c4 100644 --- a/clang/test/Preprocessor/macro_fn_comma_swallow2.c +++ b/clang/test/Preprocessor/macro_fn_comma_swallow2.c @@ -1,9 +1,12 @@ // Test the __VA_ARGS__ comma swallowing extensions of various compiler dialects. // RUN: %clang_cc1 -E %s | FileCheck -check-prefix=GCC -strict-whitespace %s +// RUN: %clang_cc1 -E -std=c90 %s | FileCheck -check-prefix=C99 -strict-whitespace %s // RUN: %clang_cc1 -E -std=c99 %s | FileCheck -check-prefix=C99 -strict-whitespace %s // RUN: %clang_cc1 -E -std=c11 %s | FileCheck -check-prefix=C99 -strict-whitespace %s // RUN: %clang_cc1 -E -x c++ %s | FileCheck -check-prefix=GCC -strict-whitespace %s +// RUN: %clang_cc1 -E -x c++ -std=c++03 %s | FileCheck -check-prefix=C99 -strict-whitespace %s +// RUN: %clang_cc1 -E -x c++ -std=c++11 %s | FileCheck -check-prefix=C99 -strict-whitespace %s // RUN: %clang_cc1 -E -std=gnu99 %s | FileCheck -check-prefix=GCC -strict-whitespace %s // RUN: %clang_cc1 -E -fms-compatibility %s | FileCheck -check-prefix=MS -strict-whitespace %s // RUN: %clang_cc1 -E -DNAMED %s | FileCheck -check-prefix=GCC -strict-whitespace %s ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits