diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index ca619aa7e98a1..e6a59a2ae1306 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -64,13 +64,13 @@ cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \ start-group "ninja" -if [[ "${targets}" != "" ]]; then +if [[ -n "${targets}" ]]; then # Targets are not escaped as they are passed as separate arguments. ninja -C "${BUILD_DIR}" -k 0 ${targets} |& tee ninja.log cp ${BUILD_DIR}/.ninja_log ninja.ninja_log fi -if [[ "${runtime_targets}" != "" ]]; then +if [[ -n "${runtime_targets}" ]]; then start-group "ninja Runtimes" ninja -C "${BUILD_DIR}" ${runtime_targets} |& tee ninja_runtimes.log @@ -79,7 +79,7 @@ fi # Compiling runtimes with just-built Clang and running their tests # as an additional testing for Clang. -if [[ "${runtime_targets_needs_reconfig}" != "" ]]; then +if [[ -n "${runtime_targets_needs_reconfig}" ]]; then start-group "CMake Runtimes C++26" cmake \ diff --git a/.ci/monolithic-windows.sh b/.ci/monolithic-windows.sh index 99e7758ce8d79..36941644c6a6c 100755 --- a/.ci/monolithic-windows.sh +++ b/.ci/monolithic-windows.sh @@ -51,13 +51,13 @@ cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \ start-group "ninja" -if [[ "${targets}" != "" ]]; then +if [[ -n "${targets}" ]]; then # Targets are not escaped as they are passed as separate arguments. ninja -C "${BUILD_DIR}" -k 0 ${targets} |& tee ninja.log cp ${BUILD_DIR}/.ninja_log ninja.ninja_log fi -if [[ "${runtimes_targets}" != "" ]]; then +if [[ -n "${runtimes_targets}" ]]; then start-group "ninja runtimes" ninja -C "${BUILD_DIR}" -k 0 ${runtimes_targets} |& tee ninja_runtimes.log diff --git a/.ci/premerge_advisor_explain.py b/.ci/premerge_advisor_explain.py index 269f75cace266..69568895e9030 100644 --- a/.ci/premerge_advisor_explain.py +++ b/.ci/premerge_advisor_explain.py @@ -148,7 +148,7 @@ def main( # Skip looking for results on AArch64 for now because the premerge advisor # service is not available on AWS currently. - if platform.machine() == "arm64": + if platform.machine() == "arm64" or platform.machine() == "aarch64": sys.exit(0) main( diff --git a/.ci/premerge_advisor_upload.py b/.ci/premerge_advisor_upload.py index 9e14743c7cc07..86032a42e179d 100644 --- a/.ci/premerge_advisor_upload.py +++ b/.ci/premerge_advisor_upload.py @@ -59,7 +59,7 @@ def main(commit_sha, workflow_run_number, build_log_files): # Skip uploading results on AArch64 for now because the premerge advisor # service is not available on AWS currently. - if platform.machine() == "arm64": + if platform.machine() == "arm64" or platform.machine() == "aarch64": sys.exit(0) main(args.commit_sha, args.workflow_run_number, args.build_log_files) diff --git a/.ci/utils.sh b/.ci/utils.sh index c364f9395d67b..713a07ba5d898 100644 --- a/.ci/utils.sh +++ b/.ci/utils.sh @@ -33,7 +33,7 @@ function at-exit { # If building fails there will be no results files. shopt -s nullglob - if [[ "$GITHUB_ACTIONS" != "" ]]; then + if [[ -n "$GITHUB_ACTIONS" ]]; then python "${MONOREPO_ROOT}"/.ci/generate_test_report_github.py \ $retcode "${BUILD_DIR}"/test-results.*.xml "${MONOREPO_ROOT}"/ninja*.log \ >> $GITHUB_STEP_SUMMARY @@ -44,7 +44,7 @@ function at-exit { fi if [[ "$retcode" != "0" ]]; then - if [[ "$GITHUB_ACTIONS" != "" ]]; then + if [[ -n "$GITHUB_ACTIONS" ]]; then python "${MONOREPO_ROOT}"/.ci/premerge_advisor_upload.py \ $(git rev-parse HEAD~1) $GITHUB_RUN_NUMBER \ "${BUILD_DIR}"/test-results.*.xml "${MONOREPO_ROOT}"/ninja*.log @@ -59,10 +59,10 @@ trap at-exit EXIT function start-group { groupname=$1 - if [[ "$GITHUB_ACTIONS" != "" ]]; then + if [[ -n "$GITHUB_ACTIONS" ]]; then echo "::endgroup" echo "::group::$groupname" - elif [[ "$POSTCOMMIT_CI" != "" ]]; then + elif [[ -n "$POSTCOMMIT_CI" ]]; then echo "@@@$STEP@@@" else echo "Starting $groupname" @@ -73,6 +73,6 @@ export PIP_BREAK_SYSTEM_PACKAGES=1 pip install -q -r "${MONOREPO_ROOT}"/.ci/all_requirements.txt # The ARM64 builders run on AWS and don't have access to the GCS cache. -if [[ "$GITHUB_ACTIONS" != "" ]] && [[ "$RUNNER_ARCH" != "ARM64" ]]; then +if [[ -n "$GITHUB_ACTIONS" ]] && [[ "$RUNNER_ARCH" != "ARM64" ]]; then python .ci/cache_lit_timing_files.py download fi diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml index bb0eef5842b0f..efdc42d349195 100644 --- a/.github/new-prs-labeler.yml +++ b/.github/new-prs-labeler.yml @@ -1,1449 +1,1131 @@ BOLT: - - changed-files: - - any-glob-to-any-file: - - bolt/**/* + - bolt/**/* ClangIR: - - changed-files: - - any-glob-to-any-file: - - clang/include/clang/CIR/**/* - - clang/lib/CIR/**/* - - clang/tools/cir-*/**/* - - clang/test/CIR/**/* + - clang/include/clang/CIR/**/* + - clang/lib/CIR/**/* + - clang/tools/cir-*/**/* + - clang/test/CIR/**/* clang:bytecode: - - changed-files: - - any-glob-to-any-file: - - clang/docs/ConstantInterpreter.rst - - clang/lib/AST/ByteCode/**/* - - clang/test/AST/ByteCode/**/* - - clang/unittests/AST/ByteCode/**/* + - clang/docs/ConstantInterpreter.rst + - clang/lib/AST/ByteCode/**/* + - clang/test/AST/ByteCode/**/* + - clang/unittests/AST/ByteCode/**/* clang:dataflow: - - changed-files: - - any-glob-to-any-file: - - clang/include/clang/Analysis/FlowSensitive/**/* - - clang/lib/Analysis/FlowSensitive/**/* - - clang/unittests/Analysis/FlowSensitive/**/* - - clang/docs/DataFlowAnalysisIntro.md - - clang/docs/DataFlowAnalysisIntroImages/**/* + - clang/include/clang/Analysis/FlowSensitive/**/* + - clang/lib/Analysis/FlowSensitive/**/* + - clang/unittests/Analysis/FlowSensitive/**/* + - clang/docs/DataFlowAnalysisIntro.md + - clang/docs/DataFlowAnalysisIntroImages/**/* clang:frontend: - - changed-files: - - any-glob-to-any-file: - - clang/lib/AST/**/* - - clang/include/clang/AST/**/* - - clang/lib/Basic/**/* - - clang/include/clang/Basic/**/* - - clang/lib/Interpreter/**/* - - clang/include/clang/Interpreter/**/* - - clang/lib/Lex/**/* - - clang/include/clang/Lex/**/* - - clang/lib/Parse/**/* - - clang/include/clang/Parse/**/* - - clang/lib/Sema/**/* - - clang/include/clang/Sema/**/* + - clang/lib/AST/**/* + - clang/include/clang/AST/**/* + - clang/lib/Basic/**/* + - clang/include/clang/Basic/**/* + - clang/lib/Interpreter/**/* + - clang/include/clang/Interpreter/**/* + - clang/lib/Lex/**/* + - clang/include/clang/Lex/**/* + - clang/lib/Parse/**/* + - clang/include/clang/Parse/**/* + - clang/lib/Sema/**/* + - clang/include/clang/Sema/**/* clang:headers: - - changed-files: - - any-glob-to-any-file: - - clang/lib/Headers/**/* + - clang/lib/Headers/**/* compiler-rt: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/**/* + - compiler-rt/**/* flang: - - changed-files: - - any-glob-to-any-file: - - flang/**/* + - flang/**/* flang:frontend: - - changed-files: - - any-glob-to-any-file: - - flang/Parser/**/* - - flang/Evaluate/**/* - - flang/Semantics/**/* + - flang/Parser/**/* + - flang/Evaluate/**/* + - flang/Semantics/**/* libclc: - - changed-files: - - any-glob-to-any-file: - - libclc/** + - libclc/** HLSL: - - changed-files: - - any-glob-to-any-file: - - clang/*HLSL*/**/* - - clang/**/*HLSL* - - llvm/**/Frontend/HLSL/**/* + - clang/*HLSL*/**/* + - clang/**/*HLSL* + - llvm/**/Frontend/HLSL/**/* lld: - - changed-files: - - any-glob-to-any-file: - - lld/**/* + - lld/**/* llvm-lit: - - changed-files: - - any-glob-to-any-file: - - llvm/utils/lit/**/* + - llvm/utils/lit/**/* PGO: - - changed-files: - - any-glob-to-any-file: - - llvm/**/ProfileData/**/* - - llvm/**/SampleProfile* - - llvm/**/CodeGen/MIRSampleProfile* - - llvm/lib/Transforms/Instrumentation/CGProfile.cpp - - llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp - - llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp - - llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp - - llvm/lib/Transforms/Instrumentation/PGO* - - llvm/lib/Transforms/Instrumentation/ValueProfile* - - llvm/test/Instrumentation/InstrProfiling/**/* - - llvm/test/Transforms/PGOProfile/**/* - - llvm/test/Transforms/SampleProfile/**/* - - llvm/**/llvm-profdata/**/* - - llvm/**/llvm-profgen/**/* + - llvm/**/ProfileData/**/* + - llvm/**/SampleProfile* + - llvm/**/CodeGen/MIRSampleProfile* + - llvm/lib/Transforms/Instrumentation/CGProfile.cpp + - llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp + - llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp + - llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp + - llvm/lib/Transforms/Instrumentation/PGO* + - llvm/lib/Transforms/Instrumentation/ValueProfile* + - llvm/test/Instrumentation/InstrProfiling/**/* + - llvm/test/Transforms/PGOProfile/**/* + - llvm/test/Transforms/SampleProfile/**/* + - llvm/**/llvm-profdata/**/* + - llvm/**/llvm-profgen/**/* vectorizers: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Transforms/Vectorize/**/* - - llvm/include/llvm/Transforms/Vectorize/**/* + - llvm/lib/Transforms/Vectorize/**/* + - llvm/include/llvm/Transforms/Vectorize/**/* # IMPORTED FROM CODEOWNERS LTO: - - changed-files: - - any-glob-to-any-file: - - llvm/*/LTO/** - - llvm/*/Linker/** - - llvm/*/ThinLTO/** - - llvm/lib/Transforms/*/FunctionImport* - - llvm/tools/gold/** + - llvm/*/LTO/** + - llvm/*/Linker/** + - llvm/*/ThinLTO/** + - llvm/lib/Transforms/*/FunctionImport* + - llvm/tools/gold/** clang:driver: - - changed-files: - - any-glob-to-any-file: - - clang/*/Driver/** + - clang/*/Driver/** compiler-rt:asan: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/asan/** - - compiler-rt/include/sanitizer/asan_interface.h - - compiler-rt/test/asan/** - - compiler-rt/lib/asan_abi/** - - compiler-rt/test/asan_abi/** + - compiler-rt/lib/asan/** + - compiler-rt/include/sanitizer/asan_interface.h + - compiler-rt/test/asan/** + - compiler-rt/lib/asan_abi/** + - compiler-rt/test/asan_abi/** compiler-rt:builtins: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/builtins/** - - compiler-rt/test/builtins/** + - compiler-rt/lib/builtins/** + - compiler-rt/test/builtins/** compiler-rt:cfi: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/cfi/** - - compiler-rt/test/cfi/** + - compiler-rt/lib/cfi/** + - compiler-rt/test/cfi/** compiler-rt:fuzzer: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/fuzzer/** - - compiler-rt/include/fuzzer/** - - compiler-rt/test/fuzzer/** + - compiler-rt/lib/fuzzer/** + - compiler-rt/include/fuzzer/** + - compiler-rt/test/fuzzer/** compiler-rt:hwasan: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/hwasan/** - - compiler-rt/include/sanitizer/hwasan_interface.h - - compiler-rt/test/hwasan/** + - compiler-rt/lib/hwasan/** + - compiler-rt/include/sanitizer/hwasan_interface.h + - compiler-rt/test/hwasan/** compiler-rt:lsan: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/lsan/** - - compiler-rt/include/sanitizer/lsan_interface.h - - compiler-rt/test/lsan/** + - compiler-rt/lib/lsan/** + - compiler-rt/include/sanitizer/lsan_interface.h + - compiler-rt/test/lsan/** compiler-rt:msan: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/msan/** - - compiler-rt/include/sanitizer/msan_interface.h - - compiler-rt/test/msan/** + - compiler-rt/lib/msan/** + - compiler-rt/include/sanitizer/msan_interface.h + - compiler-rt/test/msan/** compiler-rt:sanitizer: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Transforms/Instrumentation/*Sanitizer* - - compiler-rt/lib/interception/** - - compiler-rt/lib/*san*/** - - compiler-rt/include/sanitizer/** - - compiler-rt/test/*san*/** - - compiler-rt/lib/fuzzer/** - - compiler-rt/include/fuzzer/** - - compiler-rt/test/fuzzer/** - - compiler-rt/lib/scudo/** - - compiler-rt/test/scudo/** + - llvm/lib/Transforms/Instrumentation/*Sanitizer* + - compiler-rt/lib/interception/** + - compiler-rt/lib/*san*/** + - compiler-rt/include/sanitizer/** + - compiler-rt/test/*san*/** + - compiler-rt/lib/fuzzer/** + - compiler-rt/include/fuzzer/** + - compiler-rt/test/fuzzer/** + - compiler-rt/lib/scudo/** + - compiler-rt/test/scudo/** compiler-rt:scudo: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/scudo/** - - compiler-rt/test/scudo/** + - compiler-rt/lib/scudo/** + - compiler-rt/test/scudo/** compiler-rt:tsan: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/tsan/** - - compiler-rt/include/sanitizer/tsan_interface.h - - compiler-rt/include/sanitizer/tsan_interface_atomic.h - - compiler-rt/test/tsan/** + - compiler-rt/lib/tsan/** + - compiler-rt/include/sanitizer/tsan_interface.h + - compiler-rt/include/sanitizer/tsan_interface_atomic.h + - compiler-rt/test/tsan/** compiler-rt:ubsan: - - changed-files: - - any-glob-to-any-file: - - compiler-rt/lib/ubsan/** - - compiler-rt/include/sanitizer/ubsan_interface.h - - compiler-rt/test/ubsan/** - - compiler-rt/lib/ubsan_minimal/** - - compiler-rt/test/ubsan_minimal/** + - compiler-rt/lib/ubsan/** + - compiler-rt/include/sanitizer/ubsan_interface.h + - compiler-rt/test/ubsan/** + - compiler-rt/lib/ubsan_minimal/** + - compiler-rt/test/ubsan_minimal/** xray: - - changed-files: - - any-glob-to-any-file: - - llvm/tools/llvm-xray/** - - compiler-rt/*/xray/** - - clang/include/clang/Basic/XRay* - - clang/lib/Basic/XRay* - - compiler-rt/*/xray/** - - llvm/include/llvm/XRay/** - - llvm/lib/XRay/** - - llvm/tools/llvm-xray/** - - llvm/unittests/XRay/** - - compiler-rt/*/xray/** + - llvm/tools/llvm-xray/** + - compiler-rt/*/xray/** + - clang/include/clang/Basic/XRay* + - clang/lib/Basic/XRay* + - compiler-rt/*/xray/** + - llvm/include/llvm/XRay/** + - llvm/lib/XRay/** + - llvm/tools/llvm-xray/** + - llvm/unittests/XRay/** + - compiler-rt/*/xray/** clang:codegen: - - changed-files: - - any-glob-to-any-file: - - clang/lib/CodeGen/** - - clang/include/clang/CodeGen/** + - clang/lib/CodeGen/** + - clang/include/clang/CodeGen/** mlir: - - changed-files: - - any-glob-to-any-file: - - mlir/** + - mlir/** mlir:core: - - changed-files: - - any-glob-to-any-file: - - mlir/include/mlir/Support/** - - mlir/lib/Support/** - - mlir/include/mlir/Parser/** - - mlir/lib/Parser/** - - mlir/include/mlir/IR/** - - mlir/lib/IR/** - - mlir/include/mlir/Bytecode/** - - mlir/lib/Bytecode/** - - mlir/include/mlir/AsmParser/** - - mlir/lib/AsmParser/** - - mlir/include/mlir/Pass/** - - mlir/lib/Pass/** - - mlir/include/mlir/Tools/** - - mlir/lib/Tools/** - - mlir/include/mlir/Reducer/** - - mlir/lib/Reducer/** - - mlir/include/mlir/Transforms/** - - mlir/lib/Transforms/** - - mlir/include/mlir/Debug/** - - mlir/lib/Debug/** - - mlir/tools/** + - mlir/include/mlir/Support/** + - mlir/lib/Support/** + - mlir/include/mlir/Parser/** + - mlir/lib/Parser/** + - mlir/include/mlir/IR/** + - mlir/lib/IR/** + - mlir/include/mlir/Bytecode/** + - mlir/lib/Bytecode/** + - mlir/include/mlir/AsmParser/** + - mlir/lib/AsmParser/** + - mlir/include/mlir/Pass/** + - mlir/lib/Pass/** + - mlir/include/mlir/Tools/** + - mlir/lib/Tools/** + - mlir/include/mlir/Reducer/** + - mlir/lib/Reducer/** + - mlir/include/mlir/Transforms/** + - mlir/lib/Transforms/** + - mlir/include/mlir/Debug/** + - mlir/lib/Debug/** + - mlir/tools/** mlir:ods: - - changed-files: - - any-glob-to-any-file: - - mlir/TableGen/** - - mlir/tblgen/** - - mlir/include/mlir/IR/*.td + - mlir/TableGen/** + - mlir/tblgen/** + - mlir/include/mlir/IR/*.td mlir:bindings: - - changed-files: - - any-glob-to-any-file: - - mlir/Bindings/** + - mlir/Bindings/** mlir:gpu: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*GPU*/** + - mlir/**/*GPU*/** mlir:amdgpu: - - changed-files: - - any-glob-to-any-file: - - mlir/**/AMDGPU/** + - mlir/**/AMDGPU/** mlir:amx: - - changed-files: - - any-glob-to-any-file: - - mlir/**/AMX/** + - mlir/**/AMX/** mlir:affine: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Affine/** + - mlir/**/Affine/** mlir:arith: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Arith/** + - mlir/**/Arith/** mlir:neon: - - changed-files: - - any-glob-to-any-file: - - mlir/**/ArmNeon/** + - mlir/**/ArmNeon/** mlir:sme: - - changed-files: - - any-glob-to-any-file: - - mlir/**/ArmSME/** + - mlir/**/ArmSME/** mlir:sve: - - changed-files: - - any-glob-to-any-file: - - mlir/**/ArmSVE/** + - mlir/**/ArmSVE/** mlir:async: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Async/** - - mlir/**/Async/** + - mlir/**/Async/** + - mlir/**/Async/** mlir:bufferization: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Bufferization/** + - mlir/**/Bufferization/** mlir:complex: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Complex/** + - mlir/**/Complex/** mlir:cf: - - changed-files: - - any-glob-to-any-file: - - mlir/**/ControlFlow/** + - mlir/**/ControlFlow/** mlir:dlti: - - changed-files: - - any-glob-to-any-file: - - mlir/**/DLTI/** + - mlir/**/DLTI/** mlir:emitc: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*EmitC*/** - - mlir/lib/Target/Cpp/** + - mlir/**/*EmitC*/** + - mlir/lib/Target/Cpp/** mlir:func: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Func/** + - mlir/**/Func/** mlir:irdl: - - changed-files: - - any-glob-to-any-file: - - mlir/**/IRDL/** + - mlir/**/IRDL/** mlir:index: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Index/** + - mlir/**/Index/** mlir:llvm: - - changed-files: - - any-glob-to-any-file: - - mlir/**/LLVM* - - mlir/**/LLVM*/** + - mlir/**/LLVM* + - mlir/**/LLVM*/** mlir:linalg: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*linalg/** - - mlir/**/*Linalg/** + - mlir/**/*linalg/** + - mlir/**/*Linalg/** mlir:mlprogram: - - changed-files: - - any-glob-to-any-file: - - mlir/**/MLProgram/** + - mlir/**/MLProgram/** mlir:math: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Math/** + - mlir/**/Math/** mlir:memref: - - changed-files: - - any-glob-to-any-file: - - mlir/**/MemRef/** + - mlir/**/MemRef/** mlir:nvgpu: - - changed-files: - - any-glob-to-any-file: - - mlir/**/NVGPU/** + - mlir/**/NVGPU/** mlir:openacc: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*OpenACC* - - mlir/**/*OpenACC*/** + - mlir/**/*OpenACC* + - mlir/**/*OpenACC*/** mlir:openmp: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*OpenMP* - - mlir/**/*OpenMP*/** + - mlir/**/*OpenMP* + - mlir/**/*OpenMP*/** mlir:pdl: - - changed-files: - - any-glob-to-any-file: - - mlir/**/PDL/** + - mlir/**/PDL/** mlir:quant: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Quant/** + - mlir/**/Quant/** mlir:scf: - - changed-files: - - any-glob-to-any-file: - - mlir/**/SCF/** + - mlir/**/SCF/** mlir:spirv: - - changed-files: - - any-glob-to-any-file: - - mlir/**/SPIRV/** - - mlir/**/SPIRVTo*/** - - mlir/**/*ToSPIRV/** - - mlir/tools/mlir-spirv-cpu-runner/** - - mlir/tools/mlir-vulkan-runner/** - - mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp + - mlir/**/SPIRV/** + - mlir/**/SPIRVTo*/** + - mlir/**/*ToSPIRV/** + - mlir/tools/mlir-spirv-cpu-runner/** + - mlir/tools/mlir-vulkan-runner/** + - mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp mlir:shape: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Shape/** + - mlir/**/Shape/** mlir:sparse: - - changed-files: - - any-glob-to-any-file: - - mlir/**/SparseTensor/** + - mlir/**/SparseTensor/** mlir:tensor: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Tensor/** + - mlir/**/Tensor/** mlir:tosa: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*Tosa*/** + - mlir/**/*Tosa*/** mlir:ub: - - changed-files: - - any-glob-to-any-file: - - mlir/**/UB/** + - mlir/**/UB/** mlir:vector: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*Vector/** + - mlir/**/*Vector/** mlir:execution-engine: - - changed-files: - - any-glob-to-any-file: - - mlir/**/ExecutionEngine/** + - mlir/**/ExecutionEngine/** mlir:presburger: - - changed-files: - - any-glob-to-any-file: - - mlir/**/*Presburger*/** + - mlir/**/*Presburger*/** mlir:python: - - changed-files: - - any-glob-to-any-file: - - mlir/python/**/* + - mlir/python/**/* mlir:vectorops: - - changed-files: - - any-glob-to-any-file: - - mlir/**/Vector/**/* + - mlir/**/Vector/**/* coroutines: - - changed-files: - - any-glob-to-any-file: - - clang/docs/DebuggingCoroutines.rst - - clang/lib/Sema/SemaCoroutine.cpp - - clang/lib/CodeGen/CGCoroutine.cpp - - clang/test/CodeGenCoroutines/** - - llvm/docs/Coroutines.rst - - llvm/include/llvm/Transforms/Coroutines/** - - llvm/lib/Transforms/Coroutines/** - - llvm/test/Transforms/Coroutines/* + - clang/docs/DebuggingCoroutines.rst + - clang/lib/Sema/SemaCoroutine.cpp + - clang/lib/CodeGen/CGCoroutine.cpp + - clang/test/CodeGenCoroutines/** + - llvm/docs/Coroutines.rst + - llvm/include/llvm/Transforms/Coroutines/** + - llvm/lib/Transforms/Coroutines/** + - llvm/test/Transforms/Coroutines/* clang:modules: - - changed-files: - - any-glob-to-any-file: - - clang/docs/StandardCPlusPlusModules.rst - - clang/include/clang/AST/AbstractBasicReader.h - - clang/include/clang/AST/AbstractBasicWriter.h - - clang/include/clang/AST/AbstractTypeReader.h - - clang/include/clang/AST/AbstractTypeWriter.h - - clang/include/clang/AST/PropertiesBase.td - - clang/include/clang/AST/ODRHash.h - - clang/include/clang/AST/TypeProperties.td - - clang/include/clang/Basic/Module.h - - clang/include/clang/Frontend/PrecompiledPreamble.h - - clang/include/clang/Lex/ModuleLoader.h - - clang/include/clang/Lex/ModuleMap.h - - clang/include/clang/Serialization/** - - clang/lib/AST/ODRHash.cpp - - clang/lib/AST/StmtProfile.cpp - - clang/lib/Basic/Module.cpp - - clang/lib/Frontend/ModuleDependencyCollector.cpp - - clang/lib/Frontend/PrecompiledPreamble.cpp - - clang/lib/Lex/ModuleMap.cpp - - clang/lib/Sema/SemaModule.cpp - - clang/lib/Serialization/** - - clang/test/CXX/module/** - - clang/test/Modules/** - - clang/unittests/Serialization/* + - clang/docs/StandardCPlusPlusModules.rst + - clang/include/clang/AST/AbstractBasicReader.h + - clang/include/clang/AST/AbstractBasicWriter.h + - clang/include/clang/AST/AbstractTypeReader.h + - clang/include/clang/AST/AbstractTypeWriter.h + - clang/include/clang/AST/PropertiesBase.td + - clang/include/clang/AST/ODRHash.h + - clang/include/clang/AST/TypeProperties.td + - clang/include/clang/Basic/Module.h + - clang/include/clang/Frontend/PrecompiledPreamble.h + - clang/include/clang/Lex/ModuleLoader.h + - clang/include/clang/Lex/ModuleMap.h + - clang/include/clang/Serialization/** + - clang/lib/AST/ODRHash.cpp + - clang/lib/AST/StmtProfile.cpp + - clang/lib/Basic/Module.cpp + - clang/lib/Frontend/ModuleDependencyCollector.cpp + - clang/lib/Frontend/PrecompiledPreamble.cpp + - clang/lib/Lex/ModuleMap.cpp + - clang/lib/Sema/SemaModule.cpp + - clang/lib/Serialization/** + - clang/test/CXX/module/** + - clang/test/Modules/** + - clang/unittests/Serialization/* clang-tidy: - - changed-files: - - any-glob-to-any-file: - - clang-tools-extra/clang-tidy/** - - clang-tools-extra/docs/clang-tidy/** - - clang-tools-extra/test/clang-tidy/** + - clang-tools-extra/clang-tidy/** + - clang-tools-extra/docs/clang-tidy/** + - clang-tools-extra/test/clang-tidy/** clang-tools-extra: - - changed-files: - - any-glob-to-any-file: - - clang-tools-extra/** + - clang-tools-extra/** tools:llvm-mca: - - changed-files: - - any-glob-to-any-file: - - llvm/tools/llvm-mca/** - - llvm/include/llvm/MCA/** - - llvm/lib/MCA/** + - llvm/tools/llvm-mca/** + - llvm/include/llvm/MCA/** + - llvm/lib/MCA/** clang: - - changed-files: - - all-globs-to-all-file: - - clang/** - - '!clang/**/Format/**' - - '!clang/tools/clang-format/**' + - any: + - clang/** + - '!clang/**/Format/**' + - '!clang/tools/clang-format/**' testing-tools: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/FileCheck/** - - llvm/lib/FileCheck/** - - llvm/test/FileCheck/** - - llvm/unittests/FileCheck/** - - llvm/utils/lit/** - - llvm/utils/split-file/** - - llvm/utils/not/** - - llvm/utils/count/** - - llvm/utils/FileCheck/** - - llvm/docs/CommandGuide/FileCheck.rst - - llvm/docs/CommandGuide/lit.rst - - llvm/docs/TestingGuide.rst - - llvm/test/Other/FileCheck-space.txt - - llvm/utils/UpdateTestChecks/** - - llvm/utils/update*_test_checks.py + - llvm/include/llvm/FileCheck/** + - llvm/lib/FileCheck/** + - llvm/test/FileCheck/** + - llvm/unittests/FileCheck/** + - llvm/utils/lit/** + - llvm/utils/split-file/** + - llvm/utils/not/** + - llvm/utils/count/** + - llvm/utils/FileCheck/** + - llvm/docs/CommandGuide/FileCheck.rst + - llvm/docs/CommandGuide/lit.rst + - llvm/docs/TestingGuide.rst + - llvm/test/Other/FileCheck-space.txt + - llvm/utils/UpdateTestChecks/** + - llvm/utils/update*_test_checks.py debuginfo: - - changed-files: - - any-glob-to-any-file: - - clang/lib/CodeGen/CGDebugInfo.* - - llvm/include/llvm/BinaryFormat/Dwarf.* - - llvm/include/llvm/CodeGen/*Debug*.* - - llvm/include/llvm/DebugInfo/** - - llvm/include/llvm/Debuginfod/** - - llvm/include/llvm/Frontend/Debug/** - - llvm/include/llvm/IR/Debug*.* - - llvm/include/llvm/Object/*Debug*.* - - llvm/include/llvm/ObjectYAML/*Debug*.* - - llvm/include/llvm/Transforms/Utils/*Debug*.* - - llvm/include/llvm-c/DebugInfo.h - - llvm/lib/BinaryFormat/Dwarf.cpp - - llvm/lib/CodeGen/AsmPrinter/*Debug*.* - - llvm/lib/CodeGen/AsmPrinter/Dwarf*.* - - llvm/lib/CodeGen/AsmPrinter/DIE*.* - - llvm/lib/CodeGen/LiveDebugValues/** - - llvm/lib/CodeGen/*Debug*.* - - llvm/lib/CodeGen/DwarfEHPrepare.cpp - - llvm/lib/DebugInfo/** - - llvm/lib/Debuginfod/** - - llvm/lib/DWARFLinkerParallel/** - - llvm/lib/IR/Debug*.cpp - - llvm/lib/MC/MCDwarf.cpp - - llvm/lib/Transforms/Utils/*Debug*.* - - llvm/test/DebugInfo/** - - llvm/test/tools/dsymutil/** - - llvm/test/tools/llvm-debuginfo-analyzer/** - - llvm/test/tools/llvm-debuginfod/** - - llvm/test/tools/llvm-debuginfod-find/** - - llvm/test/tools/llvm-dwarfdump/** - - llvm/test/tools/llvm-dwarfutil/** - - llvm/test/tools/llvm-dwp/** - - llvm/test/tools/llvm-gsymutil/** - - llvm/test/tools/llvm-pdbuti/** - - llvm/tools/dsymutil/** - - llvm/tools/llvm-debuginfo-analyzer/** - - llvm/tools/llvm-debuginfod/** - - llvm/tools/llvm-debuginfod-find/** - - llvm/tools/llvm-dwarfdump/** - - llvm/tools/llvm-dwarfutil/** - - llvm/tools/llvm-dwp/** - - llvm/tools/llvm-gsymutil/** - - llvm/tools/llvm-pdbutil/** + - clang/lib/CodeGen/CGDebugInfo.* + - llvm/include/llvm/BinaryFormat/Dwarf.* + - llvm/include/llvm/CodeGen/*Debug*.* + - llvm/include/llvm/DebugInfo/** + - llvm/include/llvm/Debuginfod/** + - llvm/include/llvm/Frontend/Debug/** + - llvm/include/llvm/IR/Debug*.* + - llvm/include/llvm/Object/*Debug*.* + - llvm/include/llvm/ObjectYAML/*Debug*.* + - llvm/include/llvm/Transforms/Utils/*Debug*.* + - llvm/include/llvm-c/DebugInfo.h + - llvm/lib/BinaryFormat/Dwarf.cpp + - llvm/lib/CodeGen/AsmPrinter/*Debug*.* + - llvm/lib/CodeGen/AsmPrinter/Dwarf*.* + - llvm/lib/CodeGen/AsmPrinter/DIE*.* + - llvm/lib/CodeGen/LiveDebugValues/** + - llvm/lib/CodeGen/*Debug*.* + - llvm/lib/CodeGen/DwarfEHPrepare.cpp + - llvm/lib/DebugInfo/** + - llvm/lib/Debuginfod/** + - llvm/lib/DWARFLinkerParallel/** + - llvm/lib/IR/Debug*.cpp + - llvm/lib/MC/MCDwarf.cpp + - llvm/lib/Transforms/Utils/*Debug*.* + - llvm/test/DebugInfo/** + - llvm/test/tools/dsymutil/** + - llvm/test/tools/llvm-debuginfo-analyzer/** + - llvm/test/tools/llvm-debuginfod/** + - llvm/test/tools/llvm-debuginfod-find/** + - llvm/test/tools/llvm-dwarfdump/** + - llvm/test/tools/llvm-dwarfutil/** + - llvm/test/tools/llvm-dwp/** + - llvm/test/tools/llvm-gsymutil/** + - llvm/test/tools/llvm-pdbuti/** + - llvm/tools/dsymutil/** + - llvm/tools/llvm-debuginfo-analyzer/** + - llvm/tools/llvm-debuginfod/** + - llvm/tools/llvm-debuginfod-find/** + - llvm/tools/llvm-dwarfdump/** + - llvm/tools/llvm-dwarfutil/** + - llvm/tools/llvm-dwp/** + - llvm/tools/llvm-gsymutil/** + - llvm/tools/llvm-pdbutil/** github:workflow: - - changed-files: - - any-glob-to-any-file: - - .github/workflows/** + - .github/workflows/** cmake: - - changed-files: - - any-glob-to-any-file: - - cmake/** - - llvm/cmake/** - - runtimes/** + - cmake/** + - llvm/cmake/** + - runtimes/** flang:driver: - - changed-files: - - any-glob-to-any-file: - - flang/tools/flang-driver/** - - flang/unittests/Frontend/** - - flang/lib/FrontendTool/** - - flang/lib/Frontend/** - - flang/include/flang/Frontend/** - - flang/include/flang/FrontendTool/** - - flang/test/Driver/** + - flang/tools/flang-driver/** + - flang/unittests/Frontend/** + - flang/lib/FrontendTool/** + - flang/lib/Frontend/** + - flang/include/flang/Frontend/** + - flang/include/flang/FrontendTool/** + - flang/test/Driver/** backend:m68k: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Target/M68k/** - - clang/lib/Basic/Targets/M68k.* - - clang/lib/CodeGen/Targets/M68k.cpp - - llvm/test/CodeGen/M68k/** - - llvm/test/MC/Disassembler/M68k/** - - llvm/test/MC/M68k/** + - llvm/lib/Target/M68k/** + - clang/lib/Basic/Targets/M68k.* + - clang/lib/CodeGen/Targets/M68k.cpp + - llvm/test/CodeGen/M68k/** + - llvm/test/MC/Disassembler/M68k/** + - llvm/test/MC/M68k/** libc++: - - changed-files: - - any-glob-to-any-file: - - libcxx/** - - .github/workflows/libcxx-* + - libcxx/** + - .github/workflows/libcxx-* libc++abi: - - changed-files: - - any-glob-to-any-file: - - libcxxabi/** + - libcxxabi/** libunwind: - - changed-files: - - any-glob-to-any-file: - - libunwind/** + - libunwind/** objectyaml: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/ObjectYAML/** - - llvm/lib/ObjectYAML/** - - llvm/test/tools/obj2yaml/** - - llvm/test/tools/yaml2obj/** - - llvm/tools/obj2yaml/** - - llvm/tools/yaml2obj/** + - llvm/include/llvm/ObjectYAML/** + - llvm/lib/ObjectYAML/** + - llvm/test/tools/obj2yaml/** + - llvm/test/tools/yaml2obj/** + - llvm/tools/obj2yaml/** + - llvm/tools/yaml2obj/** clang:analysis: - - changed-files: - - any-glob-to-any-file: - - clang/include/clang/Analysis/** - - clang/lib/Analysis/** + - clang/include/clang/Analysis/** + - clang/lib/Analysis/** clang:static analyzer: - - changed-files: - - any-glob-to-any-file: - - clang/include/clang/StaticAnalyzer/** - - clang/lib/StaticAnalyzer/** - - clang/tools/scan-build/** - - clang/utils/analyzer/** - - clang/docs/analyzer/** - - clang/test/Analysis/** + - clang/include/clang/StaticAnalyzer/** + - clang/lib/StaticAnalyzer/** + - clang/tools/scan-build/** + - clang/utils/analyzer/** + - clang/docs/analyzer/** + - clang/test/Analysis/** pgo: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Transforms/Instrumentation/CGProfile.cpp - - llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp - - llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp - - llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp - - llvm/lib/Transforms/Instrumentation/PGO* - - llvm/lib/Transforms/Instrumentation/ValueProfile* - - llvm/test/Instrumentation/InstrProfiling/** - - llvm/test/Transforms/PGOProfile/** - - compiler-rt/lib/profile/** - - compiler-rt/lib/memprof/** - - compiler-rt/test/profile/** - - compiler-rt/test/memprof/** - - llvm/tools/llvm-profdata/** - - llvm/tools/llvm-profgen/** - - llvm/test/tools/llvm-profdata/** - - llvm/test/tools/llvm-profgen/** - - llvm/unittests/ProfileData/* + - llvm/lib/Transforms/Instrumentation/CGProfile.cpp + - llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp + - llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp + - llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp + - llvm/lib/Transforms/Instrumentation/PGO* + - llvm/lib/Transforms/Instrumentation/ValueProfile* + - llvm/test/Instrumentation/InstrProfiling/** + - llvm/test/Transforms/PGOProfile/** + - compiler-rt/lib/profile/** + - compiler-rt/lib/memprof/** + - compiler-rt/test/profile/** + - compiler-rt/test/memprof/** + - llvm/tools/llvm-profdata/** + - llvm/tools/llvm-profgen/** + - llvm/test/tools/llvm-profdata/** + - llvm/test/tools/llvm-profgen/** + - llvm/unittests/ProfileData/* openacc: - - changed-files: - - any-glob-to-any-file: - - flang/**/OpenACC/** - - flang/include/flang/Lower/OpenACC.h - - flang/docs/OpenACC.md - - flang/lib/Parser/openacc-parsers.cpp - - flang/lib/Lower/OpenACC.cpp - - llvm/**/Frontend/OpenACC/** - - llvm/unittests/Frontend/OpenACCTest.cpp - - mlir/test/Target/LLVMIR/openacc-llvm.mlir - - mlir/**/*OpenACC/** + - flang/**/OpenACC/** + - flang/include/flang/Lower/OpenACC.h + - flang/docs/OpenACC.md + - flang/lib/Parser/openacc-parsers.cpp + - flang/lib/Lower/OpenACC.cpp + - llvm/**/Frontend/OpenACC/** + - llvm/unittests/Frontend/OpenACCTest.cpp + - mlir/test/Target/LLVMIR/openacc-llvm.mlir + - mlir/**/*OpenACC/** flang:runtime: - - changed-files: - - any-glob-to-any-file: - - flang/runtime/** + - flang/runtime/** flang:parser: - - changed-files: - - any-glob-to-any-file: - - flang/**/Parser/** + - flang/**/Parser/** flang:semantics: - - changed-files: - - any-glob-to-any-file: - - flang/**/Evaluate/** - - flang/**/Semantics/** + - flang/**/Evaluate/** + - flang/**/Semantics/** flang:fir-hlfir: - - changed-files: - - any-glob-to-any-file: - - flang/**/Lower/** - - flang/**/Optimizer/** + - flang/**/Lower/** + - flang/**/Optimizer/** flang:codegen: - - changed-files: - - any-glob-to-any-file: - - flang/**/CodeGen/** + - flang/**/CodeGen/** llvm:codegen: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/CodeGen/* - - llvm/lib/CodeGen/MIRParser/* - - llvm/lib/CodeGen/LiveDebugValues/* - - llvm/lib/CodeGen/AsmPrinter/* + - llvm/lib/CodeGen/* + - llvm/lib/CodeGen/MIRParser/* + - llvm/lib/CodeGen/LiveDebugValues/* + - llvm/lib/CodeGen/AsmPrinter/* llvm:globalisel: - - changed-files: - - any-glob-to-any-file: - - llvm/**/GlobalISel/** - - llvm/utils/TableGen/GlobalISel* + - llvm/**/GlobalISel/** + - llvm/utils/TableGen/GlobalISel* function-specialization: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/Transforms/Utils/SCCPSolver.h - - llvm/lib/Transforms/Utils/SCCPSolver.cpp - - llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h - - llvm/lib/Transforms/IPO/FunctionSpecialization.cpp - - llvm/test/Transforms/FunctionSpecialization/* + - llvm/include/llvm/Transforms/Utils/SCCPSolver.h + - llvm/lib/Transforms/Utils/SCCPSolver.cpp + - llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h + - llvm/lib/Transforms/IPO/FunctionSpecialization.cpp + - llvm/test/Transforms/FunctionSpecialization/* libc: - - changed-files: - - any-glob-to-any-file: - - libc/** - - utils/bazel/llvm-project-overlay/libc/** + - libc/** + - utils/bazel/llvm-project-overlay/libc/** clang-format: - - changed-files: - - any-glob-to-any-file: - - clang/**/Format/** - - clang/tools/clang-format/** + - clang/**/Format/** + - clang/tools/clang-format/** flang:openmp: - - changed-files: - - any-glob-to-any-file: - - flang/test/**/OpenMP/** - - flang/lib/Lower/OpenMP.cpp - - flang/lib/Semantics/resolve-directives.cpp - - flang/lib/Semantics/check-omp-structure.cpp - - flang/lib/Optimizer/Transforms/OMP* - - flang/test/Fir/convert-to-llvm-openmp-and-fir.fir - - flang/test/Lower/OpenMP/** - - flang/test/Transforms/omp* - - mlir/**/*OpenMP* - - mlir/test/Target/LLVMIR/openmp* - - llvm/lib/Frontend/OpenMP/** - - llvm/include/llvm/Frontend/OpenMP/** - - llvm/unittests/Frontend/OpenMP* + - flang/test/**/OpenMP/** + - flang/lib/Lower/OpenMP.cpp + - flang/lib/Semantics/resolve-directives.cpp + - flang/lib/Semantics/check-omp-structure.cpp + - flang/lib/Optimizer/Transforms/OMP* + - flang/test/Fir/convert-to-llvm-openmp-and-fir.fir + - flang/test/Lower/OpenMP/** + - flang/test/Transforms/omp* + - mlir/**/*OpenMP* + - mlir/test/Target/LLVMIR/openmp* + - llvm/lib/Frontend/OpenMP/** + - llvm/include/llvm/Frontend/OpenMP/** + - llvm/unittests/Frontend/OpenMP* llvm:ir: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/IR/** - - llvm/include/llvm/IR/** - - llvm/docs/LangRef.rst - - llvm/unittests/IR/** + - llvm/lib/IR/** + - llvm/include/llvm/IR/** + - llvm/docs/LangRef.rst + - llvm/unittests/IR/** llvm:SandboxIR: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/SandboxIR/** - - llvm/include/llvm/SandboxIR/** - - llvm/docs/SandboxIR.md - - llvm/unittests/SandboxIR/** + - llvm/lib/SandboxIR/** + - llvm/include/llvm/SandboxIR/** + - llvm/docs/SandboxIR.md + - llvm/unittests/SandboxIR/** llvm:analysis: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Analysis/** - - llvm/include/llvm/Analysis/** - - llvm/test/Analysis/** - - llvm/unittests/Analysis/** + - llvm/lib/Analysis/** + - llvm/include/llvm/Analysis/** + - llvm/test/Analysis/** + - llvm/unittests/Analysis/** llvm:adt: - - changed-files: - - any-glob-to-any-file: - - llvm/**/ADT/* + - llvm/**/ADT/* llvm:support: - - changed-files: - - any-glob-to-any-file: - - llvm/**/Support/** + - llvm/**/Support/** # Skip llvm/test/MC and llvm/unittests/MC, which includes target-specific directories. llvm:mc: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/MC/** - - llvm/lib/MC/** - - llvm/tools/llvm-mc/** + - llvm/include/llvm/MC/** + - llvm/lib/MC/** + - llvm/tools/llvm-mc/** llvm:transforms: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Transforms/** - - llvm/include/llvm/Transforms/** - - llvm/test/Transforms/** - - llvm/unittests/Transforms/** + - llvm/lib/Transforms/** + - llvm/include/llvm/Transforms/** + - llvm/test/Transforms/** + - llvm/unittests/Transforms/** llvm:instcombine: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Analysis/InstructionSimplify.cpp - - llvm/lib/Transforms/InstCombine/** - - llvm/include/llvm/Transforms/InstCombine/ - - llvm/include/llvm/Analysis/InstructionSimplify.h - - llvm/test/Transforms/InstCombine/** - - llvm/test/Transforms/InstSimplify/** + - llvm/lib/Analysis/InstructionSimplify.cpp + - llvm/lib/Transforms/InstCombine/** + - llvm/include/llvm/Transforms/InstCombine/ + - llvm/include/llvm/Analysis/InstructionSimplify.h + - llvm/test/Transforms/InstCombine/** + - llvm/test/Transforms/InstSimplify/** llvm:vectorcombine: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Transforms/Vectorize/VectorCombine.cpp - - llvm/test/Transforms/VectorCombine/** + - llvm/lib/Transforms/Vectorize/VectorCombine.cpp + - llvm/test/Transforms/VectorCombine/** clangd: - - changed-files: - - any-glob-to-any-file: - - clang-tools-extra/clangd/** + - clang-tools-extra/clangd/** hlsl: - - changed-files: - - any-glob-to-any-file: - - clang/test/ParserHLSL/** - - clang/test/SemaHLSL/** - - clang/test/AST/HLSL/** - - clang/test/CodeGenHLSL/** - - clang/cmake/caches/HLSL.cmake - - clang/include/clang/Basic/HLSL*.h - - clang/include/clang/Sema/HLSL*.h - - clang/docs/HLSL/** - - clang/lib/Driver/ToolChains/HLSL* - - clang/lib/Parse/ParseHLSL.cpp - - clang/lib/Sema/HLSLExternalSemaSource.cpp - - clang/lib/Sema/SemaHLSL.cpp - - clang/lib/CodeGen/CGHLSLRuntime.* - - clang/lib/CodeGen/CGHLSLBuiltins.cpp - - llvm/include/llvm/Frontend/HLSL/** - - llvm/lib/Frontend/HLSL/** + - clang/test/ParserHLSL/** + - clang/test/SemaHLSL/** + - clang/test/AST/HLSL/** + - clang/test/CodeGenHLSL/** + - clang/cmake/caches/HLSL.cmake + - clang/include/clang/Basic/HLSL*.h + - clang/include/clang/Sema/HLSL*.h + - clang/docs/HLSL/** + - clang/lib/Driver/ToolChains/HLSL* + - clang/lib/Parse/ParseHLSL.cpp + - clang/lib/Sema/HLSLExternalSemaSource.cpp + - clang/lib/Sema/SemaHLSL.cpp + - clang/lib/CodeGen/CGHLSLRuntime.* + - clang/lib/CodeGen/CGHLSLBuiltins.cpp + - llvm/include/llvm/Frontend/HLSL/** + - llvm/lib/Frontend/HLSL/** llvm:SelectionDAG: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/CodeGen/SelectionDAG*.h - - llvm/include/llvm/CodeGen/SDNodeProperties.td - - llvm/include/llvm/Target/TargetSelectionDAG.td - - llvm/lib/CodeGen/SelectionDAG/** - - llvm/utils/TableGen/CodeGenDAG* - - llvm/utils/TableGen/DAGISel* - - llvm/include/llvm/CodeGen/DAGCombine.h - - llvm/include/llvm/CodeGen/ISDOpcodes.h + - llvm/include/llvm/CodeGen/SelectionDAG*.h + - llvm/include/llvm/CodeGen/SDNodeProperties.td + - llvm/include/llvm/Target/TargetSelectionDAG.td + - llvm/lib/CodeGen/SelectionDAG/** + - llvm/utils/TableGen/CodeGenDAG* + - llvm/utils/TableGen/DAGISel* + - llvm/include/llvm/CodeGen/DAGCombine.h + - llvm/include/llvm/CodeGen/ISDOpcodes.h backend:DirectX: - - changed-files: - - any-glob-to-any-file: - - '**/*DirectX*' - - '**/*DXIL*' - - '**/*dxil*' - - '**/*DirectX*/**' - - '**/*DXIL*/**' - - '**/*dxil*/**' - - '**/*DXContainer*' - - '**/*DXContainer*/**' - - clang/lib/Sema/SemaDirectX.cpp - - clang/include/clang/Sema/SemaDirectX.h - - clang/include/clang/Basic/BuiltinsDirectX.td - - clang/lib/CodeGen/TargetBuiltins/DirectX.cpp - - clang/test/CodeGenDirectX/** - - clang/test/SemaDirectX/** + - '**/*DirectX*' + - '**/*DXIL*' + - '**/*dxil*' + - '**/*DirectX*/**' + - '**/*DXIL*/**' + - '**/*dxil*/**' + - '**/*DXContainer*' + - '**/*DXContainer*/**' + - clang/lib/Sema/SemaDirectX.cpp + - clang/include/clang/Sema/SemaDirectX.h + - clang/include/clang/Basic/BuiltinsDirectX.td + - clang/lib/CodeGen/TargetBuiltins/DirectX.cpp + - clang/test/CodeGenDirectX/** + - clang/test/SemaDirectX/** backend:SPIR-V: - - changed-files: - - any-glob-to-any-file: - - clang/lib/Driver/ToolChains/SPIRV.* - - clang/lib/Sema/SemaSPIRV.cpp - - clang/include/clang/Sema/SemaSPIRV.h - - clang/include/clang/Basic/BuiltinsSPIRV.td - - clang/test/CodeGenSPIRV/** - - clang/test/SemaSPIRV/** - - llvm/lib/Target/SPIRV/** - - llvm/test/CodeGen/SPIRV/** - - llvm/test/Frontend/HLSL/** - - llvm/docs/SPIRVUsage.rst + - clang/lib/Driver/ToolChains/SPIRV.* + - clang/lib/Sema/SemaSPIRV.cpp + - clang/include/clang/Sema/SemaSPIRV.h + - clang/include/clang/Basic/BuiltinsSPIRV.td + - clang/test/CodeGenSPIRV/** + - clang/test/SemaSPIRV/** + - llvm/lib/Target/SPIRV/** + - llvm/test/CodeGen/SPIRV/** + - llvm/test/Frontend/HLSL/** + - llvm/docs/SPIRVUsage.rst mlgo: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Analysis/ML* - - llvm/include/llvm/Analysis/ML* - - llvm/lib/Analysis/*Runner.cpp - - llvm/include/llvm/Analysis/*Runner.h - - llvm/unittests/Analysis/ML* - - llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp - - llvm/lib/Analysis/TrainingLogger.cpp - - llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h - - llvm/include/llvm/Analysis/Utils/TrainingLogger.h - - llvm/test/Analysis/FunctionPropertiesAnalysis/* - - llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp - - llvm/test/Transforms/inline/ML/** - - llvm/lib/CodeGen/ML* - - llvm/unittests/CodeGen/ML* - - llvm/test/CodeGen/MLRegAlloc/** - - llvm/utils/mlgo-utils/** - - llvm/docs/MLGO.rst - - llvm/include/llvm/Analysis/IR2Vec.h - - llvm/lib/Analysis/IR2Vec.cpp - - llvm/lib/Analysis/models/** - - llvm/include/llvm/CodeGen/MIR2Vec.h - - llvm/lib/CodeGen/MIR2Vec.cpp - - llvm/test/Analysis/IR2Vec/** - - llvm/test/CodeGen/MIR2Vec/** - - llvm/unittests/Analysis/IR2VecTest.cpp - - llvm/unittests/CodeGen/MIR2VecTest.cpp - - llvm/tools/llvm-ir2vec/** - - llvm/docs/CommandGuide/llvm-ir2vec.rst + - llvm/lib/Analysis/ML* + - llvm/include/llvm/Analysis/ML* + - llvm/lib/Analysis/*Runner.cpp + - llvm/include/llvm/Analysis/*Runner.h + - llvm/unittests/Analysis/ML* + - llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp + - llvm/lib/Analysis/TrainingLogger.cpp + - llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h + - llvm/include/llvm/Analysis/Utils/TrainingLogger.h + - llvm/test/Analysis/FunctionPropertiesAnalysis/* + - llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp + - llvm/test/Transforms/inline/ML/** + - llvm/lib/CodeGen/ML* + - llvm/unittests/CodeGen/ML* + - llvm/test/CodeGen/MLRegAlloc/** + - llvm/utils/mlgo-utils/** + - llvm/docs/MLGO.rst + - llvm/include/llvm/Analysis/IR2Vec.h + - llvm/lib/Analysis/IR2Vec.cpp + - llvm/lib/Analysis/models/** + - llvm/include/llvm/CodeGen/MIR2Vec.h + - llvm/lib/CodeGen/MIR2Vec.cpp + - llvm/test/Analysis/IR2Vec/** + - llvm/test/CodeGen/MIR2Vec/** + - llvm/unittests/Analysis/IR2VecTest.cpp + - llvm/unittests/CodeGen/MIR2VecTest.cpp + - llvm/tools/llvm-ir2vec/** + - llvm/docs/CommandGuide/llvm-ir2vec.rst tools:llvm-exegesis: - - changed-files: - - any-glob-to-any-file: - - llvm/tools/llvm-exegesis/** - - llvm/test/tools/llvm-exegesis/** - - llvm/unittests/tools/llvm-exegesis/** + - llvm/tools/llvm-exegesis/** + - llvm/test/tools/llvm-exegesis/** + - llvm/unittests/tools/llvm-exegesis/** tools:llvm-reduce: - - changed-files: - - any-glob-to-any-file: - - llvm/tools/llvm-reduce/** + - llvm/tools/llvm-reduce/** platform:windows: - - changed-files: - - any-glob-to-any-file: - - lld/COFF/** - - clang/lib/Driver/MSVC.cpp - - clang/lib/Driver/MinGW.cpp - - llvm/lib/DebugInfo/CodeView/** - - llvm/lib/DebugInfo/PDB/** - - llvm/lib/WindowsDriver/** - - llvm/lib/Support/Windows/** - - llvm/lib/BinaryFormat/COFF.cpp + - lld/COFF/** + - clang/lib/Driver/MSVC.cpp + - clang/lib/Driver/MinGW.cpp + - llvm/lib/DebugInfo/CodeView/** + - llvm/lib/DebugInfo/PDB/** + - llvm/lib/WindowsDriver/** + - llvm/lib/Support/Windows/** + - llvm/lib/BinaryFormat/COFF.cpp llvm:regalloc: - - changed-files: - - any-glob-to-any-file: - - llvm/**/CodeGen/CalcSpillWeights* - - llvm/**/CodeGen/InlineSpiller* - - llvm/**/CodeGen/InterferenceCache* - - llvm/**/CodeGen/LiveInterval* - - llvm/**/CodeGen/LiveRange* - - llvm/**/CodeGen/LiveReg* - - llvm/**/CodeGen/LiveVariables* - - llvm/**/CodeGen/MachineCopyPropagation* - - llvm/**/CodeGen/PHIElimination* - - llvm/**/CodeGen/ProcessImplicitDefs.cpp - - llvm/**/CodeGen/Register* - - llvm/**/CodeGen/RegUsage* - - llvm/**/CodeGen/RenameIndependentSubregs.cpp - - llvm/**/CodeGen/SlotIndexes.h - - llvm/**/CodeGen/SpillPlacement* - - llvm/**/CodeGen/SplitKit* - - llvm/**/CodeGen/VirtRegMap.h - - llvm/include/PBQP/** - - llvm/include/PBQPRAConstraint.h - - llvm/include/llvm/CodeGen/Spiller.h - - llvm/**/*RegAlloc + - llvm/**/CodeGen/CalcSpillWeights* + - llvm/**/CodeGen/InlineSpiller* + - llvm/**/CodeGen/InterferenceCache* + - llvm/**/CodeGen/LiveInterval* + - llvm/**/CodeGen/LiveRange* + - llvm/**/CodeGen/LiveReg* + - llvm/**/CodeGen/LiveVariables* + - llvm/**/CodeGen/MachineCopyPropagation* + - llvm/**/CodeGen/PHIElimination* + - llvm/**/CodeGen/ProcessImplicitDefs.cpp + - llvm/**/CodeGen/Register* + - llvm/**/CodeGen/RegUsage* + - llvm/**/CodeGen/RenameIndependentSubregs.cpp + - llvm/**/CodeGen/SlotIndexes.h + - llvm/**/CodeGen/SpillPlacement* + - llvm/**/CodeGen/SplitKit* + - llvm/**/CodeGen/VirtRegMap.h + - llvm/include/PBQP/** + - llvm/include/PBQPRAConstraint.h + - llvm/include/llvm/CodeGen/Spiller.h + - llvm/**/*RegAlloc lldb: - - changed-files: - - any-glob-to-any-file: - - lldb/** + - lldb/** lldb-dap: - - changed-files: - - any-glob-to-any-file: - - lldb/tools/lldb-dap/** + - lldb/tools/lldb-dap/** backend:AMDGPU: - - changed-files: - - any-glob-to-any-file: - - '**/*amdgpu*' - - '**/*AMDGPU*' - - '**/*amdgpu*/**' - - '**/*AMDGPU*/**' + - '**/*amdgpu*' + - '**/*AMDGPU*' + - '**/*amdgpu*/**' + - '**/*AMDGPU*/**' backend:NVPTX: - - changed-files: - - any-glob-to-any-file: - - 'llvm/**/*nvvm*' - - 'llvm/**/*NVVM*' - - 'llvm/**/*nvptx*' - - 'llvm/**/*NVPTX*' - - 'llvm/**/*nvvm*/**' - - 'llvm/**/*NVVM*/**' - - 'llvm/**/*nvptx*/**' - - 'llvm/**/*NVPTX*/**' + - 'llvm/**/*nvvm*' + - 'llvm/**/*NVVM*' + - 'llvm/**/*nvptx*' + - 'llvm/**/*NVPTX*' + - 'llvm/**/*nvvm*/**' + - 'llvm/**/*NVVM*/**' + - 'llvm/**/*nvptx*/**' + - 'llvm/**/*NVPTX*/**' backend:MIPS: - - changed-files: - - any-glob-to-any-file: - - '**/*mips*' - - '**/*Mips*' - - '**/*mips*/**' - - '**/*Mips*/**' + - '**/*mips*' + - '**/*Mips*' + - '**/*mips*/**' + - '**/*Mips*/**' backend:RISC-V: - - changed-files: - - any-glob-to-any-file: - - '**/*riscv*' - - '**/*RISCV*' - - '**/*riscv*/**' - - '**/*RISCV*/**' + - '**/*riscv*' + - '**/*RISCV*' + - '**/*riscv*/**' + - '**/*RISCV*/**' backend:Xtensa: - - changed-files: - - any-glob-to-any-file: - - '**/*xtensa*' - - '**/*Xtensa*' - - '**/*xtensa*/**' - - '**/*Xtensa*/**' + - '**/*xtensa*' + - '**/*Xtensa*' + - '**/*xtensa*/**' + - '**/*Xtensa*/**' lld:coff: - - changed-files: - - any-glob-to-any-file: - - lld/**/COFF/** - - lld/Common/** + - lld/**/COFF/** + - lld/Common/** lld:elf: - - changed-files: - - any-glob-to-any-file: - - lld/**/ELF/** - - lld/Common/** + - lld/**/ELF/** + - lld/Common/** lld:macho: - - changed-files: - - any-glob-to-any-file: - - lld/**/MachO/** - - lld/Common/** + - lld/**/MachO/** + - lld/Common/** lld:wasm: - - changed-files: - - any-glob-to-any-file: - - lld/**/wasm/** - - lld/Common/** + - lld/**/wasm/** + - lld/Common/** backend:ARC: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Target/ARC/** - - clang/lib/Basic/Targets/ARC.h - - clang/lib/Basic/Targets/ARC.cpp - - clang/lib/CodeGen/Targets/ARC.cpp + - llvm/lib/Target/ARC/** + - clang/lib/Basic/Targets/ARC.h + - clang/lib/Basic/Targets/ARC.cpp + - clang/lib/CodeGen/Targets/ARC.cpp backend:ARM: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/IR/IntrinsicsARM.td - - llvm/test/MC/ARM/** - - llvm/lib/Target/ARM/** - - llvm/test/CodeGen/ARM/** - - clang/lib/Basic/Targets/ARM* - - clang/lib/Driver/ToolChains/Arch/ARM.* - - clang/lib/CodeGen/Targets/ARM.cpp - - clang/include/clang/Basic/BuiltinsARM* - - llvm/test/MC/DisasemblerARM/** - - clang/include/clang/Sema/SemaARM.h - - clang/lib/Sema/SemaARM.cpp + - llvm/include/llvm/IR/IntrinsicsARM.td + - llvm/test/MC/ARM/** + - llvm/lib/Target/ARM/** + - llvm/test/CodeGen/ARM/** + - clang/lib/Basic/Targets/ARM* + - clang/lib/Driver/ToolChains/Arch/ARM.* + - clang/lib/CodeGen/Targets/ARM.cpp + - clang/include/clang/Basic/BuiltinsARM* + - llvm/test/MC/DisasemblerARM/** + - clang/include/clang/Sema/SemaARM.h + - clang/lib/Sema/SemaARM.cpp backend:AArch64: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/IR/IntrinsicsAArch64.td - - llvm/test/MC/AArch64/** - - llvm/lib/Target/AArch64/** - - llvm/test/CodeGen/AArch64/** - - clang/lib/Basic/Targets/AArch64* - - clang/lib/Driver/ToolChains/Arch/AArch64.* - - clang/lib/CodeGen/Targets/AArch64.cpp - - clang/include/clang/Basic/BuiltinsAArch64* - - llvm/test/MC/Disassembler/AArch64/** - - clang/include/clang/Sema/SemaARM.h - - clang/lib/Sema/SemaARM.cpp + - llvm/include/llvm/IR/IntrinsicsAArch64.td + - llvm/test/MC/AArch64/** + - llvm/lib/Target/AArch64/** + - llvm/test/CodeGen/AArch64/** + - clang/lib/Basic/Targets/AArch64* + - clang/lib/Driver/ToolChains/Arch/AArch64.* + - clang/lib/CodeGen/Targets/AArch64.cpp + - clang/include/clang/Basic/BuiltinsAArch64* + - llvm/test/MC/Disassembler/AArch64/** + - clang/include/clang/Sema/SemaARM.h + - clang/lib/Sema/SemaARM.cpp backend:CSKY: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Target/CSKY/** - - llvm/include/llvm/TargetParser/CSKYTargetParser.def - - llvm/include/llvm/TargetParser/CSKYTargetParser.h - - llvm/include/llvm/BinaryFormat/ELFRelocs/CSKY.def - - llvm/lib/TargetParser/CSKYTargetParser.cpp - - llvm/lib/Support/CSKYAttributes.cpp - - llvm/lib/Support/CSKYAttributeParser.cpp - - clang/lib/Basic/Targets/CSKY.h - - clang/lib/Basic/Targets/CSKY.cpp - - clang/lib/CodeGen/Targets/CSKY.cpp - - clang/lib/Driver/ToolChains/CSKY* + - llvm/lib/Target/CSKY/** + - llvm/include/llvm/TargetParser/CSKYTargetParser.def + - llvm/include/llvm/TargetParser/CSKYTargetParser.h + - llvm/include/llvm/BinaryFormat/ELFRelocs/CSKY.def + - llvm/lib/TargetParser/CSKYTargetParser.cpp + - llvm/lib/Support/CSKYAttributes.cpp + - llvm/lib/Support/CSKYAttributeParser.cpp + - clang/lib/Basic/Targets/CSKY.h + - clang/lib/Basic/Targets/CSKY.cpp + - clang/lib/CodeGen/Targets/CSKY.cpp + - clang/lib/Driver/ToolChains/CSKY* backend:Hexagon: - - changed-files: - - any-glob-to-any-file: - - clang/include/clang/Basic/BuiltinsHexagon*.def - - clang/include/clang/Sema/SemaHexagon.h - - clang/lib/Basic/Targets/Hexagon.* - - clang/lib/CodeGen/Targets/Hexagon.cpp - - clang/lib/Driver/ToolChains/Hexagon.* - - clang/lib/Sema/SemaHexagon.cpp - - lld/ELF/Arch/Hexagon.cpp - - lldb/source/Plugins/ABI/Hexagon/** - - lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/** - - llvm/include/llvm/BinaryFormat/ELFRelocs/Hexagon.def - - llvm/include/llvm/IR/IntrinsicsHexagon* - - llvm/include/llvm/Support/Hexagon* - - llvm/lib/Support/Hexagon* - - llvm/lib/Target/Hexagon/** - - llvm/test/CodeGen/Hexagon/** - - llvm/test/CodeGen/*/Hexagon/** - - llvm/test/DebugInfo/*/Hexagon/** - - llvm/test/Transforms/*/Hexagon - - llvm/test/MC/Disassembler/Hexagon/** - - llvm/test/MC/Hexagon/** - - llvm/test/tools/llvm-objdump/ELF/Hexagon/** + - clang/include/clang/Basic/BuiltinsHexagon*.def + - clang/include/clang/Sema/SemaHexagon.h + - clang/lib/Basic/Targets/Hexagon.* + - clang/lib/CodeGen/Targets/Hexagon.cpp + - clang/lib/Driver/ToolChains/Hexagon.* + - clang/lib/Sema/SemaHexagon.cpp + - lld/ELF/Arch/Hexagon.cpp + - lldb/source/Plugins/ABI/Hexagon/** + - lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/** + - llvm/include/llvm/BinaryFormat/ELFRelocs/Hexagon.def + - llvm/include/llvm/IR/IntrinsicsHexagon* + - llvm/include/llvm/Support/Hexagon* + - llvm/lib/Support/Hexagon* + - llvm/lib/Target/Hexagon/** + - llvm/test/CodeGen/Hexagon/** + - llvm/test/CodeGen/*/Hexagon/** + - llvm/test/DebugInfo/*/Hexagon/** + - llvm/test/Transforms/*/Hexagon + - llvm/test/MC/Disassembler/Hexagon/** + - llvm/test/MC/Hexagon/** + - llvm/test/tools/llvm-objdump/ELF/Hexagon/** backend:Lanai: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Target/Lanai/** - - clang/lib/Basic/Targets/Lanai.h - - clang/lib/Basic/Targets/Lanai.cpp - - clang/lib/CodeGen/Targets/Lanai.cpp - - clang/lib/Driver/ToolChains/Lanai* + - llvm/lib/Target/Lanai/** + - clang/lib/Basic/Targets/Lanai.h + - clang/lib/Basic/Targets/Lanai.cpp + - clang/lib/CodeGen/Targets/Lanai.cpp + - clang/lib/Driver/ToolChains/Lanai* backend:loongarch: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/IR/IntrinsicsLoongArch.td - - llvm/test/MC/LoongArch/** - - llvm/lib/Target/LoongArch/** - - llvm/test/CodeGen/LoongArch/** - - clang/lib/Basic/Targets/LoongArch* - - clang/lib/Driver/ToolChains/Arch/LoongArch.* - - clang/lib/CodeGen/Targets/LoongArch.cpp - - clang/include/clang/Basic/BuiltinsLoongArch* - - clang/include/clang/Sema/SemaLoongArch.h - - clang/lib/Sema/SemaLoongArch.cpp + - llvm/include/llvm/IR/IntrinsicsLoongArch.td + - llvm/test/MC/LoongArch/** + - llvm/lib/Target/LoongArch/** + - llvm/test/CodeGen/LoongArch/** + - clang/lib/Basic/Targets/LoongArch* + - clang/lib/Driver/ToolChains/Arch/LoongArch.* + - clang/lib/CodeGen/Targets/LoongArch.cpp + - clang/include/clang/Basic/BuiltinsLoongArch* + - clang/include/clang/Sema/SemaLoongArch.h + - clang/lib/Sema/SemaLoongArch.cpp backend:MSP430: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/IR/IntrinsicsMSP430.td - - llvm/test/MC/MSP430/** - - llvm/lib/Target/MSP430/** - - llvm/test/CodeGen/MSP430/** - - clang/lib/Basic/Targets/MSP430* - - clang/lib/Driver/ToolChains/Arch/MSP430.* - - clang/lib/CodeGen/Targets/MSP430.cpp - - clang/include/clang/Basic/BuiltinsMSP430* - - llvm/test/MC/Disassembler/MSP430/** + - llvm/include/llvm/IR/IntrinsicsMSP430.td + - llvm/test/MC/MSP430/** + - llvm/lib/Target/MSP430/** + - llvm/test/CodeGen/MSP430/** + - clang/lib/Basic/Targets/MSP430* + - clang/lib/Driver/ToolChains/Arch/MSP430.* + - clang/lib/CodeGen/Targets/MSP430.cpp + - clang/include/clang/Basic/BuiltinsMSP430* + - llvm/test/MC/Disassembler/MSP430/** backend:Sparc: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/IR/IntrinsicsSparc.td - - llvm/test/MC/Sparc/** - - llvm/lib/Target/Sparc/** - - llvm/test/CodeGen/Sparc/** - - clang/lib/Basic/Targets/Sparc* - - clang/lib/Driver/ToolChains/Arch/Sparc.* - - clang/lib/CodeGen/Targets/Sparc.cpp - - clang/include/clang/Basic/BuiltinsSparc* - - llvm/test/MC/Disassembler/Sparc/** + - llvm/include/llvm/IR/IntrinsicsSparc.td + - llvm/test/MC/Sparc/** + - llvm/lib/Target/Sparc/** + - llvm/test/CodeGen/Sparc/** + - clang/lib/Basic/Targets/Sparc* + - clang/lib/Driver/ToolChains/Arch/Sparc.* + - clang/lib/CodeGen/Targets/Sparc.cpp + - clang/include/clang/Basic/BuiltinsSparc* + - llvm/test/MC/Disassembler/Sparc/** backend:WebAssembly: - - changed-files: - - any-glob-to-any-file: - - llvm/lib/Target/WebAssembly/** - - llvm/test/CodeGen/WebAssembly/** - - clang/lib/Basic/Targets/WebAssembly* - - clang/include/clang/Basic/BuiltinsWebAssembly.def - - clang/include/clang/Basic/WebAssemblyReferenceTypes.def - - clang/lib/CodeGen/Targets/WebAssembly* - - llvm/include/llvm/IR/IntinsicsWebAssembly.td - - llvm/include/llvm/Object/Wasm* - - llvm/lib/CodeGen/AsmPrinter/Wasm* - - llvm/lib/CodeGen/Wasm* - - llvm/lib/MC/MCParser/Wasm* - - llvm/lib/MC/Wasm* - - llvm/lib/ObjCopy/wasm/** - - llvm/lib/Object/Wasm* - - clang/lib/Driver/Toolchains/WebAssembly* - - clang/lib/Headers/wasm_simd128.h - - clang/test/CodeGen/WebAssembly/** - - clang/test/SemaCXX/*wasm* - - clang/test/Sema/*wasm* - - llvm/include/llvm/BinaryFormat/Wasm.h - - llvm/unittests/Target/WebAssembly/** - - llvm/test/DebugInfo/WebAssembly/** - - llvm/test/MC/WebAssembly/** - - clang/include/clang/Sema/SemaWasm.h - - clang/lib/Sema/SemaLoongWasm.cpp + - llvm/lib/Target/WebAssembly/** + - llvm/test/CodeGen/WebAssembly/** + - clang/lib/Basic/Targets/WebAssembly* + - clang/include/clang/Basic/BuiltinsWebAssembly.def + - clang/include/clang/Basic/WebAssemblyReferenceTypes.def + - clang/lib/CodeGen/Targets/WebAssembly* + - llvm/include/llvm/IR/IntinsicsWebAssembly.td + - llvm/include/llvm/Object/Wasm* + - llvm/lib/CodeGen/AsmPrinter/Wasm* + - llvm/lib/CodeGen/Wasm* + - llvm/lib/MC/MCParser/Wasm* + - llvm/lib/MC/Wasm* + - llvm/lib/ObjCopy/wasm/** + - llvm/lib/Object/Wasm* + - clang/lib/Driver/Toolchains/WebAssembly* + - clang/lib/Headers/wasm_simd128.h + - clang/test/CodeGen/WebAssembly/** + - clang/test/SemaCXX/*wasm* + - clang/test/Sema/*wasm* + - llvm/include/llvm/BinaryFormat/Wasm.h + - llvm/unittests/Target/WebAssembly/** + - llvm/test/DebugInfo/WebAssembly/** + - llvm/test/MC/WebAssembly/** + - clang/include/clang/Sema/SemaWasm.h + - clang/lib/Sema/SemaLoongWasm.cpp backend:X86: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/IR/IntrinsicsX86.td - - llvm/lib/Target/X86/** - - llvm/test/CodeGen/X86/** - - llvm/test/MC/X86/** - - llvm/test/MC/Disassembler/X86/** - - llvm/test/Analysis/CostModel/X86/** - - llvm/test/tools/llvm-mca/X86/** - - clang/lib/Basic/Targets/X86/** - - clang/lib/Driver/ToolChains/Arch/X86.* - - clang/lib/CodeGen/Targets/X86.* - - clang/lib/Headers/** - - clang/test/CodeGen/X86/** - - clang/include/clang/Basic/BuiltinsX86* - - llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h - - llvm/include/llvm/TargetParser/X86* - - llvm/lib/TargetParser/X86* - - llvm/utils/TableGen/X86* - - clang/include/clang/Sema/SemaX86.h - - clang/lib/Sema/SemaX86.cpp + - llvm/include/llvm/IR/IntrinsicsX86.td + - llvm/lib/Target/X86/** + - llvm/test/CodeGen/X86/** + - llvm/test/MC/X86/** + - llvm/test/MC/Disassembler/X86/** + - llvm/test/Analysis/CostModel/X86/** + - llvm/test/tools/llvm-mca/X86/** + - clang/lib/Basic/Targets/X86/** + - clang/lib/Driver/ToolChains/Arch/X86.* + - clang/lib/CodeGen/Targets/X86.* + - clang/lib/Headers/** + - clang/test/CodeGen/X86/** + - clang/include/clang/Basic/BuiltinsX86* + - llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h + - llvm/include/llvm/TargetParser/X86* + - llvm/lib/TargetParser/X86* + - llvm/utils/TableGen/X86* + - clang/include/clang/Sema/SemaX86.h + - clang/lib/Sema/SemaX86.cpp backend:PowerPC: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC* - - llvm/include/llvm/BinaryFormat/XCOFF.h - - llvm/include/llvm/IR/IntrinsicsPowerPC.td - - llvm/lib/CodeGen/AsmPrinter/AIXException.cpp - - llvm/lib/Target/PowerPC/** - - llvm/test/Analysis/**/PowerPC/** - - llvm/test/CodeGen/PowerPC/** - - llvm/test/CodeGen/MIR/PowerPC/** - - llvm/test/DebugInfo/XCOFF/** - - llvm/test/DebugInfo/PowerPC/** - - llvm/test/LTO/PowerPC/** - - llvm/test/MC/Disassembler/PowerPC/** - - llvm/test/MC/PowerPC/** - - llvm/test/MC/XCOFF/** - - llvm/test/Transforms/**/PowerPC/** - - clang/include/clang/Basic/BuiltinsPPC.* - - clang/lib/Basic/Targets/PPC.* - - clang/lib/CodeGen/Targets/PPC.cpp - - clang/lib/Driver/ToolChains/PPC* - - clang/lib/Driver/ToolChains/AIX* - - clang/lib/Driver/ToolChains/Arch/PPC.* - - clang/test/CodeGen/PowerPC/** - - clang/include/clang/Sema/SemaPPC.h - - clang/lib/Sema/SemaPPC.cpp + - llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC* + - llvm/include/llvm/BinaryFormat/XCOFF.h + - llvm/include/llvm/IR/IntrinsicsPowerPC.td + - llvm/lib/CodeGen/AsmPrinter/AIXException.cpp + - llvm/lib/Target/PowerPC/** + - llvm/test/Analysis/**/PowerPC/** + - llvm/test/CodeGen/PowerPC/** + - llvm/test/CodeGen/MIR/PowerPC/** + - llvm/test/DebugInfo/XCOFF/** + - llvm/test/DebugInfo/PowerPC/** + - llvm/test/LTO/PowerPC/** + - llvm/test/MC/Disassembler/PowerPC/** + - llvm/test/MC/PowerPC/** + - llvm/test/MC/XCOFF/** + - llvm/test/Transforms/**/PowerPC/** + - clang/include/clang/Basic/BuiltinsPPC.* + - clang/lib/Basic/Targets/PPC.* + - clang/lib/CodeGen/Targets/PPC.cpp + - clang/lib/Driver/ToolChains/PPC* + - clang/lib/Driver/ToolChains/AIX* + - clang/lib/Driver/ToolChains/Arch/PPC.* + - clang/test/CodeGen/PowerPC/** + - clang/include/clang/Sema/SemaPPC.h + - clang/lib/Sema/SemaPPC.cpp backend:SystemZ: - - changed-files: - - any-glob-to-any-file: - - llvm/include/llvm/BinaryFormat/ELFRelocs/SystemZ* - - llvm/include/llvm/BinaryFormat/GOFF.h - - llvm/include/llvm/IR/IntrinsicsSystemZ.td - - llvm/lib/Target/SystemZ/** - - llvm/test/Analysis/**/SystemZ/** - - llvm/test/CodeGen/SystemZ/** - - llvm/test/DebugInfo/SystemZ/** - - llvm/test/ExecutionEngine/**/SystemZ/** - - llvm/test/MC/Disassembler/SystemZ/** - - llvm/test/MC/GOFF/** - - llvm/test/MC/SystemZ/** - - llvm/test/Transforms/**/SystemZ/** - - clang/include/clang/Basic/BuiltinsSystemZ.* - - clang/lib/Basic/Targets/SystemZ.* - - clang/lib/CodeGen/Targets/SystemZ.cpp - - clang/lib/Driver/ToolChains/ZOS* - - clang/lib/Driver/ToolChains/Arch/SystemZ.* - - clang/test/CodeGen/SystemZ/** - - clang/include/clang/Sema/SemaSystemZ.h - - clang/lib/Sema/SemaSystemZ.cpp + - llvm/include/llvm/BinaryFormat/ELFRelocs/SystemZ* + - llvm/include/llvm/BinaryFormat/GOFF.h + - llvm/include/llvm/IR/IntrinsicsSystemZ.td + - llvm/lib/Target/SystemZ/** + - llvm/test/Analysis/**/SystemZ/** + - llvm/test/CodeGen/SystemZ/** + - llvm/test/DebugInfo/SystemZ/** + - llvm/test/ExecutionEngine/**/SystemZ/** + - llvm/test/MC/Disassembler/SystemZ/** + - llvm/test/MC/GOFF/** + - llvm/test/MC/SystemZ/** + - llvm/test/Transforms/**/SystemZ/** + - clang/include/clang/Basic/BuiltinsSystemZ.* + - clang/lib/Basic/Targets/SystemZ.* + - clang/lib/CodeGen/Targets/SystemZ.cpp + - clang/lib/Driver/ToolChains/ZOS* + - clang/lib/Driver/ToolChains/Arch/SystemZ.* + - clang/test/CodeGen/SystemZ/** + - clang/include/clang/Sema/SemaSystemZ.h + - clang/lib/Sema/SemaSystemZ.cpp third-party:unittests: - - changed-files: - - any-glob-to-any-file: - - third-party/unittests/** + - third-party/unittests/** third-party:benchmark: - - changed-files: - - any-glob-to-any-file: - - third-party/benchmark/** + - third-party/benchmark/** llvm:binary-utilities: - - changed-files: - - any-glob-to-any-file: - - llvm/docs/CommandGuide/llvm-* - - llvm/include/llvm/BinaryFormat/** - - llvm/include/llvm/DebugInfo/Symbolize/** - - llvm/include/llvm/ObjCopy/** - - llvm/include/llvm/Object/** - - llvm/lib/BinaryFormat/** - - llvm/lib/DebugInfo/Symbolize/** - - llvm/lib/ObjCopy/** - - llvm/lib/Object/** - - llvm/test/Object/** - - llvm/test/tools/llvm-ar/** - - llvm/test/tools/llvm-cxxfilt/** - - llvm/test/tools/llvm-nm/** - - llvm/test/tools/llvm-objcopy/** - - llvm/test/tools/llvm-objdump/** - - llvm/test/tools/llvm-readobj/** - - llvm/test/tools/llvm-size/** - - llvm/test/tools/llvm-strings/** - - llvm/test/tools/llvm-symbolizer/** - - llvm/tools/llvm-ar/** - - llvm/tools/llvm-cxxfilt/** - - llvm/tools/llvm-nm/** - - llvm/tools/llvm-objcopy/** - - llvm/tools/llvm-objdump/** - - llvm/tools/llvm-readobj/** - - llvm/tools/llvm-size/** - - llvm/tools/llvm-strings/** - - llvm/tools/llvm-symbolizer/** + - llvm/docs/CommandGuide/llvm-* + - llvm/include/llvm/BinaryFormat/** + - llvm/include/llvm/DebugInfo/Symbolize/** + - llvm/include/llvm/ObjCopy/** + - llvm/include/llvm/Object/** + - llvm/lib/BinaryFormat/** + - llvm/lib/DebugInfo/Symbolize/** + - llvm/lib/ObjCopy/** + - llvm/lib/Object/** + - llvm/test/Object/** + - llvm/test/tools/llvm-ar/** + - llvm/test/tools/llvm-cxxfilt/** + - llvm/test/tools/llvm-nm/** + - llvm/test/tools/llvm-objcopy/** + - llvm/test/tools/llvm-objdump/** + - llvm/test/tools/llvm-readobj/** + - llvm/test/tools/llvm-size/** + - llvm/test/tools/llvm-strings/** + - llvm/test/tools/llvm-symbolizer/** + - llvm/tools/llvm-ar/** + - llvm/tools/llvm-cxxfilt/** + - llvm/tools/llvm-nm/** + - llvm/tools/llvm-objcopy/** + - llvm/tools/llvm-objdump/** + - llvm/tools/llvm-readobj/** + - llvm/tools/llvm-size/** + - llvm/tools/llvm-strings/** + - llvm/tools/llvm-symbolizer/** clang:openmp: - - changed-files: - - any-glob-to-any-file: - - clang/include/clang/Basic/OpenMP* - - clang/include/clang/AST/OpenMPClause.h - - clang/include/clang/AST/DeclOpenMP.h - - clang/include/clang/AST/ExprOpenMP.h - - clang/include/clang/AST/StmtOpenMP.h - - clang/lib/AST/DeclOpenMP.cpp - - clang/lib/AST/OpenMPClause.cpp - - clang/lib/AST/StmtOpenMP.cpp - - clang/lib/Headers/openmp_wrappers/** - - clang/lib/Parse/ParseOpenMP.cpp - - clang/lib/Basic/OpenMPKinds.cpp - - clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp - - clang/lib/Driver/ToolChains/AMDGPUOpenMP.h - - clang/lib/CodeGen/CgStmtOpenMP.cpp - - clang/lib/CodeGen/CGOpenMP* - - clang/lib/Sema/SemaOpenMP.cpp - - clang/test/OpenMP/** - - clang/test/AST/ast-dump-openmp-* - - llvm/lib/Frontend/OpenMP/** - - llvm/lib/Transforms/IPO/OpenMPOpt.cpp - - llvm/include/llvm/Frontend/OpenMP/** - - llvm/include/llvm/Transforms/IPO/OpenMPOpt.h - - llvm/unittests/Frontend/OpenMP* - - llvm/test/Transforms/OpenMP/** + - clang/include/clang/Basic/OpenMP* + - clang/include/clang/AST/OpenMPClause.h + - clang/include/clang/AST/DeclOpenMP.h + - clang/include/clang/AST/ExprOpenMP.h + - clang/include/clang/AST/StmtOpenMP.h + - clang/lib/AST/DeclOpenMP.cpp + - clang/lib/AST/OpenMPClause.cpp + - clang/lib/AST/StmtOpenMP.cpp + - clang/lib/Headers/openmp_wrappers/** + - clang/lib/Parse/ParseOpenMP.cpp + - clang/lib/Basic/OpenMPKinds.cpp + - clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp + - clang/lib/Driver/ToolChains/AMDGPUOpenMP.h + - clang/lib/CodeGen/CgStmtOpenMP.cpp + - clang/lib/CodeGen/CGOpenMP* + - clang/lib/Sema/SemaOpenMP.cpp + - clang/test/OpenMP/** + - clang/test/AST/ast-dump-openmp-* + - llvm/lib/Frontend/OpenMP/** + - llvm/lib/Transforms/IPO/OpenMPOpt.cpp + - llvm/include/llvm/Frontend/OpenMP/** + - llvm/include/llvm/Transforms/IPO/OpenMPOpt.h + - llvm/unittests/Frontend/OpenMP* + - llvm/test/Transforms/OpenMP/** clang:temporal-safety: - - changed-files: - - any-glob-to-any-file: - - clang/include/clang/Analysis/Analyses/LifetimeSafety/** - - clang/lib/Analysis/LifetimeSafety/** - - clang/unittests/Analysis/LifetimeSafety* - - clang/test/Sema/*lifetime-safety* - - clang/test/Sema/*lifetime-analysis* - - clang/test/Analysis/LifetimeSafety/** + - clang/include/clang/Analysis/Analyses/LifetimeSafety/** + - clang/lib/Analysis/LifetimeSafety/** + - clang/unittests/Analysis/LifetimeSafety* + - clang/test/Sema/*lifetime-safety* + - clang/test/Sema/*lifetime-analysis* + - clang/test/Analysis/LifetimeSafety/** clang:as-a-library: - - changed-files: - - any-glob-to-any-file: - - clang/tools/libclang/** - - clang/bindings/** - - clang/include/clang-c/** - - clang/test/LibClang/** - - clang/unittest/libclang/** + - clang/tools/libclang/** + - clang/bindings/** + - clang/include/clang-c/** + - clang/test/LibClang/** + - clang/unittest/libclang/** openmp:libomp: - - changed-files: - - any-glob-to-any-file: - - 'openmp/**' + - any: ['openmp/**', '!openmp/libomptarget/**'] openmp:libomptarget: - - changed-files: - - all-globs-to-all-file: - - openmp/** - - '!openmp/runtime/**'' + - any: ['openmp/**', '!openmp/runtime/**'] bazel: - - changed-files: - - any-glob-to-any-file: - - utils/bazel/** + - utils/bazel/** offload: - - changed-files: - - any-glob-to-any-file: - - offload/** + - offload/** tablegen: - - changed-files: - - any-glob-to-any-file: - - llvm/include/TableGen/** - - llvm/lib/TableGen/** - - llvm/utils/TableGen/** + - llvm/include/TableGen/** + - llvm/lib/TableGen/** + - llvm/utils/TableGen/** infrastructure: - - changed-files: - - any-glob-to-any-file: - - .ci/** + - .ci/** diff --git a/.github/workflows/new-prs.yml b/.github/workflows/new-prs.yml index 0d97e436d39c4..e1f2e754c1a3d 100644 --- a/.github/workflows/new-prs.yml +++ b/.github/workflows/new-prs.yml @@ -67,7 +67,9 @@ jobs: github.event.pull_request.draft == false && github.event.pull_request.commits < 10 steps: - - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 + - uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 # v4.3.0 with: configuration-path: .github/new-prs-labeler.yml + # workaround for https://github.com/actions/labeler/issues/112 + sync-labels: '' repo-token: ${{ secrets.ISSUE_SUBSCRIBER_TOKEN }} diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp index a7b74944690b4..75693a0c563e9 100644 --- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp @@ -67,6 +67,11 @@ static auto typeWithNameIn(const std::vector &Names) { hasCanonicalType(hasDeclaration(namedDecl(hasAnyName(Names))))); } +static auto functionWithNameIn(const std::vector &Names) { + auto Call = callExpr(callee(functionDecl(hasAnyName(Names)))); + return anyOf(expr(cxxBindTemporaryExpr(has(Call))), expr(Call)); +} + CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -83,9 +88,8 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) { hasAttr(attr::Kind::ScopedLockable))))) .bind("scoped-lockable"); auto OtherRAII = varDecl(typeWithNameIn(RAIITypesList)).bind("raii"); - auto AllowedSuspend = awaitable( - anyOf(typeWithNameIn(AllowedAwaitablesList), - callExpr(callee(functionDecl(hasAnyName(AllowedCallees)))))); + auto AllowedSuspend = awaitable(anyOf(typeWithNameIn(AllowedAwaitablesList), + functionWithNameIn(AllowedCallees))); Finder->addMatcher( expr(anyOf(coawaitExpr(unless(AllowedSuspend)), coyieldExpr()), forEachPrevStmt( @@ -113,9 +117,9 @@ void CoroutineHostileRAIICheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "RAIITypesList", utils::options::serializeStringList(RAIITypesList)); - Options.store(Opts, "SafeAwaitableList", + Options.store(Opts, "AllowedAwaitablesList", utils::options::serializeStringList(AllowedAwaitablesList)); - Options.store(Opts, "SafeCallees", + Options.store(Opts, "AllowedCallees", utils::options::serializeStringList(AllowedCallees)); } } // namespace clang::tidy::misc diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp index ec6ddec56e1f2..dff73aeb7a5ee 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/coroutine-hostile-raii.cpp @@ -2,7 +2,7 @@ // RUN: -config="{CheckOptions: {\ // RUN: misc-coroutine-hostile-raii.RAIITypesList: 'my::Mutex; ::my::other::Mutex', \ // RUN: misc-coroutine-hostile-raii.AllowedAwaitablesList: 'safe::awaitable; ::transformable::awaitable', \ -// RUN: misc-coroutine-hostile-raii.AllowedCallees: 'safe::AwaitFunc; ::safe::Obj::AwaitMethod' \ +// RUN: misc-coroutine-hostile-raii.AllowedCallees: 'safe::AwaitFunc; ::safe::Obj::AwaitMethod; retExemptedAwaitable' \ // RUN: }}" namespace std { @@ -163,7 +163,10 @@ ReturnObject RAIISafeSuspendTest() { // ================================================================================ // Safe transformable awaitable // ================================================================================ -struct transformable { struct awaitable{}; }; +struct transformable { + struct awaitable{}; + struct unsafe_awaitable{}; +}; using alias_transformable_awaitable = transformable::awaitable; struct UseTransformAwaitable { struct promise_type { @@ -172,13 +175,18 @@ struct UseTransformAwaitable { std::suspend_always final_suspend() noexcept { return {}; } void unhandled_exception() {} std::suspend_always await_transform(transformable::awaitable) { return {}; } + std::suspend_always await_transform(transformable::unsafe_awaitable) { + return {}; + } }; }; auto retAwaitable() { return transformable::awaitable{}; } +auto retExemptedAwaitable() { return transformable::unsafe_awaitable{}; } UseTransformAwaitable RAIISafeSuspendTest2() { absl::Mutex a; co_await retAwaitable(); + co_await retExemptedAwaitable(); co_await transformable::awaitable{}; co_await alias_transformable_awaitable{}; } diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 34c2476ffccce..6b5c34d28ce2a 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -29,7 +29,6 @@ struct MissingFeatures { // Unhandled global/linkage information. static bool opGlobalThreadLocal() { return false; } - static bool opGlobalConstant() { return false; } static bool opGlobalWeakRef() { return false; } static bool opGlobalUnnamedAddr() { return false; } static bool opGlobalSection() { return false; } diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index 12bf3a3954b1b..74ec986e49ca7 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -21,7 +21,6 @@ #include "clang/AST/ASTLambda.h" #include "clang/AST/Expr.h" #include "clang/Basic/TargetInfo.h" -#include "llvm/Support/SystemZ/zOSSupport.h" using namespace clang; using namespace clang::interp; diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 325875d10d6ea..e0e4f67df87b2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -526,7 +526,8 @@ cir::GlobalOp CIRGenFunction::addInitializerToStaticVarDecl( bool needsDtor = d.needsDestruction(getContext()) == QualType::DK_cxx_destructor; - assert(!cir::MissingFeatures::opGlobalConstant()); + gv.setConstant(d.getType().isConstantStorage( + getContext(), /*ExcludeCtor=*/true, !needsDtor)); gv.setInitialValueAttr(init); emitter.finalize(gv); diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index c1f2581eb96e3..b8e51f87d4045 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -675,7 +675,10 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty, errorNYI(d->getSourceRange(), "OpenMP target global variable"); gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d))); - assert(!cir::MissingFeatures::opGlobalConstant()); + // FIXME: This code is overly simple and should be merged with other global + // handling. + gv.setConstant(d->getType().isConstantStorage( + astContext, /*ExcludeCtor=*/false, /*ExcludeDtor=*/false)); setLinkageForGV(gv, d); @@ -864,7 +867,11 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd, if (emitter) emitter->finalize(gv); - assert(!cir::MissingFeatures::opGlobalConstant()); + // If it is safe to mark the global 'constant', do so now. + gv.setConstant((vd->hasAttr() && langOpts.CUDAIsDevice) || + (!needsGlobalCtor && !needsGlobalDtor && + vd->getType().isConstantStorage( + astContext, /*ExcludeCtor=*/true, /*ExcludeDtor=*/true))); assert(!cir::MissingFeatures::opGlobalSection()); // Set CIR's linkage type as appropriate. @@ -876,8 +883,17 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd, // FIXME(cir): setLinkage should likely set MLIR's visibility automatically. gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage)); assert(!cir::MissingFeatures::opGlobalDLLImportExport()); - if (linkage == cir::GlobalLinkageKind::CommonLinkage) - errorNYI(initExpr->getSourceRange(), "common linkage"); + if (linkage == cir::GlobalLinkageKind::CommonLinkage) { + // common vars aren't constant even if declared const. + gv.setConstant(false); + // Tentative definition of global variables may be initialized with + // non-zero null pointers. In this case they should have weak linkage + // since common linkage must have zero initializer and must not have + // explicit section therefore cannot have non-zero initial value. + std::optional initializer = gv.getInitialValue(); + if (initializer && !getBuilder().isNullValue(*initializer)) + gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage); + } setNonAliasAttributes(vd, gv); @@ -1231,10 +1247,8 @@ cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator( // linkage. if (!getLangOpts().CPlusPlus && isa(dd) && !isVarDeclStrongDefinition(astContext, *this, cast(dd), - getCodeGenOpts().NoCommon)) { - errorNYI(dd->getBeginLoc(), "common linkage", dd->getDeclKindName()); + getCodeGenOpts().NoCommon)) return cir::GlobalLinkageKind::CommonLinkage; - } // selectany symbols are externally visible, so use weak instead of // linkonce. MSVC optimizes away references to const selectany globals, so diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index d43a462a25092..4912bd197dba4 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1995,7 +1995,6 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp( // attributes are available on cir.global ops. This duplicates code // in CIRToLLVMGlobalOpLowering::matchAndRewrite() but that will go // away when the placeholders are no longer needed. - assert(!cir::MissingFeatures::opGlobalConstant()); const bool isConst = op.getConstant(); assert(!cir::MissingFeatures::addressSpace()); const unsigned addrSpace = 0; @@ -2055,8 +2054,7 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite( convertTypeForMemory(*getTypeConverter(), dataLayout, cirSymType); // FIXME: These default values are placeholders until the the equivalent // attributes are available on cir.global ops. - assert(!cir::MissingFeatures::opGlobalConstant()); - const bool isConst = false; + const bool isConst = op.getConstant(); assert(!cir::MissingFeatures::addressSpace()); const unsigned addrSpace = 0; const bool isDsoLocal = op.getDsoLocal(); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index a837f00732748..f2451b16e78be 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4641,11 +4641,17 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, LHS.getBaseInfo(), TBAAAccessInfo()); } - // The HLSL runtime handle the subscript expression on global resource arrays. - if (getLangOpts().HLSL && (E->getType()->isHLSLResourceRecord() || - E->getType()->isHLSLResourceRecordArray())) { - std::optional LV = - CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *this); + // The HLSL runtime handles subscript expressions on global resource arrays + // and objects with HLSL buffer layouts. + if (getLangOpts().HLSL) { + std::optional LV; + if (E->getType()->isHLSLResourceRecord() || + E->getType()->isHLSLResourceRecordArray()) { + LV = CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *this); + } else if (E->getType().getAddressSpace() == LangAS::hlsl_constant) { + LV = CGM.getHLSLRuntime().emitBufferArraySubscriptExpr(E, *this, + EmitIdxAfterBase); + } if (LV.has_value()) return *LV; } @@ -5110,6 +5116,11 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { EmitIgnoredExpr(E->getBase()); return EmitDeclRefLValue(DRE); } + if (getLangOpts().HLSL && + E->getType().getAddressSpace() == LangAS::hlsl_constant) { + // We have an HLSL buffer - emit using HLSL's layout rules. + return CGM.getHLSLRuntime().emitBufferMemberExpr(*this, E); + } Expr *BaseExpr = E->getBase(); // Check whether the underlying base pointer is a constant null. diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 4e61a6f61948f..67b5f919d1b2a 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -2278,6 +2278,10 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, } } + if (getLangOpts().HLSL && Ty.getAddressSpace() == LangAS::hlsl_constant) + if (CGM.getHLSLRuntime().emitBufferCopy(*this, DestPtr, SrcPtr, Ty)) + return; + // Aggregate assignment turns into llvm.memcpy. This is almost valid per // C99 6.5.16.1p3, which states "If the value being stored in an object is // read from another object that overlaps in anyway the storage of the first diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index ec02096787c7a..208afff24d498 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -13,10 +13,11 @@ //===----------------------------------------------------------------------===// #include "CGHLSLRuntime.h" -#include "Address.h" #include "CGDebugInfo.h" +#include "CGRecordLayout.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "HLSLBufferLayoutBuilder.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attrs.inc" @@ -26,6 +27,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/TargetOptions.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/HLSL/RootSignatureMetadata.h" @@ -278,23 +280,18 @@ llvm::Triple::ArchType CGHLSLRuntime::getArch() { // Emits constant global variables for buffer constants declarations // and creates metadata linking the constant globals with the buffer global. -void CGHLSLRuntime::emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl, - llvm::GlobalVariable *BufGV) { +void CGHLSLRuntime::emitBufferGlobalsAndMetadata( + const HLSLBufferDecl *BufDecl, llvm::GlobalVariable *BufGV, + const CGHLSLOffsetInfo &OffsetInfo) { LLVMContext &Ctx = CGM.getLLVMContext(); // get the layout struct from constant buffer target type llvm::Type *BufType = BufGV->getValueType(); - llvm::Type *BufLayoutType = - cast(BufType)->getTypeParameter(0); llvm::StructType *LayoutStruct = cast( - cast(BufLayoutType)->getTypeParameter(0)); + cast(BufType)->getTypeParameter(0)); - // Start metadata list associating the buffer global variable with its - // constatns - SmallVector BufGlobals; - BufGlobals.push_back(ValueAsMetadata::get(BufGV)); - - const auto *ElemIt = LayoutStruct->element_begin(); + SmallVector> DeclsWithOffset; + size_t OffsetIdx = 0; for (Decl *D : BufDecl->buffer_decls()) { if (isa(D)) // Nothing to do for this declaration. @@ -326,14 +323,28 @@ void CGHLSLRuntime::emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl, continue; } + DeclsWithOffset.emplace_back(VD, OffsetInfo[OffsetIdx++]); + } + + if (!OffsetInfo.empty()) + llvm::stable_sort(DeclsWithOffset, [](const auto &LHS, const auto &RHS) { + return CGHLSLOffsetInfo::compareOffsets(LHS.second, RHS.second); + }); + + // Associate the buffer global variable with its constants + SmallVector BufGlobals; + BufGlobals.reserve(DeclsWithOffset.size() + 1); + BufGlobals.push_back(ValueAsMetadata::get(BufGV)); + + auto ElemIt = LayoutStruct->element_begin(); + for (auto &[VD, _] : DeclsWithOffset) { + if (CGM.getTargetCodeGenInfo().isHLSLPadding(*ElemIt)) + ++ElemIt; + assert(ElemIt != LayoutStruct->element_end() && "number of elements in layout struct does not match"); llvm::Type *LayoutType = *ElemIt++; - // FIXME: handle resources inside user defined structs - // (llvm/wg-hlsl#175) - - // create global variable for the constant and to metadata list GlobalVariable *ElemGV = cast(CGM.GetAddrOfGlobalVar(VD, LayoutType)); BufGlobals.push_back(ValueAsMetadata::get(ElemGV)); @@ -410,18 +421,17 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { // create global variable for the constant buffer CGHLSLOffsetInfo OffsetInfo = CGHLSLOffsetInfo::fromDecl(*BufDecl); - llvm::TargetExtType *TargetTy = cast( - convertHLSLSpecificType(ResHandleTy, OffsetInfo)); + llvm::Type *LayoutTy = convertHLSLSpecificType(ResHandleTy, OffsetInfo); llvm::GlobalVariable *BufGV = new GlobalVariable( - TargetTy, /*isConstant*/ false, - GlobalValue::LinkageTypes::ExternalLinkage, PoisonValue::get(TargetTy), + LayoutTy, /*isConstant*/ false, + GlobalValue::LinkageTypes::ExternalLinkage, PoisonValue::get(LayoutTy), llvm::formatv("{0}{1}", BufDecl->getName(), BufDecl->isCBuffer() ? ".cb" : ".tb"), GlobalValue::NotThreadLocal); CGM.getModule().insertGlobalVariable(BufGV); // Add globals for constant buffer elements and create metadata nodes - emitBufferGlobalsAndMetadata(BufDecl, BufGV); + emitBufferGlobalsAndMetadata(BufDecl, BufGV, OffsetInfo); // Initialize cbuffer from binding (implicit or explicit) initializeBufferFromBinding(BufDecl, BufGV); @@ -440,7 +450,7 @@ void CGHLSLRuntime::addRootSignature( SignatureDecl->getRootElements(), nullptr, M); } -llvm::TargetExtType * +llvm::StructType * CGHLSLRuntime::getHLSLBufferLayoutType(const RecordType *StructType) { const auto Entry = LayoutTypes.find(StructType); if (Entry != LayoutTypes.end()) @@ -449,7 +459,7 @@ CGHLSLRuntime::getHLSLBufferLayoutType(const RecordType *StructType) { } void CGHLSLRuntime::addHLSLBufferLayoutType(const RecordType *StructType, - llvm::TargetExtType *LayoutTy) { + llvm::StructType *LayoutTy) { assert(getHLSLBufferLayoutType(StructType) == nullptr && "layout type for this struct already exist"); LayoutTypes[StructType] = LayoutTy; @@ -1103,3 +1113,236 @@ std::optional CGHLSLRuntime::emitResourceArraySubscriptExpr( } return CGF.MakeAddrLValue(TmpVar, ResultTy, AlignmentSource::Decl); } + +std::optional CGHLSLRuntime::emitBufferArraySubscriptExpr( + const ArraySubscriptExpr *E, CodeGenFunction &CGF, + llvm::function_ref EmitIdxAfterBase) { + // Find the element type to index by first padding the element type per HLSL + // buffer rules, and then padding out to a 16-byte register boundary if + // necessary. + llvm::Type *LayoutTy = + HLSLBufferLayoutBuilder(CGF.CGM).layOutType(E->getType()); + uint64_t LayoutSizeInBits = + CGM.getDataLayout().getTypeSizeInBits(LayoutTy).getFixedValue(); + CharUnits ElementSize = CharUnits::fromQuantity(LayoutSizeInBits / 8); + CharUnits RowAlignedSize = ElementSize.alignTo(CharUnits::fromQuantity(16)); + if (RowAlignedSize > ElementSize) { + llvm::Type *Padding = CGM.getTargetCodeGenInfo().getHLSLPadding( + CGM, RowAlignedSize - ElementSize); + assert(Padding && "No padding type for target?"); + LayoutTy = llvm::StructType::get(CGF.getLLVMContext(), {LayoutTy, Padding}, + /*isPacked=*/true); + } + + // If the layout type doesn't introduce any padding, we don't need to do + // anything special. + llvm::Type *OrigTy = CGF.CGM.getTypes().ConvertTypeForMem(E->getType()); + if (LayoutTy == OrigTy) + return std::nullopt; + + LValueBaseInfo EltBaseInfo; + TBAAAccessInfo EltTBAAInfo; + Address Addr = + CGF.EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo); + llvm::Value *Idx = EmitIdxAfterBase(/*Promote*/ true); + + // Index into the object as-if we have an array of the padded element type, + // and then dereference the element itself to avoid reading padding that may + // be past the end of the in-memory object. + SmallVector Indices; + Indices.push_back(Idx); + Indices.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 0)); + + llvm::Value *GEP = CGF.Builder.CreateGEP(LayoutTy, Addr.emitRawPointer(CGF), + Indices, "cbufferidx"); + Addr = Address(GEP, Addr.getElementType(), RowAlignedSize, KnownNonNull); + + return CGF.MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo); +} + +namespace { +/// Utility for emitting copies following the HLSL buffer layout rules (ie, +/// copying out of a cbuffer). +class HLSLBufferCopyEmitter { + CodeGenFunction &CGF; + Address DestPtr; + Address SrcPtr; + llvm::Type *LayoutTy = nullptr; + + SmallVector CurStoreIndices; + SmallVector CurLoadIndices; + + void emitCopyAtIndices(llvm::Type *FieldTy, llvm::ConstantInt *StoreIndex, + llvm::ConstantInt *LoadIndex) { + CurStoreIndices.push_back(StoreIndex); + CurLoadIndices.push_back(LoadIndex); + auto RestoreIndices = llvm::make_scope_exit([&]() { + CurStoreIndices.pop_back(); + CurLoadIndices.pop_back(); + }); + + // First, see if this is some kind of aggregate and recurse. + if (processArray(FieldTy)) + return; + if (processBufferLayoutArray(FieldTy)) + return; + if (processStruct(FieldTy)) + return; + + // When we have a scalar or vector element we can emit the copy. + CharUnits Align = CharUnits::fromQuantity( + CGF.CGM.getDataLayout().getABITypeAlign(FieldTy)); + Address SrcGEP = RawAddress( + CGF.Builder.CreateInBoundsGEP(LayoutTy, SrcPtr.getBasePointer(), + CurLoadIndices, "cbuf.src"), + FieldTy, Align, SrcPtr.isKnownNonNull()); + Address DestGEP = CGF.Builder.CreateInBoundsGEP( + DestPtr, CurStoreIndices, FieldTy, Align, "cbuf.dest"); + llvm::Value *Load = CGF.Builder.CreateLoad(SrcGEP, "cbuf.load"); + CGF.Builder.CreateStore(Load, DestGEP); + } + + bool processArray(llvm::Type *FieldTy) { + auto *AT = dyn_cast(FieldTy); + if (!AT) + return false; + + // If we have an llvm::ArrayType this is just a regular array with no top + // level padding, so all we need to do is copy each member. + for (unsigned I = 0, E = AT->getNumElements(); I < E; ++I) + emitCopyAtIndices(AT->getElementType(), + llvm::ConstantInt::get(CGF.SizeTy, I), + llvm::ConstantInt::get(CGF.SizeTy, I)); + return true; + } + + bool processBufferLayoutArray(llvm::Type *FieldTy) { + // A buffer layout array is a struct with two elements: the padded array, + // and the last element. That is, is should look something like this: + // + // { [%n x { %type, %padding }], %type } + // + auto *ST = dyn_cast(FieldTy); + if (!ST || ST->getNumElements() != 2) + return false; + + auto *PaddedEltsTy = dyn_cast(ST->getElementType(0)); + if (!PaddedEltsTy) + return false; + + auto *PaddedTy = dyn_cast(PaddedEltsTy->getElementType()); + if (!PaddedTy || PaddedTy->getNumElements() != 2) + return false; + + if (!CGF.CGM.getTargetCodeGenInfo().isHLSLPadding( + PaddedTy->getElementType(1))) + return false; + + llvm::Type *ElementTy = ST->getElementType(1); + if (PaddedTy->getElementType(0) != ElementTy) + return false; + + // All but the last of the logical array elements are in the padded array. + unsigned NumElts = PaddedEltsTy->getNumElements() + 1; + + // Add an extra indirection to the load for the struct and walk the + // array prefix. + CurLoadIndices.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 0)); + for (unsigned I = 0; I < NumElts - 1; ++I) { + // We need to copy the element itself, without the padding. + CurLoadIndices.push_back(llvm::ConstantInt::get(CGF.SizeTy, I)); + emitCopyAtIndices(ElementTy, llvm::ConstantInt::get(CGF.SizeTy, I), + llvm::ConstantInt::get(CGF.Int32Ty, 0)); + CurLoadIndices.pop_back(); + } + CurLoadIndices.pop_back(); + + // Now copy the last element. + emitCopyAtIndices(ElementTy, + llvm::ConstantInt::get(CGF.SizeTy, NumElts - 1), + llvm::ConstantInt::get(CGF.Int32Ty, 1)); + + return true; + } + + bool processStruct(llvm::Type *FieldTy) { + auto *ST = dyn_cast(FieldTy); + if (!ST) + return false; + + // Copy the struct field by field, but skip any explicit padding. + unsigned Skipped = 0; + for (unsigned I = 0, E = ST->getNumElements(); I < E; ++I) { + llvm::Type *ElementTy = ST->getElementType(I); + if (CGF.CGM.getTargetCodeGenInfo().isHLSLPadding(ElementTy)) + ++Skipped; + else + emitCopyAtIndices(ElementTy, llvm::ConstantInt::get(CGF.Int32Ty, I), + llvm::ConstantInt::get(CGF.Int32Ty, I + Skipped)); + } + return true; + } + +public: + HLSLBufferCopyEmitter(CodeGenFunction &CGF, Address DestPtr, Address SrcPtr) + : CGF(CGF), DestPtr(DestPtr), SrcPtr(SrcPtr) {} + + bool emitCopy(QualType CType) { + LayoutTy = HLSLBufferLayoutBuilder(CGF.CGM).layOutType(CType); + + // TODO: We should be able to fall back to a regular memcpy if the layout + // type doesn't have any padding, but that runs into issues in the backend + // currently. + // + // See https://github.com/llvm/wg-hlsl/issues/351 + emitCopyAtIndices(LayoutTy, llvm::ConstantInt::get(CGF.SizeTy, 0), + llvm::ConstantInt::get(CGF.SizeTy, 0)); + return true; + } +}; +} // namespace + +bool CGHLSLRuntime::emitBufferCopy(CodeGenFunction &CGF, Address DestPtr, + Address SrcPtr, QualType CType) { + return HLSLBufferCopyEmitter(CGF, DestPtr, SrcPtr).emitCopy(CType); +} + +LValue CGHLSLRuntime::emitBufferMemberExpr(CodeGenFunction &CGF, + const MemberExpr *E) { + LValue Base = + CGF.EmitCheckedLValue(E->getBase(), CodeGenFunction::TCK_MemberAccess); + auto *Field = dyn_cast(E->getMemberDecl()); + assert(Field && "Unexpected access into HLSL buffer"); + + // Get the field index for the struct. + const RecordDecl *Rec = Field->getParent(); + unsigned FieldIdx = + CGM.getTypes().getCGRecordLayout(Rec).getLLVMFieldNo(Field); + + // Work out the buffer layout type to index into. + QualType RecType = CGM.getContext().getCanonicalTagType(Rec); + assert(RecType->isStructureOrClassType() && "Invalid type in HLSL buffer"); + // Since this is a member of an object in the buffer and not the buffer's + // struct/class itself, we shouldn't have any offsets on the members we need + // to contend with. + CGHLSLOffsetInfo EmptyOffsets; + llvm::StructType *LayoutTy = HLSLBufferLayoutBuilder(CGM).layOutStruct( + RecType->getAsCanonical(), EmptyOffsets); + + // Now index into the struct, making sure that the type we return is the + // buffer layout type rather than the original type in the AST. + QualType FieldType = Field->getType(); + llvm::Type *FieldLLVMTy = CGM.getTypes().ConvertTypeForMem(FieldType); + CharUnits Align = CharUnits::fromQuantity( + CGF.CGM.getDataLayout().getABITypeAlign(FieldLLVMTy)); + Address Addr(CGF.Builder.CreateStructGEP(LayoutTy, Base.getPointer(CGF), + FieldIdx, Field->getName()), + FieldLLVMTy, Align, KnownNonNull); + + LValue LV = LValue::MakeAddr(Addr, FieldType, CGM.getContext(), + LValueBaseInfo(AlignmentSource::Type), + CGM.getTBAAAccessInfo(FieldType)); + LV.getQuals().addCVRQualifiers(Base.getVRQualifiers()); + + return LV; +} diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index e1200c62eccf1..e6f3cc09819bd 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -15,20 +15,19 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H #define LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H -#include "llvm/ADT/DenseMap.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/IR/IntrinsicsDirectX.h" -#include "llvm/IR/IntrinsicsSPIRV.h" - +#include "Address.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/HLSLRuntime.h" - +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Frontend/HLSL/HLSLResource.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/IntrinsicsSPIRV.h" #include #include @@ -100,12 +99,19 @@ class CGHLSLOffsetInfo { /// of the HLSL buffer after all of the elements with specified offset. static CGHLSLOffsetInfo fromDecl(const HLSLBufferDecl &BufDecl); + /// Comparison function for offsets received from `operator[]` suitable for + /// use in a `stable_sort`. This will order implicit bindings after explicit + /// offsets. + static bool compareOffsets(uint32_t LHS, uint32_t RHS) { return LHS < RHS; } + /// Get the given offset, or `~0U` if there is no offset for the member. uint32_t operator[](size_t I) const { if (Offsets.empty()) return Unspecified; return Offsets[I]; } + + bool empty() const { return Offsets.empty(); } }; class CGHLSLRuntime { @@ -221,19 +227,28 @@ class CGHLSLRuntime { llvm::Instruction *getConvergenceToken(llvm::BasicBlock &BB); - llvm::TargetExtType * - getHLSLBufferLayoutType(const RecordType *LayoutStructTy); + llvm::StructType *getHLSLBufferLayoutType(const RecordType *LayoutStructTy); void addHLSLBufferLayoutType(const RecordType *LayoutStructTy, - llvm::TargetExtType *LayoutTy); + llvm::StructType *LayoutTy); void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E); std::optional emitResourceArraySubscriptExpr(const ArraySubscriptExpr *E, CodeGenFunction &CGF); + std::optional emitBufferArraySubscriptExpr( + const ArraySubscriptExpr *E, CodeGenFunction &CGF, + llvm::function_ref EmitIdxAfterBase); + + bool emitBufferCopy(CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, + QualType CType); + + LValue emitBufferMemberExpr(CodeGenFunction &CGF, const MemberExpr *E); + private: void emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl, - llvm::GlobalVariable *BufGV); + llvm::GlobalVariable *BufGV, + const CGHLSLOffsetInfo &OffsetInfo); void initializeBufferFromBinding(const HLSLBufferDecl *BufDecl, llvm::GlobalVariable *GV); void initializeBufferFromBinding(const HLSLBufferDecl *BufDecl, @@ -253,7 +268,7 @@ class CGHLSLRuntime { llvm::Triple::ArchType getArch(); - llvm::DenseMap LayoutTypes; + llvm::DenseMap LayoutTypes; unsigned SPIRVLastAssignedInputSemanticLocation = 0; }; diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp index 4bc6d565fd41f..07cc738882b50 100644 --- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp +++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp @@ -9,6 +9,7 @@ #include "HLSLBufferLayoutBuilder.h" #include "CGHLSLRuntime.h" #include "CodeGenModule.h" +#include "TargetInfo.h" #include "clang/AST/Type.h" #include @@ -19,72 +20,22 @@ using namespace clang; using namespace clang::CodeGen; -using llvm::hlsl::CBufferRowSizeInBytes; -namespace { - -// Creates a new array type with the same dimentions but with the new -// element type. -static llvm::Type * -createArrayWithNewElementType(CodeGenModule &CGM, - const ConstantArrayType *ArrayType, - llvm::Type *NewElemType) { - const clang::Type *ArrayElemType = ArrayType->getArrayElementTypeNoTypeQual(); - if (ArrayElemType->isConstantArrayType()) - NewElemType = createArrayWithNewElementType( - CGM, cast(ArrayElemType), NewElemType); - return llvm::ArrayType::get(NewElemType, ArrayType->getSExtSize()); -} - -// Returns the size of a scalar or vector in bytes -static unsigned getScalarOrVectorSizeInBytes(llvm::Type *Ty) { - assert(Ty->isVectorTy() || Ty->isIntegerTy() || Ty->isFloatingPointTy()); - if (Ty->isVectorTy()) { - llvm::FixedVectorType *FVT = cast(Ty); - return FVT->getNumElements() * - (FVT->getElementType()->getScalarSizeInBits() / 8); - } - return Ty->getScalarSizeInBits() / 8; -} - -} // namespace +static const CharUnits CBufferRowSize = + CharUnits::fromQuantity(llvm::hlsl::CBufferRowSizeInBytes); namespace clang { namespace CodeGen { -// Creates a layout type for given struct or class with HLSL constant buffer -// layout taking into account PackOffsets, if provided. -// Previously created layout types are cached by CGHLSLRuntime. -// -// The function iterates over all fields of the record type (including base -// classes) and calls layoutField to converts each field to its corresponding -// LLVM type and to calculate its HLSL constant buffer layout. Any embedded -// structs (or arrays of structs) are converted to target layout types as well. -// -// When PackOffsets are specified the elements will be placed based on the -// user-specified offsets. Not all elements must have a packoffset/register(c#) -// annotation though. For those that don't, the PackOffsets array will contain -// -1 value instead. These elements must be placed at the end of the layout -// after all of the elements with specific offset. -llvm::TargetExtType * -HLSLBufferLayoutBuilder::createLayoutType(const RecordType *RT, - const CGHLSLOffsetInfo &OffsetInfo) { +llvm::StructType * +HLSLBufferLayoutBuilder::layOutStruct(const RecordType *RT, + const CGHLSLOffsetInfo &OffsetInfo) { // check if we already have the layout type for this struct - if (llvm::TargetExtType *Ty = - CGM.getHLSLRuntime().getHLSLBufferLayoutType(RT)) + // TODO: Do we need to check for matching OffsetInfo? + if (llvm::StructType *Ty = CGM.getHLSLRuntime().getHLSLBufferLayoutType(RT)) return Ty; - SmallVector Layout; - SmallVector LayoutElements; - unsigned Index = 0; // packoffset index - unsigned EndOffset = 0; - - SmallVector> DelayLayoutFields; - - // reserve first spot in the layout vector for buffer size - Layout.push_back(0); - // iterate over all fields of the record, including fields on base classes llvm::SmallVector RecordDecls; RecordDecls.push_back(RT->castAsCXXRecordDecl()); @@ -95,187 +46,97 @@ HLSLBufferLayoutBuilder::createLayoutType(const RecordType *RT, RecordDecls.push_back(D->bases_begin()->getType()->castAsCXXRecordDecl()); } - unsigned FieldOffset; - llvm::Type *FieldType; - - while (!RecordDecls.empty()) { - const CXXRecordDecl *RD = RecordDecls.pop_back_val(); - - for (const auto *FD : RD->fields()) { - // No PackOffset info at all, or have a valid packoffset/register(c#) - // annotations value -> layout the field. - const uint32_t PO = OffsetInfo[Index++]; - if (PO != CGHLSLOffsetInfo::Unspecified) { - if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO)) - return nullptr; - Layout.push_back(FieldOffset); - LayoutElements.push_back(FieldType); - continue; - } - // Have PackOffset info, but there is no packoffset/register(cX) - // annotation on this field. Delay the layout until after all of the - // other elements with packoffsets/register(cX) are processed. - DelayLayoutFields.emplace_back(FD, LayoutElements.size()); - // reserve space for this field in the layout vector and elements list - Layout.push_back(UINT_MAX); - LayoutElements.push_back(nullptr); + SmallVector> FieldsWithOffset; + unsigned OffsetIdx = 0; + for (const CXXRecordDecl *RD : llvm::reverse(RecordDecls)) + for (const auto *FD : RD->fields()) + FieldsWithOffset.emplace_back(FD, OffsetInfo[OffsetIdx++]); + + if (!OffsetInfo.empty()) + llvm::stable_sort(FieldsWithOffset, [](const auto &LHS, const auto &RHS) { + return CGHLSLOffsetInfo::compareOffsets(LHS.second, RHS.second); + }); + + SmallVector Layout; + CharUnits CurrentOffset = CharUnits::Zero(); + for (auto &[FD, Offset] : FieldsWithOffset) { + llvm::Type *LayoutType = layOutType(FD->getType()); + + const llvm::DataLayout &DL = CGM.getDataLayout(); + CharUnits Size = + CharUnits::fromQuantity(DL.getTypeSizeInBits(LayoutType) / 8); + CharUnits Align = CharUnits::fromQuantity(DL.getABITypeAlign(LayoutType)); + + if (LayoutType->isAggregateType() || + (CurrentOffset % CBufferRowSize) + Size > CBufferRowSize) + Align = Align.alignTo(CBufferRowSize); + + CharUnits NextOffset = CurrentOffset.alignTo(Align); + + if (Offset != CGHLSLOffsetInfo::Unspecified) { + CharUnits PackOffset = CharUnits::fromQuantity(Offset); + assert(PackOffset >= NextOffset && + "Offset is invalid - would overlap with previous object"); + NextOffset = PackOffset; } - } - - // process delayed layouts - for (auto I : DelayLayoutFields) { - const FieldDecl *FD = I.first; - const unsigned IndexInLayoutElements = I.second; - // the first item in layout vector is size, so we need to offset the index - // by 1 - const unsigned IndexInLayout = IndexInLayoutElements + 1; - assert(Layout[IndexInLayout] == UINT_MAX && - LayoutElements[IndexInLayoutElements] == nullptr); - if (!layoutField(FD, EndOffset, FieldOffset, FieldType)) - return nullptr; - Layout[IndexInLayout] = FieldOffset; - LayoutElements[IndexInLayoutElements] = FieldType; + if (NextOffset > CurrentOffset) { + llvm::Type *Padding = CGM.getTargetCodeGenInfo().getHLSLPadding( + CGM, NextOffset - CurrentOffset); + assert(Padding && "No padding type for target?"); + Layout.emplace_back(Padding); + CurrentOffset = NextOffset; + } + Layout.emplace_back(LayoutType); + CurrentOffset += Size; } - // set the size of the buffer - Layout[0] = EndOffset; - - // create the layout struct type; anonymous struct have empty name but + // Create the layout struct type; anonymous structs have empty name but // non-empty qualified name const auto *Decl = RT->castAsCXXRecordDecl(); std::string Name = Decl->getName().empty() ? "anon" : Decl->getQualifiedNameAsString(); - llvm::StructType *StructTy = - llvm::StructType::create(LayoutElements, Name, true); - // create target layout type - llvm::TargetExtType *NewLayoutTy = llvm::TargetExtType::get( - CGM.getLLVMContext(), LayoutTypeName, {StructTy}, Layout); - if (NewLayoutTy) - CGM.getHLSLRuntime().addHLSLBufferLayoutType(RT, NewLayoutTy); - return NewLayoutTy; + llvm::StructType *NewTy = llvm::StructType::create(Layout, Name, + /*isPacked=*/true); + CGM.getHLSLRuntime().addHLSLBufferLayoutType(RT, NewTy); + return NewTy; } -// The function converts a single field of HLSL Buffer to its corresponding -// LLVM type and calculates it's layout. Any embedded structs (or -// arrays of structs) are converted to target layout types as well. -// The converted type is set to the FieldType parameter, the element -// offset is set to the FieldOffset parameter. The EndOffset (=size of the -// buffer) is also updated accordingly to the offset just after the placed -// element, unless the incoming EndOffset already larger (may happen in case -// of unsorted packoffset annotations). -// Returns true if the conversion was successful. -// The packoffset parameter contains the field's layout offset provided by the -// user or -1 if there was no packoffset (or register(cX)) annotation. -bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, - unsigned &EndOffset, - unsigned &FieldOffset, - llvm::Type *&FieldType, - uint32_t Packoffset) { - - // Size of element; for arrays this is a size of a single element in the - // array. Total array size of calculated as (ArrayCount-1) * ArrayStride + - // ElemSize. - unsigned ElemSize = 0; - unsigned ElemOffset = 0; - unsigned ArrayCount = 1; - unsigned ArrayStride = 0; - - unsigned NextRowOffset = llvm::alignTo(EndOffset, CBufferRowSizeInBytes); - - llvm::Type *ElemLayoutTy = nullptr; - QualType FieldTy = FD->getType(); +llvm::Type *HLSLBufferLayoutBuilder::layOutArray(const ConstantArrayType *AT) { + llvm::Type *EltTy = layOutType(AT->getElementType()); + uint64_t Count = AT->getZExtSize(); + + CharUnits EltSize = + CharUnits::fromQuantity(CGM.getDataLayout().getTypeSizeInBits(EltTy) / 8); + CharUnits Padding = EltSize.alignTo(CBufferRowSize) - EltSize; + + // If we don't have any padding between elements then we just need the array + // itself. + if (Count < 2 || Padding.isZero()) + return llvm::ArrayType::get(EltTy, Count); + + llvm::LLVMContext &Context = CGM.getLLVMContext(); + llvm::Type *PaddingTy = + CGM.getTargetCodeGenInfo().getHLSLPadding(CGM, Padding); + assert(PaddingTy && "No padding type for target?"); + auto *PaddedEltTy = + llvm::StructType::get(Context, {EltTy, PaddingTy}, /*isPacked=*/true); + return llvm::StructType::get( + Context, {llvm::ArrayType::get(PaddedEltTy, Count - 1), EltTy}, + /*IsPacked=*/true); +} - if (FieldTy->isConstantArrayType()) { - // Unwrap array to find the element type and get combined array size. - QualType Ty = FieldTy; - while (Ty->isConstantArrayType()) { - auto *ArrayTy = CGM.getContext().getAsConstantArrayType(Ty); - ArrayCount *= ArrayTy->getSExtSize(); - Ty = ArrayTy->getElementType(); - } - // For array of structures, create a new array with a layout type - // instead of the structure type. - if (Ty->isStructureOrClassType()) { - CGHLSLOffsetInfo EmptyOffsets; - llvm::Type *NewTy = cast( - createLayoutType(Ty->getAsCanonical(), EmptyOffsets)); - if (!NewTy) - return false; - assert(isa(NewTy) && "expected target type"); - ElemSize = cast(NewTy)->getIntParameter(0); - ElemLayoutTy = createArrayWithNewElementType( - CGM, cast(FieldTy.getTypePtr()), NewTy); - } else { - // Array of vectors or scalars - ElemSize = - getScalarOrVectorSizeInBytes(CGM.getTypes().ConvertTypeForMem(Ty)); - ElemLayoutTy = CGM.getTypes().ConvertTypeForMem(FieldTy); - } - ArrayStride = llvm::alignTo(ElemSize, CBufferRowSizeInBytes); - ElemOffset = (Packoffset != CGHLSLOffsetInfo::Unspecified) ? Packoffset - : NextRowOffset; +llvm::Type *HLSLBufferLayoutBuilder::layOutType(QualType Ty) { + if (const auto *AT = CGM.getContext().getAsConstantArrayType(Ty)) + return layOutArray(AT); - } else if (FieldTy->isStructureOrClassType()) { - // Create a layout type for the structure + if (Ty->isStructureOrClassType()) { CGHLSLOffsetInfo EmptyOffsets; - ElemLayoutTy = createLayoutType( - cast(FieldTy->getAsCanonical()), EmptyOffsets); - if (!ElemLayoutTy) - return false; - assert(isa(ElemLayoutTy) && "expected target type"); - ElemSize = cast(ElemLayoutTy)->getIntParameter(0); - ElemOffset = (Packoffset != CGHLSLOffsetInfo::Unspecified) ? Packoffset - : NextRowOffset; - - } else { - // scalar or vector - find element size and alignment - unsigned Align = 0; - ElemLayoutTy = CGM.getTypes().ConvertTypeForMem(FieldTy); - if (ElemLayoutTy->isVectorTy()) { - // align vectors by sub element size - const llvm::FixedVectorType *FVT = - cast(ElemLayoutTy); - unsigned SubElemSize = FVT->getElementType()->getScalarSizeInBits() / 8; - ElemSize = FVT->getNumElements() * SubElemSize; - Align = SubElemSize; - } else { - assert(ElemLayoutTy->isIntegerTy() || ElemLayoutTy->isFloatingPointTy()); - ElemSize = ElemLayoutTy->getScalarSizeInBits() / 8; - Align = ElemSize; - } - - // calculate or get element offset for the vector or scalar - if (Packoffset != CGHLSLOffsetInfo::Unspecified) { - ElemOffset = Packoffset; - } else { - ElemOffset = llvm::alignTo(EndOffset, Align); - // if the element does not fit, move it to the next row - if (ElemOffset + ElemSize > NextRowOffset) - ElemOffset = NextRowOffset; - } + return layOutStruct(Ty->getAsCanonical(), EmptyOffsets); } - // Update end offset of the layout; do not update it if the EndOffset - // is already bigger than the new value (which may happen with unordered - // packoffset annotations) - unsigned NewEndOffset = - ElemOffset + (ArrayCount - 1) * ArrayStride + ElemSize; - EndOffset = std::max(EndOffset, NewEndOffset); - - // add the layout element and offset to the lists - FieldOffset = ElemOffset; - FieldType = ElemLayoutTy; - return true; -} - -bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, - unsigned &EndOffset, - unsigned &FieldOffset, - llvm::Type *&FieldType) { - return layoutField(FD, EndOffset, FieldOffset, FieldType, - CGHLSLOffsetInfo::Unspecified); + return CGM.getTypes().ConvertTypeForMem(Ty); } } // namespace CodeGen diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h index 916e60e83e2c0..c55f680fe5a98 100644 --- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h +++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h @@ -6,16 +6,15 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/TypeBase.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DerivedTypes.h" namespace clang { -class RecordType; -class FieldDecl; - namespace CodeGen { class CGHLSLOffsetInfo; class CodeGenModule; +class CGHLSLOffsetInfo; //===----------------------------------------------------------------------===// // Implementation of constant buffer layout common between DirectX and @@ -25,24 +24,30 @@ class CodeGenModule; class HLSLBufferLayoutBuilder { private: CodeGenModule &CGM; - llvm::StringRef LayoutTypeName; public: - HLSLBufferLayoutBuilder(CodeGenModule &CGM, llvm::StringRef LayoutTypeName) - : CGM(CGM), LayoutTypeName(LayoutTypeName) {} - - // Returns LLVM target extension type with the name LayoutTypeName - // for given structure type and layout data. The first number in - // the Layout is the size followed by offsets for each struct element. - llvm::TargetExtType *createLayoutType(const RecordType *StructType, - const CGHLSLOffsetInfo &OffsetInfo); - -private: - bool layoutField(const clang::FieldDecl *FD, unsigned &EndOffset, - unsigned &FieldOffset, llvm::Type *&FieldType, - uint32_t Packoffset); - bool layoutField(const clang::FieldDecl *FD, unsigned &EndOffset, - unsigned &FieldOffset, llvm::Type *&FieldType); + HLSLBufferLayoutBuilder(CodeGenModule &CGM) : CGM(CGM) {} + + /// Lays out a struct type following HLSL buffer rules and considering any + /// explicit offset information. Previously created layout structs are cached + /// by CGHLSLRuntime. + /// + /// The function iterates over all fields of the record type (including base + /// classes) and works out a padded llvm type to represent the buffer layout. + /// + /// If a non-empty OffsetInfo is provided (ie, from `packoffset` annotations + /// in the source), any provided offsets offsets will be respected. If the + /// OffsetInfo is available but has empty entries, those will be layed out at + /// the end of the structure. + llvm::StructType *layOutStruct(const RecordType *StructType, + const CGHLSLOffsetInfo &OffsetInfo); + + /// Lays out an array type following HLSL buffer rules. + llvm::Type *layOutArray(const ConstantArrayType *AT); + + /// Lays out a type following HLSL buffer rules. Arrays and structures will be + /// padded appropriately and nested objects will be converted as appropriate. + llvm::Type *layOutType(QualType Type); }; } // namespace CodeGen diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 383f52f298d2e..db06584d766bf 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -38,6 +38,7 @@ namespace CodeGen { class ABIInfo; class CallArgList; class CodeGenFunction; +class CGHLSLOffsetInfo; class CGBlockInfo; class CGHLSLOffsetInfo; class SwiftABIInfo; @@ -448,6 +449,15 @@ class TargetCodeGenInfo { return nullptr; } + /// Return an LLVM type that corresponds to padding in HLSL types + virtual llvm::Type *getHLSLPadding(CodeGenModule &CGM, + CharUnits NumBytes) const { + return nullptr; + } + + /// Return true if this is an HLSL padding type. + virtual bool isHLSLPadding(llvm::Type *Ty) const { return false; } + // Set the Branch Protection Attributes of the Function accordingly to the // BPI. Remove attributes that contradict with current BPI. static void diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp index f30b30284cb12..a007c90881ab2 100644 --- a/clang/lib/CodeGen/Targets/DirectX.cpp +++ b/clang/lib/CodeGen/Targets/DirectX.cpp @@ -31,6 +31,19 @@ class DirectXTargetCodeGenInfo : public TargetCodeGenInfo { llvm::Type *getHLSLType(CodeGenModule &CGM, const Type *T, const CGHLSLOffsetInfo &OffsetInfo) const override; + + llvm::Type *getHLSLPadding(CodeGenModule &CGM, + CharUnits NumBytes) const override { + unsigned Size = NumBytes.getQuantity(); + return llvm::TargetExtType::get(CGM.getLLVMContext(), "dx.Padding", {}, + {Size}); + } + + bool isHLSLPadding(llvm::Type *Ty) const override { + if (auto *TET = dyn_cast(Ty)) + return TET->getName() == "dx.Padding"; + return false; + } }; llvm::Type *DirectXTargetCodeGenInfo::getHLSLType( @@ -74,10 +87,9 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType( if (ContainedTy.isNull() || !ContainedTy->isStructureType()) return nullptr; - llvm::Type *BufferLayoutTy = - HLSLBufferLayoutBuilder(CGM, "dx.Layout") - .createLayoutType(ContainedTy->castAsCanonical(), - OffsetInfo); + llvm::StructType *BufferLayoutTy = + HLSLBufferLayoutBuilder(CGM).layOutStruct( + ContainedTy->getAsCanonical(), OffsetInfo); if (!BufferLayoutTy) return nullptr; diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index be7e9ccecae9f..1a8c85d8871ec 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -55,6 +55,20 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo { llvm::Type *getOpenCLType(CodeGenModule &CGM, const Type *T) const override; llvm::Type *getHLSLType(CodeGenModule &CGM, const Type *Ty, const CGHLSLOffsetInfo &OffsetInfo) const override; + + llvm::Type *getHLSLPadding(CodeGenModule &CGM, + CharUnits NumBytes) const override { + unsigned Size = NumBytes.getQuantity(); + return llvm::TargetExtType::get(CGM.getLLVMContext(), "spirv.Padding", {}, + {Size}); + } + + bool isHLSLPadding(llvm::Type *Ty) const override { + if (auto *TET = dyn_cast(Ty)) + return TET->getName() == "spirv.Padding"; + return false; + } + llvm::Type *getSPIRVImageTypeFromHLSLResource( const HLSLAttributedResourceType::Attributes &attributes, QualType SampledType, CodeGenModule &CGM) const; @@ -563,10 +577,9 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType( if (ContainedTy.isNull() || !ContainedTy->isStructureType()) return nullptr; - llvm::Type *BufferLayoutTy = - HLSLBufferLayoutBuilder(CGM, "spirv.Layout") - .createLayoutType(ContainedTy->castAsCanonical(), - OffsetInfo); + llvm::StructType *BufferLayoutTy = + HLSLBufferLayoutBuilder(CGM).layOutStruct( + ContainedTy->getAsCanonical(), OffsetInfo); uint32_t StorageClass = /* Uniform storage class */ 2; return llvm::TargetExtType::get(Ctx, "spirv.VulkanBuffer", {BufferLayoutTy}, {StorageClass, false}); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp index 4178d1fd352c3..a3deb907c23ed 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp @@ -358,9 +358,8 @@ void sanitizeDiagOpts(DiagnosticOptions &DiagOpts) { } } // namespace -namespace clang::tooling::dependencies { std::unique_ptr -createDiagOptions(ArrayRef CommandLine) { +dependencies::createDiagOptions(ArrayRef CommandLine) { std::vector CLI; for (const std::string &Arg : CommandLine) CLI.push_back(Arg.c_str()); @@ -382,9 +381,10 @@ DignosticsEngineWithDiagOpts::DignosticsEngineWithDiagOpts( } std::pair, std::unique_ptr> -buildCompilation(ArrayRef ArgStrs, DiagnosticsEngine &Diags, - IntrusiveRefCntPtr FS, - llvm::BumpPtrAllocator &Alloc) { +dependencies::buildCompilation(ArrayRef ArgStrs, + DiagnosticsEngine &Diags, + IntrusiveRefCntPtr FS, + llvm::BumpPtrAllocator &Alloc) { SmallVector Argv; Argv.reserve(ArgStrs.size()); for (const std::string &Arg : ArgStrs) @@ -417,8 +417,8 @@ buildCompilation(ArrayRef ArgStrs, DiagnosticsEngine &Diags, } std::unique_ptr -createCompilerInvocation(ArrayRef CommandLine, - DiagnosticsEngine &Diags) { +dependencies::createCompilerInvocation(ArrayRef CommandLine, + DiagnosticsEngine &Diags) { llvm::opt::ArgStringList Argv; for (const std::string &Str : ArrayRef(CommandLine).drop_front()) Argv.push_back(Str.c_str()); @@ -432,10 +432,10 @@ createCompilerInvocation(ArrayRef CommandLine, } std::pair, std::vector> -initVFSForTUBuferScanning(IntrusiveRefCntPtr BaseFS, - ArrayRef CommandLine, - StringRef WorkingDirectory, - llvm::MemoryBufferRef TUBuffer) { +dependencies::initVFSForTUBuferScanning( + IntrusiveRefCntPtr BaseFS, + ArrayRef CommandLine, StringRef WorkingDirectory, + llvm::MemoryBufferRef TUBuffer) { // Reset what might have been modified in the previous worker invocation. BaseFS->setCurrentWorkingDirectory(WorkingDirectory); @@ -459,9 +459,10 @@ initVFSForTUBuferScanning(IntrusiveRefCntPtr BaseFS, std::pair, std::vector> -initVFSForByNameScanning(IntrusiveRefCntPtr BaseFS, - ArrayRef CommandLine, - StringRef WorkingDirectory, StringRef ModuleName) { +dependencies::initVFSForByNameScanning( + IntrusiveRefCntPtr BaseFS, + ArrayRef CommandLine, StringRef WorkingDirectory, + StringRef ModuleName) { // Reset what might have been modified in the previous worker invocation. BaseFS->setCurrentWorkingDirectory(WorkingDirectory); @@ -486,7 +487,7 @@ initVFSForByNameScanning(IntrusiveRefCntPtr BaseFS, return std::make_pair(OverlayFS, ModifiedCommandLine); } -bool initializeScanCompilerInstance( +bool dependencies::initializeScanCompilerInstance( CompilerInstance &ScanInstance, IntrusiveRefCntPtr FS, DiagnosticConsumer *DiagConsumer, DependencyScanningService &Service, @@ -559,7 +560,7 @@ bool initializeScanCompilerInstance( } llvm::SmallVector -getInitialStableDirs(const CompilerInstance &ScanInstance) { +dependencies::getInitialStableDirs(const CompilerInstance &ScanInstance) { // Create a collection of stable directories derived from the ScanInstance // for determining whether module dependencies would fully resolve from // those directories. @@ -571,8 +572,8 @@ getInitialStableDirs(const CompilerInstance &ScanInstance) { } std::optional -computePrebuiltModulesASTMap(CompilerInstance &ScanInstance, - llvm::SmallVector &StableDirs) { +dependencies::computePrebuiltModulesASTMap( + CompilerInstance &ScanInstance, llvm::SmallVector &StableDirs) { // Store a mapping of prebuilt module files and their properties like header // search options. This will prevent the implicit build to create duplicate // modules and will force reuse of the existing prebuilt module files @@ -590,7 +591,8 @@ computePrebuiltModulesASTMap(CompilerInstance &ScanInstance, } std::unique_ptr -takeAndUpdateDependencyOutputOptionsFrom(CompilerInstance &ScanInstance) { +dependencies::takeAndUpdateDependencyOutputOptionsFrom( + CompilerInstance &ScanInstance) { // This function moves the existing dependency output options from the // invocation to the collector. The options in the invocation are reset, // which ensures that the compiler won't create new dependency collectors, @@ -607,7 +609,8 @@ takeAndUpdateDependencyOutputOptionsFrom(CompilerInstance &ScanInstance) { return Opts; } -std::shared_ptr initializeScanInstanceDependencyCollector( +std::shared_ptr +dependencies::initializeScanInstanceDependencyCollector( CompilerInstance &ScanInstance, std::unique_ptr DepOutputOpts, StringRef WorkingDirectory, DependencyConsumer &Consumer, @@ -633,7 +636,6 @@ std::shared_ptr initializeScanInstanceDependencyCollector( return MDC; } -} // namespace clang::tooling::dependencies bool DependencyScanningAction::runInvocation( std::unique_ptr Invocation, diff --git a/clang/test/CIR/CodeGen/constant-inits.cpp b/clang/test/CIR/CodeGen/constant-inits.cpp index d5a7bb9d57251..ef9802de405c1 100644 --- a/clang/test/CIR/CodeGen/constant-inits.cpp +++ b/clang/test/CIR/CodeGen/constant-inits.cpp @@ -105,57 +105,57 @@ void function() { // CIR-DAG: !rec_anon_struct = !cir.record // CIR-DAG: !rec_anon_struct1 = !cir.record}> -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE1e = #cir.zero : !rec_empty -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE1s = #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : !s32i}> : !rec_simple -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE2p1 = #cir.const_record<{#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.const_array<[#cir.int<99> : !s8i, #cir.int<88> : !s8i, #cir.int<77> : !s8i]> : !cir.array, #cir.int<40> : !s32i}> : !rec_Point -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE2p2 = #cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : !s32i}> : !rec_packed -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE3paa = #cir.const_record<{#cir.int<1> : !s16i, #cir.int<2> : !s8i, #cir.fp<3.000000e+00> : !cir.float, #cir.zero : !u8i}> : !rec_packed_and_aligned +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE1e = #cir.zero : !rec_empty +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE1s = #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : !s32i}> : !rec_simple +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE2p1 = #cir.const_record<{#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.const_array<[#cir.int<99> : !s8i, #cir.int<88> : !s8i, #cir.int<77> : !s8i]> : !cir.array, #cir.int<40> : !s32i}> : !rec_Point +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE2p2 = #cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : !s32i}> : !rec_packed +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE3paa = #cir.const_record<{#cir.int<1> : !s16i, #cir.int<2> : !s8i, #cir.fp<3.000000e+00> : !cir.float, #cir.zero : !u8i}> : !rec_packed_and_aligned -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5array = #cir.const_array<[ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE5array = #cir.const_array<[ // CIR-DAG-SAME: #cir.const_record<{#cir.int<123> : !s32i, #cir.int<456> : !s32i, #cir.const_array<[#cir.int<11> : !s8i, #cir.int<22> : !s8i, #cir.int<33> : !s8i]> : !cir.array, #cir.int<789> : !s32i}> : !rec_Point // CIR-DAG-SAME: #cir.const_record<{#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.zero : !cir.array, #cir.int<40> : !s32i}> : !rec_Point // CIR-DAG-SAME: ]> : !cir.array -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE12simple_array = #cir.const_array<[ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE12simple_array = #cir.const_array<[ // CIR-DAG-SAME: #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : !s32i}> : !rec_simple, // CIR-DAG-SAME: #cir.const_record<{#cir.int<1111> : !s32i, #cir.int<2222> : !s32i}> : !rec_simple, // CIR-DAG-SAME: #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : !s32i}> : !rec_simple // CIR-DAG-SAME: ]> : !cir.array -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE12packed_array = #cir.const_array<[ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE12packed_array = #cir.const_array<[ // CIR-DAG-SAME: #cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : !s32i}> : !rec_packed, // CIR-DAG-SAME: #cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : !s32i}> : !rec_packed // CIR-DAG-SAME: ]> : !cir.array -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE9paa_array = #cir.const_array<[ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE9paa_array = #cir.const_array<[ // CIR-DAG-SAME: #cir.const_record<{#cir.int<1> : !s16i, #cir.int<2> : !s8i, #cir.fp<3.000000e+00> : !cir.float, #cir.zero : !u8i}> : !rec_packed_and_aligned, // CIR-DAG-SAME: #cir.zero : !rec_packed_and_aligned // CIR-DAG-SAME: ]> : !cir.array -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf1 = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE6ba_bf1 = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<255> : !u8i, // CIR-DAG-SAME: #cir.int<170> : !u8i, // CIR-DAG-SAME: #cir.int<52> : !u8i, // CIR-DAG-SAME: #cir.int<18> : !u8i // CIR-DAG-SAME: }> : !rec_anon_struct -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf2 = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE6ba_bf2 = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<255> : !u8i, // CIR-DAG-SAME: #cir.int<127> : !u8i, // CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array // CIR-DAG-SAME: }> : !rec_anon_struct1 -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf3 = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE6ba_bf3 = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<42> : !u8i // CIR-DAG-SAME: }> : !rec_single_byte_bitfield -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf1 = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE5p_bf1 = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<17> : !u8i, // CIR-DAG-SAME: #cir.int<3> : !u8i, // CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array // CIR-DAG-SAME: }> : !rec_anon_struct1 -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf2 = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE5p_bf2 = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<127> : !u8i, // CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array // CIR-DAG-SAME: }> : !rec_signed_partial_bitfields -// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf3 = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE5p_bf3 = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<125> : !u8i // CIR-DAG-SAME: }> : !rec_mixed_partial_bitfields @@ -163,21 +163,21 @@ void function() { // CIR: cir.return -// LLVM-DAG: @_ZZ8functionvE12packed_array = internal global [2 x %struct.packed] [%struct.packed <{ i8 123, i32 456 }>, %struct.packed <{ i8 123, i32 456 }>] -// LLVM-DAG: @_ZZ8functionvE12simple_array = internal global [3 x %struct.simple] [%struct.simple { i32 0, i32 -1 }, %struct.simple { i32 1111, i32 2222 }, %struct.simple { i32 0, i32 -1 }] -// LLVM-DAG: @_ZZ8functionvE1e = internal global %struct.empty zeroinitializer -// LLVM-DAG: @_ZZ8functionvE1s = internal global %struct.simple { i32 0, i32 -1 } -// LLVM-DAG: @_ZZ8functionvE2p1 = internal global %struct.Point { i32 10, i32 20, [3 x i8] c"cXM", i32 40 } -// LLVM-DAG: @_ZZ8functionvE2p2 = internal global %struct.packed <{ i8 123, i32 456 }> -// LLVM-DAG: @_ZZ8functionvE3paa = internal global %struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 0 }> -// LLVM-DAG: @_ZZ8functionvE5array = internal global [2 x %struct.Point] [%struct.Point { i32 123, i32 456, [3 x i8] c"\0B\16!", i32 789 }, %struct.Point { i32 10, i32 20, [3 x i8] zeroinitializer, i32 40 }] -// LLVM-DAG: @_ZZ8functionvE9paa_array = internal global [2 x %struct.packed_and_aligned] [%struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 0 }>, %struct.packed_and_aligned zeroinitializer] -// LLVM-DAG: @_ZZ8functionvE6ba_bf1 = internal global { i8, i8, i8, i8 } { i8 -1, i8 -86, i8 52, i8 18 } -// LLVM-DAG: @_ZZ8functionvE6ba_bf2 = internal global { i8, i8, [2 x i8] } { i8 -1, i8 127, [2 x i8] zeroinitializer } -// LLVM-DAG: @_ZZ8functionvE6ba_bf3 = internal global %struct.single_byte_bitfield { i8 42 } -// LLVM-DAG: @_ZZ8functionvE5p_bf1 = internal global { i8, i8, [2 x i8] } { i8 17, i8 3, [2 x i8] zeroinitializer } -// LLVM-DAG: @_ZZ8functionvE5p_bf2 = internal global %struct.signed_partial_bitfields { i8 127, [3 x i8] zeroinitializer } -// LLVM-DAG: @_ZZ8functionvE5p_bf3 = internal global %struct.mixed_partial_bitfields { i8 125 } +// LLVM-DAG: @_ZZ8functionvE12packed_array = internal constant [2 x %struct.packed] [%struct.packed <{ i8 123, i32 456 }>, %struct.packed <{ i8 123, i32 456 }>] +// LLVM-DAG: @_ZZ8functionvE12simple_array = internal constant [3 x %struct.simple] [%struct.simple { i32 0, i32 -1 }, %struct.simple { i32 1111, i32 2222 }, %struct.simple { i32 0, i32 -1 }] +// LLVM-DAG: @_ZZ8functionvE1e = internal constant %struct.empty zeroinitializer +// LLVM-DAG: @_ZZ8functionvE1s = internal constant %struct.simple { i32 0, i32 -1 } +// LLVM-DAG: @_ZZ8functionvE2p1 = internal constant %struct.Point { i32 10, i32 20, [3 x i8] c"cXM", i32 40 } +// LLVM-DAG: @_ZZ8functionvE2p2 = internal constant %struct.packed <{ i8 123, i32 456 }> +// LLVM-DAG: @_ZZ8functionvE3paa = internal constant %struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 0 }> +// LLVM-DAG: @_ZZ8functionvE5array = internal constant [2 x %struct.Point] [%struct.Point { i32 123, i32 456, [3 x i8] c"\0B\16!", i32 789 }, %struct.Point { i32 10, i32 20, [3 x i8] zeroinitializer, i32 40 }] +// LLVM-DAG: @_ZZ8functionvE9paa_array = internal constant [2 x %struct.packed_and_aligned] [%struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 0 }>, %struct.packed_and_aligned zeroinitializer] +// LLVM-DAG: @_ZZ8functionvE6ba_bf1 = internal constant { i8, i8, i8, i8 } { i8 -1, i8 -86, i8 52, i8 18 } +// LLVM-DAG: @_ZZ8functionvE6ba_bf2 = internal constant { i8, i8, [2 x i8] } { i8 -1, i8 127, [2 x i8] zeroinitializer } +// LLVM-DAG: @_ZZ8functionvE6ba_bf3 = internal constant %struct.single_byte_bitfield { i8 42 } +// LLVM-DAG: @_ZZ8functionvE5p_bf1 = internal constant { i8, i8, [2 x i8] } { i8 17, i8 3, [2 x i8] zeroinitializer } +// LLVM-DAG: @_ZZ8functionvE5p_bf2 = internal constant %struct.signed_partial_bitfields { i8 127, [3 x i8] zeroinitializer } +// LLVM-DAG: @_ZZ8functionvE5p_bf3 = internal constant %struct.mixed_partial_bitfields { i8 125 } // LLVM-LABEL: define{{.*}} void @_Z8functionv // LLVM: ret void diff --git a/clang/test/CIR/CodeGen/global-constant.c b/clang/test/CIR/CodeGen/global-constant.c new file mode 100644 index 0000000000000..588642c0c3faa --- /dev/null +++ b/clang/test/CIR/CodeGen/global-constant.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s + +const int global_no_use = 12; +// CIR: cir.global constant {{.*}}@global_no_use +// LLVM: @global_no_use = constant +// OGCG: @global_no_use = constant + +const float global_used = 1.2f; +// CIR: cir.global constant {{.*}}@global_used +// LLVM: @global_used = constant +// OGCG: @global_used = constant + +float const * get_float_ptr() { + return &global_used; +} diff --git a/clang/test/CIR/CodeGen/no-common.c b/clang/test/CIR/CodeGen/no-common.c new file mode 100644 index 0000000000000..ce4c5fc0b3a33 --- /dev/null +++ b/clang/test/CIR/CodeGen/no-common.c @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-cir -o %t-default.cir +// RUN: FileCheck --input-file=%t-default.cir %s -check-prefix=CIR-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-cir -o %t-no-common.cir +// RUN: FileCheck --input-file=%t-no-common.cir %s -check-prefix=CIR-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-cir -o %t-common.cir +// RUN: FileCheck --input-file=%t-common.cir %s -check-prefix=CIR-COMMON + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-llvm -o %t-default-cir.ll +// RUN: FileCheck --input-file=%t-default-cir.ll %s -check-prefix=LLVM-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-llvm -o %t-no-common-cir.ll +// RUN: FileCheck --input-file=%t-no-common-cir.ll %s -check-prefix=LLVM-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-llvm -o %t-common-cir.ll +// RUN: FileCheck --input-file=%t-common-cir.ll %s -check-prefix=LLVM-COMMON + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o %t-default.ll +// RUN: FileCheck --input-file=%t-default.ll %s -check-prefix=OGCG-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fno-common -emit-llvm -o %t-no-common.ll +// RUN: FileCheck --input-file=%t-no-common.ll %s -check-prefix=OGCG-DEFAULT +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fcommon -emit-llvm -o %t-common.ll +// RUN: FileCheck --input-file=%t-common.ll %s -check-prefix=OGCG-COMMON + +const int a = 42; +// CIR-DEFAULT: cir.global constant external @a = #cir.int<42> +// LLVM-DEFAULT: @a = constant i32 42 +// OGCG-DEFAULT: @a = constant i32 42 + +// CIR-COMMON: cir.global constant external @a +// LLVM-COMMON: @a = constant i32 42 +// OGCG-COMMON: @a = constant i32 42 + +const int b __attribute__((common)) = 42; +// CIR-DEFAULT: cir.global constant external @b = #cir.int<42> +// LLVM-DEFAULT: @b = constant i32 42 +// OGCG-DEFAULT: @b = constant i32 42 + +// CIR-COMMON: cir.global constant external @b = #cir.int<42> +// LLVM-COMMON: @b = constant i32 42 +// OGCG-COMMON: @b = constant i32 42 + +const int c __attribute__((nocommon)) = 42; +// CIR-DEFAULT: cir.global constant external @c = #cir.int<42> +// LLVM-DEFAULT: @c = constant i32 42 +// OGCG-DEFAULT: @c = constant i32 42 + +// CIR-COMMON: cir.global constant external @c = #cir.int<42> +// LLVM-COMMON: @c = constant i32 42 +// OGCG-COMMON: @c = constant i32 42 + +int d = 11; +// CIR-DEFAULT: cir.global external @d = #cir.int<11> +// LLVM-DEFAULT: @d = global i32 11 +// OGCG-DEFAULT: @d = global i32 11 + +// CIR-COMMON: cir.global external @d = #cir.int<11> +// LLVM-COMMON: @d = global i32 11 +// OGCG-COMMON: @d = global i32 11 + +int e; +// CIR-DEFAULT: cir.global external @e = #cir.int<0> +// LLVM-DEFAULT: @e = global i32 0 +// OGCG-DEFAULT: @e = global i32 0 + +// CIR-COMMON: cir.global common @e = #cir.int<0> +// LLVM-COMMON: @e = common global i32 0 +// OGCG-COMMON: @e = common global i32 0 + + +int f __attribute__((common)); +// CIR-DEFAULT: cir.global common @f = #cir.int<0> +// LLVM-DEFAULT: @f = common global i32 0 +// OGCG-DEFAULT: @f = common global i32 0 + +// CIR-COMMON: cir.global common @f +// LLVM-COMMON: @f = common global i32 0 +// OGCG-COMMON: @f = common global i32 0 + +int g __attribute__((nocommon)); +// CIR-DEFAULT: cir.global external @g = #cir.int<0> +// LLVM-DEFAULT: @g = global i32 +// OGCG-DEFAULT: @g = global i32 0 + +// CIR-COMMON: cir.global external @g = #cir.int<0> +// LLVM-COMMON: @g = global i32 0 +// OGCG-COMMON: @g = global i32 0 + +const int h; +// CIR-DEFAULT: cir.global constant external @h = #cir.int<0> +// LLVM-DEFAULT: @h = constant i32 +// OGCG-DEFAULT: @h = constant i32 0 + +// CIR-COMMON: cir.global common @h = #cir.int<0> +// LLVM-COMMON: @h = common global i32 0 +// OGCG-COMMON: @h = common global i32 0 + +typedef void* (*fn_t)(long a, long b, char *f, int c); +fn_t ABC __attribute__ ((nocommon)); +// CIR-DEFAULT: cir.global external @ABC = #cir.ptr +// LLVM-DEFAULT: @ABC = global ptr null +// OGCG-DEFAULT: @ABC = global ptr null + +// CIR-COMMON: cir.global external @ABC = #cir.ptr +// LLVM-COMMON: @ABC = global ptr null +// OGCG-COMMON: @ABC = global ptr null diff --git a/clang/test/CIR/CodeGen/record-zero-init-padding.c b/clang/test/CIR/CodeGen/record-zero-init-padding.c index f131c9bbd069f..9c8daccb21a53 100644 --- a/clang/test/CIR/CodeGen/record-zero-init-padding.c +++ b/clang/test/CIR/CodeGen/record-zero-init-padding.c @@ -41,28 +41,28 @@ void test_zero_init_padding(void) { // CIR-DAG: !rec_anon_struct3 = !cir.record, !s32i}> // paf: char + 3 bytes padding + int -> uses !rec_anon_struct3 -// CIR-DAG: cir.global "private" internal dso_local @test_zero_init_padding.paf = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @test_zero_init_padding.paf = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<1> : !s8i, // CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array, // CIR-DAG-SAME: #cir.int<42> : !s32i // CIR-DAG-SAME: }> : !rec_anon_struct3 // bfp: unsigned bitfield byte + 3 bytes padding + int -> uses !rec_anon_struct2 -// CIR-DAG: cir.global "private" internal dso_local @test_zero_init_padding.bfp = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @test_zero_init_padding.bfp = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<17> : !u8i, // CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array, // CIR-DAG-SAME: #cir.int<99> : !s32i // CIR-DAG-SAME: }> : !rec_anon_struct2 // tp: int + char + 3 bytes tail padding -> uses !rec_anon_struct1 -// CIR-DAG: cir.global "private" internal dso_local @test_zero_init_padding.tp = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @test_zero_init_padding.tp = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<10> : !s32i, // CIR-DAG-SAME: #cir.int<20> : !s8i, // CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array // CIR-DAG-SAME: }> : !rec_anon_struct1 // mp: char + 1 byte padding + short + 4 bytes padding + long long -> uses !rec_anon_struct -// CIR-DAG: cir.global "private" internal dso_local @test_zero_init_padding.mp = #cir.const_record<{ +// CIR-DAG: cir.global "private" constant internal dso_local @test_zero_init_padding.mp = #cir.const_record<{ // CIR-DAG-SAME: #cir.int<5> : !s8i, // CIR-DAG-SAME: #cir.zero : !u8i, // CIR-DAG-SAME: #cir.int<10> : !s16i, @@ -73,10 +73,10 @@ void test_zero_init_padding(void) { // CIR-LABEL: cir.func {{.*}}@test_zero_init_padding // CIR: cir.return -// LLVM-DAG: @test_zero_init_padding.paf = internal global { i8, [3 x i8], i32 } { i8 1, [3 x i8] zeroinitializer, i32 42 } -// LLVM-DAG: @test_zero_init_padding.bfp = internal global { i8, [3 x i8], i32 } { i8 17, [3 x i8] zeroinitializer, i32 99 } -// LLVM-DAG: @test_zero_init_padding.tp = internal global { i32, i8, [3 x i8] } { i32 10, i8 20, [3 x i8] zeroinitializer } -// LLVM-DAG: @test_zero_init_padding.mp = internal global { i8, i8, i16, [4 x i8], i64 } { i8 5, i8 0, i16 10, [4 x i8] zeroinitializer, i64 100 } +// LLVM-DAG: @test_zero_init_padding.paf = internal constant { i8, [3 x i8], i32 } { i8 1, [3 x i8] zeroinitializer, i32 42 } +// LLVM-DAG: @test_zero_init_padding.bfp = internal constant { i8, [3 x i8], i32 } { i8 17, [3 x i8] zeroinitializer, i32 99 } +// LLVM-DAG: @test_zero_init_padding.tp = internal constant { i32, i8, [3 x i8] } { i32 10, i8 20, [3 x i8] zeroinitializer } +// LLVM-DAG: @test_zero_init_padding.mp = internal constant { i8, i8, i16, [4 x i8], i64 } { i8 5, i8 0, i16 10, [4 x i8] zeroinitializer, i64 100 } // LLVM-LABEL: define{{.*}} void @test_zero_init_padding // LLVM: ret void diff --git a/clang/test/CIR/CodeGen/vtt.cpp b/clang/test/CIR/CodeGen/vtt.cpp index f9a62e37450cf..d0319b7adc126 100644 --- a/clang/test/CIR/CodeGen/vtt.cpp +++ b/clang/test/CIR/CodeGen/vtt.cpp @@ -5,12 +5,12 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fno-rtti -emit-llvm %s -o %t.ll // RUN: FileCheck --check-prefixes=OGCG-NO-RTTI,OGCG-COMMON --input-file=%t.ll %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -// RUN: FileCheck --check-prefixes=CIR-RTTI,CIR-COMMON --input-file=%t.cir %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll -// RUN: FileCheck --check-prefixes=LLVM-RTTI,LLVM-COMMON --input-file=%t-cir.ll %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll -// RUN: FileCheck --check-prefixes=OGCG-RTTI,OGCG-COMMON --input-file=%t.ll %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t-rtti.cir +// RUN: FileCheck --check-prefixes=CIR-RTTI,CIR-COMMON --input-file=%t-rtti.cir %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir-rtti.ll +// RUN: FileCheck --check-prefixes=LLVM-RTTI,LLVM-COMMON --input-file=%t-cir-rtti.ll %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t-rtti.ll +// RUN: FileCheck --check-prefixes=OGCG-RTTI,OGCG-COMMON --input-file=%t-rtti.ll %s // Note: This test will be expanded to verify VTT emission and VTT implicit // argument handling. For now, it's just test the record layout. @@ -170,7 +170,7 @@ void D::y() {} // CIR-RTTI: cir.global{{.*}} @_ZTI1B : !cir.ptr -// LLVM-RTTI: @_ZTI1B = external global ptr +// LLVM-RTTI: @_ZTI1B = external constant ptr // OGCG-RTTI: @_ZTI1B = external constant ptr diff --git a/clang/test/ClangScanDeps/module-in-stable-dir-by-name.c b/clang/test/ClangScanDeps/module-in-stable-dir-by-name.c new file mode 100644 index 0000000000000..742bc2e046ceb --- /dev/null +++ b/clang/test/ClangScanDeps/module-in-stable-dir-by-name.c @@ -0,0 +1,43 @@ +// UNSUPPORTED: system-windows +// RUN: rm -rf %t +// RUN: split-file %s %t + +// Verify the stable dir path. +//--- Sysroot/usr/include/SysA/module.modulemap +module SysA { + header "SysA.h" +} + +//--- Sysroot/usr/include/SysA/SysA.h +int SysVal = 42; + +//--- cdb.json.template +[{ + "file": "", + "directory": "DIR", + "command": "clang -fmodules -fmodules-cache-path=DIR/cache -isysroot DIR/Sysroot -IDIR/Sysroot/usr/include -x c" +}] + +// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -module-names=SysA > %t/result.json +// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "is-in-stable-directories": true, +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/Sysroot/usr/include/SysA/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/Sysroot/usr/include/SysA/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/Sysroot/usr/include/SysA/SysA.h" +// CHECK-NEXT: ], +// CHECK-NEXT: "link-libraries": [], +// CHECK-NEXT: "name": "SysA" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "translation-units": [] +// CHECK-NEXT: } diff --git a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl index aaa486eff10b7..d1bfc6db8b504 100644 --- a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl +++ b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl @@ -5,18 +5,19 @@ struct S { float f; }; -// CHECK: [[CBLayout:%.*]] = type <{ [2 x float], [2 x <4 x i32>], [2 x [2 x i32]], [1 x target("dx.Layout", %S, 8, 0, 4)] }> -// CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", [[CBLayout]], 136, 0, 32, 64, 128)) -// CHECK: @c1 = external hidden addrspace(2) global [2 x float], align 4 +// CHECK: [[CBLayout:%.*]] = type <{ <{ [1 x <{ float, target("dx.Padding", 12) }>], float }>, target("dx.Padding", 12), [2 x <4 x i32>], <{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, target("dx.Padding", 12), <{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }> }> + +// CHECK: @CBArrays.cb = global target("dx.CBuffer", [[CBLayout]]) +// CHECK: @c1 = external hidden addrspace(2) global <{ [1 x <{ float, target("dx.Padding", 12) }>], float }>, align 4 // CHECK: @c2 = external hidden addrspace(2) global [2 x <4 x i32>], align 16 -// CHECK: @c3 = external hidden addrspace(2) global [2 x [2 x i32]], align 4 -// CHECK: @c4 = external hidden addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 1 +// CHECK: @c3 = external hidden addrspace(2) global <{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, align 4 +// CHECK: @c4 = external hidden addrspace(2) global <{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, align 1 cbuffer CBArrays : register(b0) { float c1[2]; int4 c2[2]; int c3[2][2]; - S c4[1]; + S c4[2]; } // CHECK-LABEL: define hidden void {{.*}}arr_assign1 @@ -140,40 +141,71 @@ void arr_assign7() { // CHECK-LABEL: define hidden void {{.*}}arr_assign8 // CHECK: [[C:%.*]] = alloca [2 x float], align 4 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 8, i1 false) -// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c1, i32 8, i1 false) +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x float], ptr [[C]], i32 0 +// CHECK-NEXT: [[L0:%.*]] = load float, ptr addrspace(2) @c1, align 4 +// CHECK-NEXT: store float [[L0]], ptr [[V0]], align 4 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x float], ptr [[C]], i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load float, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ float, target("dx.Padding", 12) }>], float }>, ptr addrspace(2) @c1, i32 0, i32 1), align 4 +// CHECK-NEXT: store float [[L1]], ptr [[V1]], align 4 // CHECK-NEXT: ret void void arr_assign8() { - float C[2] = {1.0, 2.0}; + float C[2]; C = c1; } +// TODO: We should be able to just memcpy here. +// See https://github.com/llvm/wg-hlsl/issues/351 +// // CHECK-LABEL: define hidden void {{.*}}arr_assign9 // CHECK: [[C:%.*]] = alloca [2 x <4 x i32>], align 16 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[C]], ptr align 16 {{.*}}, i32 32, i1 false) -// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 16 [[C]], ptr addrspace(2) align 16 @c2, i32 32, i1 false) +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x <4 x i32>], ptr [[C]], i32 0 +// CHECK-NEXT: [[L0:%.*]] = load <4 x i32>, ptr addrspace(2) @c2, align 16 +// CHECK-NEXT: store <4 x i32> [[L0]], ptr [[V0]], align 16 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x <4 x i32>], ptr [[C]], i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load <4 x i32>, ptr addrspace(2) getelementptr inbounds ([2 x <4 x i32>], ptr addrspace(2) @c2, i32 0, i32 1), align 16 +// CHECK-NEXT: store <4 x i32> [[L1]], ptr [[V1]], align 16 // CHECK-NEXT: ret void void arr_assign9() { - int4 C[2] = {1,2,3,4,5,6,7,8}; + int4 C[2]; C = c2; } // CHECK-LABEL: define hidden void {{.*}}arr_assign10 // CHECK: [[C:%.*]] = alloca [2 x [2 x i32]], align 4 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 16, i1 false) -// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c3, i32 16, i1 false) +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[L0:%.*]] = load i32, ptr addrspace(2) @c3, align 4 +// CHECK-NEXT: store i32 [[L0]], ptr [[V0]], align 4 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, ptr addrspace(2) @c3, i32 0, i32 0, i32 0, i32 0, i32 1), align 4 +// CHECK-NEXT: store i32 [[L1]], ptr [[V1]], align 4 +// CHECK-NEXT: [[V2:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 1, i32 0 +// CHECK-NEXT: [[L2:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, ptr addrspace(2) @c3, i32 0, i32 1, i32 0, i32 0, i32 0), align 4 +// CHECK-NEXT: store i32 [[L2]], ptr [[V2]], align 4 +// CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 1, i32 1 +// CHECK-NEXT: [[L3:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, ptr addrspace(2) @c3, i32 0, i32 1, i32 1), align 4 +// CHECK-NEXT: store i32 [[L3]], ptr [[V3]], align 4 // CHECK-NEXT: ret void void arr_assign10() { - int C[2][2] = {1,2,3,4}; + int C[2][2]; C = c3; } // CHECK-LABEL: define hidden void {{.*}}arr_assign11 -// CHECK: [[C:%.*]] = alloca [1 x %struct.S], align 1 -// CHECK: call void @llvm.memcpy.p0.p2.i32(ptr align 1 [[C]], ptr addrspace(2) align 1 @c4, i32 8, i1 false) +// CHECK: [[C:%.*]] = alloca [2 x %struct.S], align 1 +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[L0:%.*]] = load i32, ptr addrspace(2) @c4, align 4 +// CHECK-NEXT: store i32 [[L0]], ptr [[V0]], align 4 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load float, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, ptr addrspace(2) @c4, i32 0, i32 0, i32 0, i32 0, i32 1), align 4 +// CHECK-NEXT: store float [[L1]], ptr [[V1]], align 4 +// CHECK-NEXT: [[V2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 1, i32 0 +// CHECK-NEXT: [[L2:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, ptr addrspace(2) @c4, i32 0, i32 1, i32 0), align 4 +// CHECK-NEXT: store i32 [[L2]], ptr [[V2]], align 4 +// CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 1, i32 1 +// CHECK-NEXT: [[L3:%.*]] = load float, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, ptr addrspace(2) @c4, i32 0, i32 1, i32 1), align 4 +// CHECK-NEXT: store float [[L3]], ptr [[V3]], align 4 // CHECK-NEXT: ret void void arr_assign11() { - S s = {1, 2.0}; - S C[1] = {s}; + S C[2]; C = c4; } diff --git a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl index b36682e065b3a..5553f8c17c6c8 100644 --- a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl +++ b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl @@ -37,9 +37,8 @@ void main(unsigned GI : SV_GroupIndex) {} // INLINE-NEXT: alloca // INLINE-NEXT: store i32 12 // INLINE-NEXT: store i32 13 -// INLINE-NEXT: %[[HANDLE:.*]] = call target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 4, 0)) -// INLINE-NEXT-SAME: @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_$Globalss_4_0tt"(i32 0, i32 0, i32 1, i32 0, i1 false) -// INLINE-NEXT: store target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 4, 0)) %[[HANDLE]], ptr @"$Globals.cb", align 4 +// INLINE-NEXT: %[[HANDLE:.*]] = call target("dx.CBuffer", %"__cblayout_$Globals") @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_$Globalsst"(i32 0, i32 0, i32 1, i32 0, ptr @"$Globals.str") +// INLINE-NEXT: store target("dx.CBuffer", %"__cblayout_$Globals") %[[HANDLE]], ptr @"$Globals.cb", align 4 // INLINE-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group() // INLINE-NEXT: store i32 % // INLINE-NEXT: store i32 0 diff --git a/clang/test/CodeGenHLSL/resources/cbuffer.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer.hlsl index c8efe0d64c985..b72cf587d0f93 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer.hlsl @@ -1,37 +1,123 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -fnative-half-type -fnative-int16-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -// CHECK: %__cblayout_CBScalars = type <{ float, double, half, i64, i32, i16, i32, i64 }> -// CHECK: %__cblayout_CBVectors = type <{ <3 x float>, <3 x double>, <2 x half>, <3 x i64>, <4 x i32>, <3 x i16>, <3 x i64> }> -// CHECK: %__cblayout_CBArrays = type <{ [3 x float], [2 x <3 x double>], [2 x [2 x half]], [3 x i64], [2 x [3 x [4 x <4 x i32>]]], [1 x i16], [2 x i64], [4 x i32] }> -// CHECK: %__cblayout_CBStructs = type <{ target("dx.Layout", %A, 8, 0), target("dx.Layout", %B, 14, 0, 8), -// CHECK-SAME: target("dx.Layout", %C, 24, 0, 16), [5 x target("dx.Layout", %A, 8, 0)], -// CHECK-SAME: target("dx.Layout", %__cblayout_D, 94, 0), half, <3 x i16> }> +// CHECK: %__cblayout_CBScalars = type <{ +// CHECK-SAME: float, target("dx.Padding", 4), double, +// CHECK-SAME: half, target("dx.Padding", 6), i64, +// CHECK-SAME: i32, i16, target("dx.Padding", 2), i32, target("dx.Padding", 4), +// CHECK-SAME: i64 +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBVectors = type <{ +// CHECK-SAME: <3 x float>, target("dx.Padding", 4), +// CHECK-SAME: <3 x double>, <2 x half>, target("dx.Padding", 4), +// CHECK-SAME: <3 x i64>, target("dx.Padding", 8), +// CHECK-SAME: <4 x i32>, +// CHECK-SAME: <3 x i16>, target("dx.Padding", 10), +// CHECK-SAME: <3 x i64> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBArrays = type <{ +// CHECK-SAME: <{ [2 x <{ float, target("dx.Padding", 12) }>], float }>, target("dx.Padding", 12), +// CHECK-SAME: <{ [1 x <{ <3 x double>, target("dx.Padding", 8) }>], <3 x double> }>, target("dx.Padding", 8), +// CHECK-SAME: <{ [1 x <{ +// CHECK-SAME: <{ [1 x <{ half, target("dx.Padding", 14) }>], half }>, target("dx.Padding", 14) }>], +// CHECK-SAME: <{ [1 x <{ half, target("dx.Padding", 14) }>], half }> +// CHECK-SAME: }>, target("dx.Padding", 14), +// CHECK-SAME: <{ [2 x <{ i64, target("dx.Padding", 8) }>], i64 }>, target("dx.Padding", 8), +// CHECK-SAME: [2 x [3 x [4 x <4 x i32>]]] +// CHECK-SAME: [1 x i16], target("dx.Padding", 14), +// CHECK-SAME: <{ [1 x <{ i64, target("dx.Padding", 8) }>], i64 }>, target("dx.Padding", 8), +// CHECK-SAME: <{ [3 x <{ i32, target("dx.Padding", 12) }>], i32 }> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBStructs = type <{ +// CHECK-SAME: %A, target("dx.Padding", 8), + +// TODO: We should have target("dx.Padding", 2) padding after %B, but we don't +// correctly handle 2- and 3-element vectors inside structs yet because of +// DataLayout rules. See https://github.com/llvm/llvm-project/issues/123968. +// +// CHECK-SAME: %B, + +// CHECK-SAME: %C, target("dx.Padding", 8), +// CHECK-SAME: <{ [4 x <{ %A, target("dx.Padding", 8) }>], %A }>, target("dx.Padding", 8), +// CHECK-SAME: %__cblayout_D, half, +// CHECK-SAME: <3 x i16> +// CHECK-SAME: }> // CHECK: %A = type <{ <2 x float> }> // CHECK: %B = type <{ <2 x float>, <3 x i16> }> -// CHECK: %C = type <{ i32, target("dx.Layout", %A, 8, 0) }> -// CHECK: %__cblayout_D = type <{ [2 x [3 x target("dx.Layout", %B, 14, 0, 8)]] }> +// CHECK: %C = type <{ i32, target("dx.Padding", 12), %A }> + +// CHECK: %__cblayout_D = type <{ +// CHECK-SAME: <{ [1 x <{ +// CHECK-SAME: <{ [2 x <{ %B, target("dx.Padding", 2) }>], %B }>, target("dx.Padding", 2) +// CHECK-SAME: }>], +// CHECK-SAME: <{ [2 x <{ %B, target("dx.Padding", 2) }>], %B }> }> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBClasses = type <{ +// CHECK-SAME: %K, target("dx.Padding", 12), +// CHECK-SAME: %L, target("dx.Padding", 8), +// CHECK-SAME: %M, target("dx.Padding", 12), +// CHECK-SAME: <{ [9 x <{ %K, target("dx.Padding", 12) }>], %K }> +// CHECK-SAME: }> -// CHECK: %__cblayout_CBClasses = type <{ target("dx.Layout", %K, 4, 0), target("dx.Layout", %L, 8, 0, 4), -// CHECK-SAME: target("dx.Layout", %M, 68, 0), [10 x target("dx.Layout", %K, 4, 0)] }> // CHECK: %K = type <{ float }> // CHECK: %L = type <{ float, float }> -// CHECK: %M = type <{ [5 x target("dx.Layout", %K, 4, 0)] }> - -// CHECK: %__cblayout_CBMix = type <{ [2 x target("dx.Layout", %Test, 8, 0, 4)], float, [3 x [2 x <2 x float>]], float, -// CHECK-SAME: target("dx.Layout", %anon, 4, 0), double, target("dx.Layout", %anon.0, 8, 0), float, <1 x double>, i16 }> +// CHECK: %M = type <{ <{ [4 x <{ %K, target("dx.Padding", 12) }>], %K }> }> + +// CHECK: %__cblayout_CBMix = type <{ +// CHECK-SAME: <{ [1 x <{ %Test, target("dx.Padding", 8) }>], %Test }>, float, target("dx.Padding", 4) +// CHECK-SAME: <{ [2 x <{ +// CHECK-SAME: <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }>, target("dx.Padding", 8) }>], +// CHECK-SAME: <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }> +// CHECK-SAME: }>, float, target("dx.Padding", 4), +// CHECK-SAME: %anon, target("dx.Padding", 4), double, +// CHECK-SAME: %anon.0, float, target("dx.Padding", 4), +// CHECK-SAME: <1 x double>, i16 +// CHECK-SAME: }> // CHECK: %Test = type <{ float, float }> // CHECK: %anon = type <{ float }> // CHECK: %anon.0 = type <{ <2 x i32> }> -// CHECK: %__cblayout_CB_A = type <{ [2 x double], [3 x <3 x float>], float, [3 x double], half, [1 x <2 x double>], float, [2 x <3 x half>], <3 x half> }> -// CHECK: %__cblayout_CB_B = type <{ [3 x <3 x double>], <3 x half> }> -// CHECK: %__cblayout_CB_C = type <{ i32, target("dx.Layout", %F, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90), half, target("dx.Layout", %G, 258, 0, 48, 64, 256), double }> - -// CHECK: %F = type <{ double, <3 x float>, float, <3 x double>, half, <2 x double>, float, <3 x half>, <3 x half> }> -// CHECK: %G = type <{ target("dx.Layout", %E, 36, 0, 8, 16, 20, 22, 24, 32), [1 x float], [2 x target("dx.Layout", %F, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90)], half }> -// CHECK: %E = type <{ float, double, float, half, i16, i64, i32 }> +// CHECK: %__cblayout_CB_A = type <{ +// CHECK-SAME: <{ [1 x <{ double, target("dx.Padding", 8) }>], double }>, target("dx.Padding", 8), +// CHECK-SAME: <{ [2 x <{ <3 x float>, target("dx.Padding", 4) }>], <3 x float> }>, float, +// CHECK-SAME: <{ [2 x <{ double, target("dx.Padding", 8) }>], double }>, half, target("dx.Padding", 6), +// CHECK-SAME: [1 x <2 x double>], +// CHECK-SAME: float, target("dx.Padding", 12), +// CHECK-SAME: <{ [1 x <{ <3 x half>, target("dx.Padding", 10) }>], <3 x half> }>, <3 x half> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CB_B = type <{ +// CHECK-SAME: <{ [2 x <{ <3 x double>, target("dx.Padding", 8) }>], <3 x double> }>, <3 x half> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CB_C = type <{ +// CHECK-SAME: i32, target("dx.Padding", 12), +// CHECK-SAME: %F, +// CHECK-SAME: half, target("dx.Padding", 14), +// CHECK-SAME: %G, target("dx.Padding", 6), double +// CHECK-SAME: }> + +// CHECK: %F = type <{ +// CHECK-SAME: double, target("dx.Padding", 8), +// CHECK-SAME: <3 x float>, float, +// CHECK-SAME: <3 x double>, half, target("dx.Padding", 6), +// CHECK-SAME: <2 x double>, +// CHECK-SAME: float, <3 x half>, <3 x half> +// CHECK-SAME: }> + +// CHECK: %G = type <{ +// CHECK-SAME: %E, target("dx.Padding", 12), +// CHECK-SAME: [1 x float], target("dx.Padding", 12), +// CHECK-SAME: [2 x %F], +// CHECK-SAME: half +// CHECK-SAME: }> + +// CHECK: %E = type <{ float, target("dx.Padding", 4), double, float, half, i16, i64, i32 }> cbuffer CBScalars : register(b1, space5) { float a1; @@ -44,8 +130,7 @@ cbuffer CBScalars : register(b1, space5) { int64_t a8; } -// CHECK: @CBScalars.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBScalars, -// CHECK-SAME: 56, 0, 8, 16, 24, 32, 36, 40, 48)) +// CHECK: @CBScalars.cb = global target("dx.CBuffer", %__cblayout_CBScalars) // CHECK: @a1 = external hidden addrspace(2) global float, align 4 // CHECK: @a2 = external hidden addrspace(2) global double, align 8 // CHECK: @a3 = external hidden addrspace(2) global half, align 2 @@ -67,8 +152,7 @@ cbuffer CBVectors { // FIXME: add a bool vectors after llvm-project/llvm#91639 is added } -// CHECK: @CBVectors.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBVectors, -// CHECK-SAME: 136, 0, 16, 40, 48, 80, 96, 112)) +// CHECK: @CBVectors.cb = global target("dx.CBuffer", %__cblayout_CBVectors) // CHECK: @b1 = external hidden addrspace(2) global <3 x float>, align 16 // CHECK: @b2 = external hidden addrspace(2) global <3 x double>, align 32 // CHECK: @b3 = external hidden addrspace(2) global <2 x half>, align 4 @@ -89,16 +173,15 @@ cbuffer CBArrays : register(b2) { bool c8[4]; } -// CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, -// CHECK-SAME: 708, 0, 48, 112, 176, 224, 608, 624, 656)) -// CHECK: @c1 = external hidden addrspace(2) global [3 x float], align 4 -// CHECK: @c2 = external hidden addrspace(2) global [2 x <3 x double>], align 32 -// CHECK: @c3 = external hidden addrspace(2) global [2 x [2 x half]], align 2 -// CHECK: @c4 = external hidden addrspace(2) global [3 x i64], align 8 +// CHECK: @CBArrays.cb = global target("dx.CBuffer", %__cblayout_CBArrays) +// CHECK: @c1 = external hidden addrspace(2) global <{ [2 x <{ float, target("dx.Padding", 12) }>], float }>, align 4 +// CHECK: @c2 = external hidden addrspace(2) global <{ [1 x <{ <3 x double>, target("dx.Padding", 8) }>], <3 x double> }>, align 32 +// CHECK: @c3 = external hidden addrspace(2) global <{ [1 x <{ <{ [1 x <{ half, target("dx.Padding", 14) }>], half }>, target("dx.Padding", 14) }>], <{ [1 x <{ half, target("dx.Padding", 14) }>], half }> }>, align 2 +// CHECK: @c4 = external hidden addrspace(2) global <{ [2 x <{ i64, target("dx.Padding", 8) }>], i64 }>, align 8 // CHECK: @c5 = external hidden addrspace(2) global [2 x [3 x [4 x <4 x i32>]]], align 16 // CHECK: @c6 = external hidden addrspace(2) global [1 x i16], align 2 -// CHECK: @c7 = external hidden addrspace(2) global [2 x i64], align 8 -// CHECK: @c8 = external hidden addrspace(2) global [4 x i32], align 4 +// CHECK: @c7 = external hidden addrspace(2) global <{ [1 x <{ i64, target("dx.Padding", 8) }>], i64 }>, align 8 +// CHECK: @c8 = external hidden addrspace(2) global <{ [3 x <{ i32, target("dx.Padding", 12) }>], i32 }>, align 4 // CHECK: @CBArrays.str = private unnamed_addr constant [9 x i8] c"CBArrays\00", align 1 typedef uint32_t4 uint32_t8[2]; @@ -110,8 +193,7 @@ cbuffer CBTypedefArray : register(space2) { T2 t2[2]; } -// CHECK: @CBTypedefArray.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBTypedefArray, -// CHECK-SAME: 128, 0, 64)) +// CHECK: @CBTypedefArray.cb = global target("dx.CBuffer", %__cblayout_CBTypedefArray) // CHECK: @t1 = external hidden addrspace(2) global [2 x [2 x <4 x i32>]], align 16 // CHECK: @t2 = external hidden addrspace(2) global [2 x [2 x <4 x i32>]], align 16 // CHECK: @CBTypedefArray.str = private unnamed_addr constant [15 x i8] c"CBTypedefArray\00", align 1 @@ -135,13 +217,12 @@ struct D { Empty es; }; -// CHECK: @CBStructs.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBStructs, -// CHECK-SAME: 246, 0, 16, 32, 64, 144, 238, 240)) -// CHECK: @a = external hidden addrspace(2) global target("dx.Layout", %A, 8, 0), align 1 -// CHECK: @b = external hidden addrspace(2) global target("dx.Layout", %B, 14, 0, 8), align 1 -// CHECK: @c = external hidden addrspace(2) global target("dx.Layout", %C, 24, 0, 16), align 1 -// CHECK: @array_of_A = external hidden addrspace(2) global [5 x target("dx.Layout", %A, 8, 0)], align 1 -// CHECK: @d = external hidden addrspace(2) global target("dx.Layout", %__cblayout_D, 94, 0), align 1 +// CHECK: @CBStructs.cb = global target("dx.CBuffer", %__cblayout_CBStructs) +// CHECK: @a = external hidden addrspace(2) global %A, align 1 +// CHECK: @b = external hidden addrspace(2) global %B, align 1 +// CHECK: @c = external hidden addrspace(2) global %C, align 1 +// CHECK: @array_of_A = external hidden addrspace(2) global <{ [4 x <{ %A, target("dx.Padding", 8) }>], %A }>, align 1 +// CHECK: @d = external hidden addrspace(2) global %__cblayout_D, align 1 // CHECK: @e = external hidden addrspace(2) global half, align 2 // CHECK: @f = external hidden addrspace(2) global <3 x i16>, align 8 // CHECK: @CBStructs.str = private unnamed_addr constant [10 x i8] c"CBStructs\00", align 1 @@ -176,27 +257,25 @@ cbuffer CBClasses { K ka[10]; }; -// CHECK: @CBClasses.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBClasses, -// CHECK-SAME: 260, 0, 16, 32, 112)) -// CHECK: @k = external hidden addrspace(2) global target("dx.Layout", %K, 4, 0), align 1 -// CHECK: @l = external hidden addrspace(2) global target("dx.Layout", %L, 8, 0, 4), align 1 -// CHECK: @m = external hidden addrspace(2) global target("dx.Layout", %M, 68, 0), align 1 -// CHECK: @ka = external hidden addrspace(2) global [10 x target("dx.Layout", %K, 4, 0)], align 1 +// CHECK: @CBClasses.cb = global target("dx.CBuffer", %__cblayout_CBClasses) +// CHECK: @k = external hidden addrspace(2) global %K, align 1 +// CHECK: @l = external hidden addrspace(2) global %L, align 1 +// CHECK: @m = external hidden addrspace(2) global %M, align 1 +// CHECK: @ka = external hidden addrspace(2) global <{ [9 x <{ %K, target("dx.Padding", 12) }>], %K }>, align 1 // CHECK: @CBClasses.str = private unnamed_addr constant [10 x i8] c"CBClasses\00", align 1 struct Test { float a, b; }; -// CHECK: @CBMix.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBMix, -// CHECK-SAME: 170, 0, 24, 32, 120, 128, 136, 144, 152, 160, 168)) -// CHECK: @test = external hidden addrspace(2) global [2 x target("dx.Layout", %Test, 8, 0, 4)], align 1 +// CHECK: @CBMix.cb = global target("dx.CBuffer", %__cblayout_CBMix) +// CHECK: @test = external hidden addrspace(2) global <{ [1 x <{ %Test, target("dx.Padding", 8) }>], %Test }>, align 1 // CHECK: @f1 = external hidden addrspace(2) global float, align 4 -// CHECK: @f2 = external hidden addrspace(2) global [3 x [2 x <2 x float>]], align 8 +// CHECK: @f2 = external hidden addrspace(2) global <{ [2 x <{ <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }>, target("dx.Padding", 8) }>], <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }> }>, align 8 // CHECK: @f3 = external hidden addrspace(2) global float, align 4 -// CHECK: @f4 = external hidden addrspace(2) global target("dx.Layout", %anon, 4, 0), align 1 +// CHECK: @f4 = external hidden addrspace(2) global %anon, align 1 // CHECK: @f5 = external hidden addrspace(2) global double, align 8 -// CHECK: @f6 = external hidden addrspace(2) global target("dx.Layout", %anon.0, 8, 0), align 1 +// CHECK: @f6 = external hidden addrspace(2) global %anon.0, align 1 // CHECK: @f7 = external hidden addrspace(2) global float, align 4 // CHECK: @f8 = external hidden addrspace(2) global <1 x double>, align 8 // CHECK: @f9 = external hidden addrspace(2) global i16, align 2 @@ -215,7 +294,7 @@ cbuffer CBMix { uint16_t f9; }; -// CHECK: @CB_A.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_A, 188, 0, 32, 76, 80, 120, 128, 144, 160, 182)) +// CHECK: @CB_A.cb = global target("dx.CBuffer", %__cblayout_CB_A) cbuffer CB_A { double B0[2]; @@ -229,7 +308,7 @@ cbuffer CB_A { half3 B8; } -// CHECK: @CB_B.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_B, 94, 0, 88)) +// CHECK: @CB_B.cb = global target("dx.CBuffer", %__cblayout_CB_B) cbuffer CB_B { double3 B9[3]; half3 B10; @@ -264,7 +343,7 @@ struct G { half C3; }; -// CHECK: @CB_C.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_C, 400, 0, 16, 112, 128, 392)) +// CHECK: @CB_C.cb = global target("dx.CBuffer", %__cblayout_CB_C) cbuffer CB_C { int D0; F D1; @@ -275,63 +354,63 @@ cbuffer CB_C { // CHECK: define internal void @_init_buffer_CBScalars.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBScalars.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBScalars, 56, 0, 8, 16, 24, 32, 36, 40, 48)) -// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBScalarss_56_0_8_16_24_32_36_40_48tt(i32 5, i32 1, i32 1, i32 0, ptr @CBScalars.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBScalars, 56, 0, 8, 16, 24, 32, 36, 40, 48)) %CBScalars.cb_h, ptr @CBScalars.cb, align 4 +// CHECK-NEXT: %CBScalars.cb_h = call target("dx.CBuffer", %__cblayout_CBScalars) +// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_s___cblayout_CBScalarsst(i32 5, i32 1, i32 1, i32 0, ptr @CBScalars.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBScalars) %CBScalars.cb_h, ptr @CBScalars.cb, align 4 // CHECK: define internal void @_init_buffer_CBVectors.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBVectors.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBVectors, 136, 0, 16, 40, 48, 80, 96, 112)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBVectorss_136_0_16_40_48_80_96_112tt(i32 0, i32 0, i32 1, i32 0, ptr @CBVectors.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBVectors, 136, 0, 16, 40, 48, 80, 96, 112)) %CBVectors.cb_h, ptr @CBVectors.cb, align 4 +// CHECK-NEXT: %CBVectors.cb_h = call target("dx.CBuffer", %__cblayout_CBVectors) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBVectorsst(i32 0, i32 0, i32 1, i32 0, ptr @CBVectors.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBVectors) %CBVectors.cb_h, ptr @CBVectors.cb, align 4 // CHECK: define internal void @_init_buffer_CBArrays.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBArrays.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, 708, 0, 48, 112, 176, 224, 608, 624, 656)) -// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBArrayss_708_0_48_112_176_224_608_624_656tt(i32 0, i32 2, i32 1, i32 0, ptr @CBArrays.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, 708, 0, 48, 112, 176, 224, 608, 624, 656)) %CBArrays.cb_h, ptr @CBArrays.cb, align 4 +// CHECK-NEXT: %CBArrays.cb_h = call target("dx.CBuffer", %__cblayout_CBArrays) +// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_s___cblayout_CBArraysst(i32 0, i32 2, i32 1, i32 0, ptr @CBArrays.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBArrays) %CBArrays.cb_h, ptr @CBArrays.cb, align 4 // CHECK: define internal void @_init_buffer_CBTypedefArray.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBTypedefArray.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBTypedefArray, 128, 0, 64)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBTypedefArrays_128_0_64tt(i32 1, i32 2, i32 1, i32 0, ptr @CBTypedefArray.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBTypedefArray, 128, 0, 64)) %CBTypedefArray.cb_h, ptr @CBTypedefArray.cb, align 4 +// CHECK-NEXT: %CBTypedefArray.cb_h = call target("dx.CBuffer", %__cblayout_CBTypedefArray) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBTypedefArrayst(i32 1, i32 2, i32 1, i32 0, ptr @CBTypedefArray.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBTypedefArray) %CBTypedefArray.cb_h, ptr @CBTypedefArray.cb, align 4 // CHECK: define internal void @_init_buffer_CBStructs.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBStructs.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBStructs, 246, 0, 16, 32, 64, 144, 238, 240)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBStructss_246_0_16_32_64_144_238_240tt(i32 2, i32 0, i32 1, i32 0, ptr @CBStructs.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBStructs, 246, 0, 16, 32, 64, 144, 238, 240)) %CBStructs.cb_h, ptr @CBStructs.cb, align 4 +// CHECK-NEXT: %CBStructs.cb_h = call target("dx.CBuffer", %__cblayout_CBStructs) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBStructsst(i32 2, i32 0, i32 1, i32 0, ptr @CBStructs.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBStructs) %CBStructs.cb_h, ptr @CBStructs.cb, align 4 // CHECK: define internal void @_init_buffer_CBClasses.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBClasses.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBClasses, 260, 0, 16, 32, 112)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBClassess_260_0_16_32_112tt(i32 3, i32 0, i32 1, i32 0, ptr @CBClasses.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBClasses, 260, 0, 16, 32, 112)) %CBClasses.cb_h, ptr @CBClasses.cb, align 4 +// CHECK-NEXT: %CBClasses.cb_h = call target("dx.CBuffer", %__cblayout_CBClasses) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBClassesst(i32 3, i32 0, i32 1, i32 0, ptr @CBClasses.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBClasses) %CBClasses.cb_h, ptr @CBClasses.cb, align 4 // CHECK: define internal void @_init_buffer_CBMix.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBMix.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBMix, 170, 0, 24, 32, 120, 128, 136, 144, 152, 160, 168)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBMixs_170_0_24_32_120_128_136_144_152_160_168tt(i32 4, i32 0, i32 1, i32 0, ptr @CBMix.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBMix, 170, 0, 24, 32, 120, 128, 136, 144, 152, 160, 168)) %CBMix.cb_h, ptr @CBMix.cb, align 4 +// CHECK-NEXT: %CBMix.cb_h = call target("dx.CBuffer", %__cblayout_CBMix) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBMixst(i32 4, i32 0, i32 1, i32 0, ptr @CBMix.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBMix) %CBMix.cb_h, ptr @CBMix.cb, align 4 // CHECK: define internal void @_init_buffer_CB_A.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB_A.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_A, 188, 0, 32, 76, 80, 120, 128, 144, 160, 182)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CB_As_188_0_32_76_80_120_128_144_160_182tt(i32 5, i32 0, i32 1, i32 0, ptr @CB_A.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_A, 188, 0, 32, 76, 80, 120, 128, 144, 160, 182)) %CB_A.cb_h, ptr @CB_A.cb, align 4 +// CHECK-NEXT: %CB_A.cb_h = call target("dx.CBuffer", %__cblayout_CB_A) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Ast(i32 5, i32 0, i32 1, i32 0, ptr @CB_A.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CB_A) %CB_A.cb_h, ptr @CB_A.cb, align 4 // CHECK: define internal void @_init_buffer_CB_B.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB_B.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_B, 94, 0, 88)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CB_Bs_94_0_88tt(i32 6, i32 0, i32 1, i32 0, ptr @CB_B.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_B, 94, 0, 88)) %CB_B.cb_h, ptr @CB_B.cb, align 4 +// CHECK-NEXT: %CB_B.cb_h = call target("dx.CBuffer", %__cblayout_CB_B) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Bst(i32 6, i32 0, i32 1, i32 0, ptr @CB_B.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CB_B) %CB_B.cb_h, ptr @CB_B.cb, align 4 // CHECK: define internal void @_init_buffer_CB_C.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB_C.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_C, 400, 0, 16, 112, 128, 392)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CB_Cs_400_0_16_112_128_392tt(i32 7, i32 0, i32 1, i32 0, ptr @CB_C.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_C, 400, 0, 16, 112, 128, 392)) %CB_C.cb_h, ptr @CB_C.cb, align 4 +// CHECK-NEXT: %CB_C.cb_h = call target("dx.CBuffer", %__cblayout_CB_C) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Cst(i32 7, i32 0, i32 1, i32 0, ptr @CB_C.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CB_C) %CB_C.cb_h, ptr @CB_C.cb, align 4 RWBuffer Buf; diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl index b7bdce32e6507..1fe0a68261c94 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl @@ -4,18 +4,18 @@ // CHECK: %"n0::n1::__cblayout_A" = type <{ float }> // CHECK: %"n0::__cblayout_B" = type <{ float }> -// CHECK: %"n0::n2::__cblayout_C" = type <{ float, target("dx.Layout", %"n0::Foo", 4, 0) }> +// CHECK: %"n0::n2::__cblayout_C" = type <{ float, target("dx.Padding", 12), %"n0::Foo" }> // CHECK: %"n0::Foo" = type <{ float }> -// CHECK: @A.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::n1::__cblayout_A", 4, 0)) +// CHECK: @A.cb = global target("dx.CBuffer", %"n0::n1::__cblayout_A") // CHECK: @_ZN2n02n11aE = external hidden addrspace(2) global float, align 4 -// CHECK: @B.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::__cblayout_B", 4, 0)) +// CHECK: @B.cb = global target("dx.CBuffer", %"n0::__cblayout_B") // CHECK: @_ZN2n01aE = external hidden addrspace(2) global float, align 4 -// CHECK: @C.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::n2::__cblayout_C", 20, 0, 16)) +// CHECK: @C.cb = global target("dx.CBuffer", %"n0::n2::__cblayout_C") // CHECK: @_ZN2n02n21aE = external hidden addrspace(2) global float, align 4 -// CHECK: external hidden addrspace(2) global target("dx.Layout", %"n0::Foo", 4, 0), align 1 +// CHECK: external hidden addrspace(2) global %"n0::Foo", align 1 namespace n0 { struct Foo { diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_geps.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_geps.hlsl new file mode 100644 index 0000000000000..7a0b45875faf9 --- /dev/null +++ b/clang/test/CodeGenHLSL/resources/cbuffer_geps.hlsl @@ -0,0 +1,117 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -fnative-half-type -fnative-int16-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +// Capture the anonymous struct types for check lines below. +// CHECK: [[ANON_1:%.*]] = type <{ float, target("dx.Padding", 12), <4 x i32> }> +// CHECK: [[ANON_2:%.*]] = type <{ <2 x i32>, target("dx.Padding", 8), <{ [3 x <{ %ArrayAndScalar, target("dx.Padding", 12) }>], %ArrayAndScalar }> + +template void use(T); + +cbuffer CBArrays : register(b2) { + float c1[30]; + double3 c2[20]; + float16_t c3[10][20]; + uint64_t c4[30]; + int4 c5[20][30][40]; + uint16_t c6[10]; + int64_t c7[20]; + bool c8[40]; +} + +// CHECK-LABEL: define hidden void @_Z8cbarraysv() +void cbarrays() { + // CHECK: load float, ptr addrspace(2) @c1, align 16 + use(c1[0]); + // CHECK: load float, ptr addrspace(2) getelementptr (<{ float, target("dx.Padding", 12) }>, ptr addrspace(2) @c1, i32 7, i32 0), align 16 + use(c1[7]); + // CHECK: load float, ptr addrspace(2) getelementptr (<{ float, target("dx.Padding", 12) }>, ptr addrspace(2) @c1, i32 29, i32 0), align 16 + use(c1[29]); + + // CHECK: load <3 x double>, ptr addrspace(2) getelementptr (<{ <3 x double>, target("dx.Padding", 8) }>, ptr addrspace(2) @c2, i32 8, i32 0), align 32 + use(c2[8]); + // CHECK: load half, ptr addrspace(2) getelementptr (<{ half, target("dx.Padding", 14) }>, ptr addrspace(2) getelementptr (<{ <{ [19 x <{ half, target("dx.Padding", 14) }>], half }>, target("dx.Padding", 14) }>, ptr addrspace(2) @c3, i32 9, i32 0), i32 5, i32 0), align 16 + use(c3[9][5]); + // CHECK: load i64, ptr addrspace(2) getelementptr (<{ i64, target("dx.Padding", 8) }>, ptr addrspace(2) @c4, i32 6, i32 0), align 16 + use(c4[6]); + // CHECK: load <4 x i32>, ptr addrspace(2) getelementptr inbounds ([40 x <4 x i32>], ptr addrspace(2) getelementptr inbounds ([30 x [40 x <4 x i32>]], ptr addrspace(2) getelementptr inbounds ([20 x [30 x [40 x <4 x i32>]]], ptr addrspace(2) @c5, i32 0, i32 1), i32 0, i32 12), i32 0, i32 15), align 16 + use(c5[1][12][15]); + // CHECK: load i16, ptr addrspace(2) getelementptr (<{ i16, target("dx.Padding", 14) }>, ptr addrspace(2) @c6, i32 4, i32 0), align 16 + use(c6[4]); + // CHECK: load i64, ptr addrspace(2) getelementptr (<{ i64, target("dx.Padding", 8) }>, ptr addrspace(2) @c7, i32 17, i32 0), align 16 + use(c7[17]); + // CHECK: load i32, ptr addrspace(2) getelementptr (<{ i32, target("dx.Padding", 12) }>, ptr addrspace(2) @c8, i32 30, i32 0), align 16 + use(c8[30]); +} + +struct A { + float2 a1; +}; + +struct B : A { + uint16_t3 b1; +}; + +struct C { + int c1; + A c2; +}; + +struct D { + B d1[4][6]; +}; + +cbuffer CBStructs { + A s1; + B s2; + C s3; + A s4[5]; + D s5; +}; + +// CHECK-LABEL: define hidden void @_Z9cbstructsv() +void cbstructs() { + // CHECK: load <2 x float>, ptr addrspace(2) @s1, align 8 + use(s1.a1); + // CHECK: load <3 x i16>, ptr addrspace(2) getelementptr inbounds nuw (%B, ptr addrspace(2) @s2, i32 0, i32 1), align 2 + use(s2.b1); + // CHECK: load <2 x float>, ptr addrspace(2) getelementptr inbounds nuw (%C, ptr addrspace(2) @s3, i32 0, i32 1), align 8 + use(s3.c2.a1); + // CHECK: load <2 x float>, ptr addrspace(2) getelementptr (<{ %A, target("dx.Padding", 8) }>, ptr addrspace(2) @s4, i32 2, i32 0), align 8 + use(s4[2].a1); + // CHECK: load <3 x i16>, ptr addrspace(2) getelementptr inbounds nuw (%B, ptr addrspace(2) getelementptr (<{ %B, target("dx.Padding", 2) }>, ptr addrspace(2) getelementptr (<{ <{ [5 x <{ %B, target("dx.Padding", 2) }>], %B }>, target("dx.Padding", 2) }>, ptr addrspace(2) @s5, i32 3, i32 0), i32 5, i32 0), i32 0, i32 1), align 2 + use(s5.d1[3][5].b1); +} + +struct Scalars { + float a, b; +}; + +struct ArrayAndScalar { + uint4 x[5]; + float y; +}; + +cbuffer CBMix { + Scalars m1[3]; + float m2; + ArrayAndScalar m3; + float2 m4[5][4]; + struct { float c; uint4 d; } m5; + struct { int2 i; ArrayAndScalar j[4]; } m6; + vector m7; +}; + +// CHECK-LABEL: define hidden void @_Z5cbmixv() +void cbmix() { + // CHECK: load float, ptr addrspace(2) getelementptr inbounds nuw (%Scalars, ptr addrspace(2) getelementptr (<{ %Scalars, target("dx.Padding", 8) }>, ptr addrspace(2) @m1, i32 2, i32 0), i32 0, i32 1), align 4 + use(m1[2].b); + // CHECK: load float, ptr addrspace(2) getelementptr inbounds nuw (%ArrayAndScalar, ptr addrspace(2) @m3, i32 0, i32 1), align 4 + use(m3.y); + // CHECK: load <2 x float>, ptr addrspace(2) getelementptr (<{ <2 x float>, target("dx.Padding", 8) }>, ptr addrspace(2) getelementptr (<{ <{ [3 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }>, target("dx.Padding", 8) }>, ptr addrspace(2) @m4, i32 2, i32 0), i32 3, i32 0), align 16 + use(m4[2][3]); + // CHECK: load <4 x i32>, ptr addrspace(2) getelementptr inbounds nuw ([[ANON_1]], ptr addrspace(2) @m5, i32 0, i32 1), align 16 + use(m5.d); + // CHECK: load <4 x i32>, ptr addrspace(2) getelementptr inbounds ([5 x <4 x i32>], ptr addrspace(2) getelementptr (<{ %ArrayAndScalar, target("dx.Padding", 12) }>, ptr addrspace(2) getelementptr inbounds nuw ([[ANON_2]], ptr addrspace(2) @m6, i32 0, i32 1), i32 2, i32 0), i32 0, i32 2), align 16 + use(m6.j[2].x[2]); + // CHECK: load <1 x double>, ptr addrspace(2) @m7, align 8 + use(m7); +} diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl index 7bedd63c9f65d..68e263b9fc07f 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl @@ -2,13 +2,24 @@ // RUN: dxil-pc-shadermodel6.3-compute %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK: %__cblayout_CB = type <{ float, double, <2 x i32> }> -// CHECK: %__cblayout_CB_1 = type <{ float, <2 x float> }> - -// CHECK: @CB.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 176, 16, 168, 88)) -// CHECK: @a = external hidden addrspace(2) global float, align 4 -// CHECK: @b = external hidden addrspace(2) global double, align 8 -// CHECK: @c = external hidden addrspace(2) global <2 x i32>, align 8 +// CHECK: %__cblayout_CB = type <{ +// CHECK-SAME: target("dx.Padding", 16), +// CHECK-SAME: float, +// CHECK-SAME: target("dx.Padding", 68), +// CHECK-SAME: <2 x i32>, +// CHECK-SAME target("dx.Padding", 72), +// CHECK-SAME: double +// CHECK-SAME: }> +// CHECK: %__cblayout_CB_1 = type <{ +// CHECK-SAME: target("dx.Padding", 80), +// CHECK-SAME: <2 x float>, +// CHECK-SAME: float +// CHECK-SAME: }> + +// CHECK-DAG: @CB.cb = global target("dx.CBuffer", %__cblayout_CB) +// CHECK-DAG: @a = external hidden addrspace(2) global float, align 4 +// CHECK-DAG: @b = external hidden addrspace(2) global double, align 8 +// CHECK-DAG: @c = external hidden addrspace(2) global <2 x i32>, align 8 // CHECK: @CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1 cbuffer CB : register(b1, space3) { @@ -17,9 +28,9 @@ cbuffer CB : register(b1, space3) { int2 c : packoffset(c5.z); } -// CHECK: @CB.cb.1 = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_1, 92, 88, 80)) -// CHECK: @x = external hidden addrspace(2) global float, align 4 -// CHECK: @y = external hidden addrspace(2) global <2 x float>, align 8 +// CHECK-DAG: @CB.cb.1 = global target("dx.CBuffer", %__cblayout_CB_1) +// CHECK-DAG: @x = external hidden addrspace(2) global float, align 4 +// CHECK-DAG: @y = external hidden addrspace(2) global <2 x float>, align 8 // Missing packoffset annotation will produce a warning. // Element x will be placed after the element y that has an explicit packoffset. @@ -30,8 +41,7 @@ cbuffer CB : register(b0) { // CHECK: define internal void @_init_buffer_CB.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 176, 16, 168, 88)) -// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_176_16_168_88tt(i32 3, i32 1, i32 1, i32 0, ptr @CB.str) +// CHECK-NEXT: %CB.cb_h = call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_s___cblayout_CBst(i32 3, i32 1, i32 1, i32 0, ptr @CB.str) float foo() { // CHECK: load float, ptr addrspace(2) @a, align 4 @@ -48,5 +58,5 @@ void main() { } // CHECK: !hlsl.cbs = !{![[CB1:[0-9]+]], ![[CB2:[0-9]+]]} -// CHECK: ![[CB1]] = !{ptr @CB.cb, ptr addrspace(2) @a, ptr addrspace(2) @b, ptr addrspace(2) @c} -// CHECK: ![[CB2]] = !{ptr @CB.cb.1, ptr addrspace(2) @x, ptr addrspace(2) @y} +// CHECK: ![[CB1]] = !{ptr @CB.cb, ptr addrspace(2) @a, ptr addrspace(2) @c, ptr addrspace(2) @b} +// CHECK: ![[CB2]] = !{ptr @CB.cb.1, ptr addrspace(2) @y, ptr addrspace(2) @x} diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl index fa3405df9e3d3..b8c7babb8d634 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl @@ -2,7 +2,7 @@ // CHECK: %__cblayout_A = type <{ float }> -// CHECK: @A.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_A, 4, 0)) +// CHECK: @A.cb = global target("dx.CBuffer", %__cblayout_A) // CHECK: @a = external hidden addrspace(2) global float, align 4 // CHECK-DAG: @_ZL1b = internal global float 3.000000e+00, align 4 // CHECK-NOT: @B.cb diff --git a/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl b/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl index ad4d92f8afc02..5333dad962195 100644 --- a/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl +++ b/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl @@ -1,19 +1,18 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -fnative-half-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,DXIL // RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan1.3-compute -fnative-half-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,SPIRV -// DXIL: %"__cblayout_$Globals" = type <{ float, float, target("dx.Layout", %__cblayout_S, 4, 0) }> -// SPIRV: %"__cblayout_$Globals" = type <{ float, float, target("spirv.Layout", %__cblayout_S, 4, 0) }> +// CHECK: %"__cblayout_$Globals" = type <{ float, float, target("{{.*}}.Padding", 8), %__cblayout_S }> // CHECK: %__cblayout_S = type <{ float }> -// DXIL-DAG: @"$Globals.cb" = global target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 20, 0, 4, 16)) +// DXIL-DAG: @"$Globals.cb" = global target("dx.CBuffer", %"__cblayout_$Globals") // DXIL-DAG: @a = external hidden addrspace(2) global float // DXIL-DAG: @g = external hidden addrspace(2) global float -// DXIL-DAG: @h = external hidden addrspace(2) global target("dx.Layout", %__cblayout_S, 4, 0), align 4 +// DXIL-DAG: @h = external hidden addrspace(2) global %__cblayout_S, align 4 -// SPIRV-DAG: @"$Globals.cb" = global target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 20, 0, 4, 16), 2, 0) +// SPIRV-DAG: @"$Globals.cb" = global target("spirv.VulkanBuffer", %"__cblayout_$Globals", 2, 0) // SPIRV-DAG: @a = external hidden addrspace(12) global float // SPIRV-DAG: @g = external hidden addrspace(12) global float -// SPIRV-DAG: @h = external hidden addrspace(12) global target("spirv.Layout", %__cblayout_S, 4, 0), align 8 +// SPIRV-DAG: @h = external hidden addrspace(12) global %__cblayout_S, align 8 struct EmptyStruct { }; diff --git a/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl b/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl index 1b2cb0e99aa83..7be1f9043042c 100644 --- a/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl +++ b/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl @@ -1,17 +1,26 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -// CHECK: %"__cblayout_$Globals" = type <{ i32, float, [4 x double], <4 x i32>, <4 x float>, -// CHECK-SAME: target("dx.Layout", %S, 8, 0) }> +// CHECK: %"__cblayout_$Globals" = type <{ +// CHECK-SAME: float, +// CHECK-SAME: target("dx.Padding", 12), +// CHECK-SAME: <{ [3 x <{ double, target("dx.Padding", 8) }>], double }>, +// CHECK-SAME: target("dx.Padding", 8), +// CHECK-SAME: <4 x i32>, +// CHECK-SAME: %S +// CHECK-SAME: i32, +// CHECK-SAME: target("dx.Padding", 4), +// CHECK-SAME: <4 x float> +// CHECK-SAME: }> + // CHECK: %S = type <{ <2 x float> }> +// CHECK-DAG: @"$Globals.cb" = global target("dx.CBuffer", %"__cblayout_$Globals") +// CHECK-DAG: @a = external hidden addrspace(2) global i32, align 4 // CHECK-DAG: @b = external hidden addrspace(2) global float, align 4 +// CHECK-DAG: @c = external hidden addrspace(2) global <{ [3 x <{ double, target("dx.Padding", 8) }>], double }>, align 8 // CHECK-DAG: @d = external hidden addrspace(2) global <4 x i32>, align 16 -// CHECK-DAG: @"$Globals.cb" = global target("dx.CBuffer", -// CHECK-DAG-SAME: target("dx.Layout", %"__cblayout_$Globals", 144, 120, 16, 32, 64, 128, 112)) -// CHECK-DAG: @a = external hidden addrspace(2) global i32, align 4 -// CHECK-DAG: @c = external hidden addrspace(2) global [4 x double], align 8 // CHECK-DAG: @e = external hidden addrspace(2) global <4 x float>, align 16 -// CHECK-DAG: @s = external hidden addrspace(2) global target("dx.Layout", %S, 8, 0), align 1 +// CHECK-DAG: @s = external hidden addrspace(2) global %S, align 1 struct S { float2 v; @@ -19,8 +28,8 @@ struct S { int a; float b : register(c1); +int4 d : register(c6); double c[4] : register(c2); -int4 d : register(c4); float4 e; S s : register(c7); @@ -32,5 +41,4 @@ void main() { } // CHECK: !hlsl.cbs = !{![[CB:.*]]} -// CHECK: ![[CB]] = !{ptr @"$Globals.cb", ptr addrspace(2) @a, ptr addrspace(2) @b, ptr addrspace(2) @c, -// CHECK-SAME: ptr addrspace(2) @d, ptr addrspace(2) @e, ptr addrspace(2) @s} +// CHECK: ![[CB]] = !{ptr @"$Globals.cb", ptr addrspace(2) @b, ptr addrspace(2) @c, ptr addrspace(2) @d, ptr addrspace(2) @s, ptr addrspace(2) @a, ptr addrspace(2) @e} diff --git a/clang/test/Driver/fsanitize-alloc-token.c b/clang/test/Driver/fsanitize-alloc-token.c index 6d8bda16dfb96..0ffe9abad8053 100644 --- a/clang/test/Driver/fsanitize-alloc-token.c +++ b/clang/test/Driver/fsanitize-alloc-token.c @@ -5,6 +5,7 @@ // CHECK-NO-TOKEN-ALLOC-NOT: "-fsanitize=alloc-token" // RUN: %clang --target=x86_64-linux-gnu -flto -fvisibility=hidden -fno-sanitize-ignorelist -fsanitize=alloc-token,undefined,cfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COMPATIBLE +// RUN: %clang --target=aarch64-linux-android -march=armv8-a+memtag -flto -fvisibility=hidden -fsanitize=alloc-token,kcfi,memtag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COMPATIBLE // CHECK-COMPATIBLE: "-fsanitize={{.*}}alloc-token" // RUN: %clang --target=x86_64-linux-gnu -fsanitize=alloc-token -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MINIMAL diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index bbff4969cb413..4b6c10917c315 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -264,6 +264,11 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.mman.munlock libc.src.sys.mman.munlockall libc.src.sys.mman.munmap + libc.src.sys.mman.pkey_alloc + libc.src.sys.mman.pkey_free + libc.src.sys.mman.pkey_get + libc.src.sys.mman.pkey_mprotect + libc.src.sys.mman.pkey_set libc.src.sys.mman.remap_file_pages libc.src.sys.mman.posix_madvise libc.src.sys.mman.shm_open diff --git a/libc/include/sys/mman.yaml b/libc/include/sys/mman.yaml index 8c207552f9805..f9ab0c1001c3d 100644 --- a/libc/include/sys/mman.yaml +++ b/libc/include/sys/mman.yaml @@ -101,6 +101,41 @@ functions: arguments: - type: void * - type: size_t + - name: pkey_alloc + standards: + - Linux + return_type: int + arguments: + - type: unsigned int + - type: unsigned int + - name: pkey_free + standards: + - Linux + return_type: int + arguments: + - type: int + - name: pkey_get + standards: + - GNU + return_type: int + arguments: + - type: int + - name: pkey_mprotect + standards: + - Linux + return_type: int + arguments: + - type: void * + - type: size_t + - type: int + - type: int + - name: pkey_set + standards: + - GNU + return_type: int + arguments: + - type: int + - type: unsigned int - name: posix_madvise standards: - POSIX diff --git a/libc/src/sys/mman/CMakeLists.txt b/libc/src/sys/mman/CMakeLists.txt index 4d4c2ad376050..c7be1eddacb5e 100644 --- a/libc/src/sys/mman/CMakeLists.txt +++ b/libc/src/sys/mman/CMakeLists.txt @@ -86,6 +86,41 @@ add_entrypoint_object( .${LIBC_TARGET_OS}.msync ) +add_entrypoint_object( + pkey_alloc + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.pkey_alloc +) + +add_entrypoint_object( + pkey_free + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.pkey_free +) + +add_entrypoint_object( + pkey_get + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.pkey_get +) + +add_entrypoint_object( + pkey_mprotect + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.pkey_mprotect +) + +add_entrypoint_object( + pkey_set + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.pkey_set +) + add_entrypoint_object( remap_file_pages ALIAS diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt index 7181bb98a187f..97c116f1d2e79 100644 --- a/libc/src/sys/mman/linux/CMakeLists.txt +++ b/libc/src/sys/mman/linux/CMakeLists.txt @@ -1,3 +1,10 @@ +add_subdirectory(generic) +set(ARCH_SUBDIRECTORY generic) +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE}) + add_subdirectory(${LIBC_TARGET_ARCHITECTURE}) + set(ARCH_SUBDIRECTORY ${LIBC_TARGET_ARCHITECTURE}) +endif() + add_entrypoint_object( madvise SRCS @@ -50,6 +57,17 @@ add_entrypoint_object( libc.src.errno.errno ) +add_header_library( + mprotect_common + HDRS + mprotect_common.h + DEPENDS + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno + libc.src.__support.error_or +) + add_entrypoint_object( mprotect SRCS @@ -61,6 +79,7 @@ add_entrypoint_object( libc.include.sys_syscall libc.src.__support.OSUtil.osutil libc.src.errno.errno + .mprotect_common ) add_entrypoint_object( @@ -166,6 +185,82 @@ add_entrypoint_object( libc.src.errno.errno ) +add_entrypoint_object( + pkey_alloc + SRCS + pkey_alloc.cpp + HDRS + ../pkey_alloc.h + DEPENDS + libc.include.sys_mman + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_header_library( + pkey_common + HDRS + pkey_common.h + DEPENDS + .${ARCH_SUBDIRECTORY}.pkey_common +) + +add_entrypoint_object( + pkey_free + SRCS + pkey_free.cpp + HDRS + ../pkey_free.h + DEPENDS + libc.include.sys_mman + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_entrypoint_object( + pkey_get + SRCS + pkey_get.cpp + HDRS + ../pkey_get.h + DEPENDS + libc.include.sys_mman + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno + .pkey_common +) + +add_entrypoint_object( + pkey_mprotect + SRCS + pkey_mprotect.cpp + HDRS + ../pkey_mprotect.h + DEPENDS + libc.include.sys_mman + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno + .mprotect_common +) + +add_entrypoint_object( + pkey_set + SRCS + pkey_set.cpp + HDRS + ../pkey_set.h + DEPENDS + libc.include.sys_mman + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno + .pkey_common +) + add_entrypoint_object( remap_file_pages SRCS diff --git a/libc/src/sys/mman/linux/generic/CMakeLists.txt b/libc/src/sys/mman/linux/generic/CMakeLists.txt new file mode 100644 index 0000000000000..42b6d96c8387e --- /dev/null +++ b/libc/src/sys/mman/linux/generic/CMakeLists.txt @@ -0,0 +1,9 @@ +add_header_library( + pkey_common + HDRS + pkey_common.h + DEPENDS + libc.hdr.errno_macros + libc.src.__support.common + libc.src.__support.error_or +) diff --git a/libc/src/sys/mman/linux/generic/pkey_common.h b/libc/src/sys/mman/linux/generic/pkey_common.h new file mode 100644 index 0000000000000..95f9a464fbd4a --- /dev/null +++ b/libc/src/sys/mman/linux/generic/pkey_common.h @@ -0,0 +1,31 @@ +//===---------- Generic stub implementations for pkey functionality. ------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_ +#define LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_ + +#include "hdr/errno_macros.h" // For ENOSYS +#include "src/__support/common.h" +#include "src/__support/error_or.h" + +namespace LIBC_NAMESPACE_DECL { +namespace pkey_common { + +LIBC_INLINE ErrorOr pkey_get([[maybe_unused]] int pkey) { + return Error(ENOSYS); +} + +LIBC_INLINE ErrorOr pkey_set([[maybe_unused]] int pkey, + [[maybe_unused]] unsigned int access_rights) { + return Error(ENOSYS); +} + +} // namespace pkey_common +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_SYS_MMAN_LINUX_GENERIC_PKEY_COMMON_H_ diff --git a/libc/src/sys/mman/linux/mprotect.cpp b/libc/src/sys/mman/linux/mprotect.cpp index 6b14915b60c94..c891f03a4713c 100644 --- a/libc/src/sys/mman/linux/mprotect.cpp +++ b/libc/src/sys/mman/linux/mprotect.cpp @@ -11,26 +11,22 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/__support/error_or.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" +#include "src/sys/mman/linux/mprotect_common.h" #include // For syscall numbers. namespace LIBC_NAMESPACE_DECL { -// This function is currently linux only. It has to be refactored suitably if -// mprotect is to be supported on non-linux operating systems also. LLVM_LIBC_FUNCTION(int, mprotect, (void *addr, size_t size, int prot)) { - int ret = LIBC_NAMESPACE::syscall_impl( - SYS_mprotect, reinterpret_cast(addr), size, prot); - - // A negative return value indicates an error with the magnitude of the - // value being the error code. - if (ret < 0) { - libc_errno = -ret; + ErrorOr result = + LIBC_NAMESPACE::mprotect_common::mprotect_impl(addr, size, prot); + if (!result.has_value()) { + libc_errno = result.error(); return -1; } - - return 0; + return result.value(); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/mprotect_common.h b/libc/src/sys/mman/linux/mprotect_common.h new file mode 100644 index 0000000000000..5cd354f9919dd --- /dev/null +++ b/libc/src/sys/mman/linux/mprotect_common.h @@ -0,0 +1,38 @@ +//===---------- Shared Linux implementation of POSIX mprotect. ------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers. + +namespace LIBC_NAMESPACE_DECL { + +namespace mprotect_common { + +// This function is currently linux only. It has to be refactored suitably if +// mprotect is to be supported on non-linux operating systems also. +LIBC_INLINE ErrorOr mprotect_impl(void *addr, size_t size, int prot) { + int ret = LIBC_NAMESPACE::syscall_impl( + SYS_mprotect, reinterpret_cast(addr), size, prot); + + // A negative return value indicates an error with the magnitude of the + // value being the error code. + if (ret < 0) { + return Error(-ret); + } + + return 0; +} + +} // namespace mprotect_common + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/pkey_alloc.cpp b/libc/src/sys/mman/linux/pkey_alloc.cpp new file mode 100644 index 0000000000000..6ad65f342eb5e --- /dev/null +++ b/libc/src/sys/mman/linux/pkey_alloc.cpp @@ -0,0 +1,37 @@ +//===---------- Linux implementation of the Linux pkey_alloc function -----===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/sys/mman/pkey_alloc.h" + +#include "hdr/errno_macros.h" // For ENOSYS +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" + +#include // For syscall numbers. + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, pkey_alloc, + (unsigned int flags, unsigned int access_rights)) { +#if !defined(SYS_pkey_alloc) + libc_errno = ENOSYS; + return -1; +#else + int ret = + LIBC_NAMESPACE::syscall_impl(SYS_pkey_alloc, flags, access_rights); + if (ret < 0) { + libc_errno = -ret; + return -1; + } + return static_cast(ret); +#endif +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/pkey_common.h b/libc/src/sys/mman/linux/pkey_common.h new file mode 100644 index 0000000000000..7ea7b61cdcb75 --- /dev/null +++ b/libc/src/sys/mman/linux/pkey_common.h @@ -0,0 +1,15 @@ +//===---------- Linux implementation of the Linux pkey_mprotect function --===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/macros/properties/architectures.h" + +#if defined(LIBC_TARGET_ARCH_IS_X86_64) +#include "src/sys/mman/linux/x86_64/pkey_common.h" +#else +#include "src/sys/mman/linux/generic/pkey_common.h" +#endif diff --git a/libc/src/sys/mman/linux/pkey_free.cpp b/libc/src/sys/mman/linux/pkey_free.cpp new file mode 100644 index 0000000000000..328ba0468252e --- /dev/null +++ b/libc/src/sys/mman/linux/pkey_free.cpp @@ -0,0 +1,35 @@ +//===---------- Linux implementation of the Linux pkey_free function ------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/sys/mman/pkey_free.h" + +#include "hdr/errno_macros.h" // For ENOSYS +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" + +#include // For syscall numbers. + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, pkey_free, (int pkey)) { +#if !defined(SYS_pkey_free) + libc_errno = ENOSYS; + return -1; +#else + int ret = LIBC_NAMESPACE::syscall_impl(SYS_pkey_free, pkey); + if (ret < 0) { + libc_errno = -ret; + return -1; + } + return 0; +#endif +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/pkey_get.cpp b/libc/src/sys/mman/linux/pkey_get.cpp new file mode 100644 index 0000000000000..fbec5706c918d --- /dev/null +++ b/libc/src/sys/mman/linux/pkey_get.cpp @@ -0,0 +1,29 @@ +//===---------- Linux implementation of the Linux pkey_mprotect function --===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/sys/mman/pkey_get.h" + +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/architectures.h" +#include "src/sys/mman/linux/pkey_common.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, pkey_get, (int pkey)) { + ErrorOr ret = LIBC_NAMESPACE::pkey_common::pkey_get(pkey); + if (!ret.has_value()) { + libc_errno = ret.error(); + return -1; + } + return ret.value(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/pkey_mprotect.cpp b/libc/src/sys/mman/linux/pkey_mprotect.cpp new file mode 100644 index 0000000000000..daa12fa927f87 --- /dev/null +++ b/libc/src/sys/mman/linux/pkey_mprotect.cpp @@ -0,0 +1,58 @@ +//===---------- Linux implementation of the Linux pkey_mprotect function --===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/sys/mman/pkey_mprotect.h" + +#include "hdr/errno_macros.h" // For ENOSYS +#include "hdr/types/size_t.h" +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/sys/mman/linux/mprotect_common.h" + +#include // For syscall numbers. + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +LIBC_INLINE ErrorOr pkey_mprotect_impl(void *addr, size_t len, int prot, + int pkey) { + // Fall back to mprotect if pkey is -1 + // to maintain compatibility with kernel versions that don't support pkey. + if (pkey == -1) { + return LIBC_NAMESPACE::mprotect_common::mprotect_impl(addr, len, prot); + } + +#if !defined(SYS_pkey_mprotect) + return Error(ENOSYS); +#else + int ret = LIBC_NAMESPACE::syscall_impl(SYS_pkey_mprotect, addr, len, + prot, pkey); + if (ret < 0) { + return Error(-ret); + } + return 0; +#endif +} + +} // namespace internal + +LLVM_LIBC_FUNCTION(int, pkey_mprotect, + (void *addr, size_t len, int prot, int pkey)) { + ErrorOr ret = + LIBC_NAMESPACE::internal::pkey_mprotect_impl(addr, len, prot, pkey); + if (!ret.has_value()) { + libc_errno = ret.error(); + return -1; + } + return ret.value(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/pkey_set.cpp b/libc/src/sys/mman/linux/pkey_set.cpp new file mode 100644 index 0000000000000..919a6dceeafef --- /dev/null +++ b/libc/src/sys/mman/linux/pkey_set.cpp @@ -0,0 +1,29 @@ +//===---------- Linux implementation of the Linux pkey_mprotect function --===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/sys/mman/pkey_set.h" + +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/config.h" +#include "src/sys/mman/linux/pkey_common.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, pkey_set, (int pkey, unsigned int access_rights)) { + ErrorOr ret = LIBC_NAMESPACE::pkey_common::pkey_set(pkey, access_rights); + if (!ret.has_value()) { + libc_errno = ret.error(); + return -1; + } + return ret.value(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/x86_64/CMakeLists.txt b/libc/src/sys/mman/linux/x86_64/CMakeLists.txt new file mode 100644 index 0000000000000..1ce23af6dbd2a --- /dev/null +++ b/libc/src/sys/mman/linux/x86_64/CMakeLists.txt @@ -0,0 +1,10 @@ +add_header_library( + pkey_common + HDRS + pkey_common.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.stdint_proxy + libc.src.__support.common + libc.src.__support.error_or +) diff --git a/libc/src/sys/mman/linux/x86_64/pkey_common.h b/libc/src/sys/mman/linux/x86_64/pkey_common.h new file mode 100644 index 0000000000000..cb657750112c9 --- /dev/null +++ b/libc/src/sys/mman/linux/x86_64/pkey_common.h @@ -0,0 +1,61 @@ +//===---------- x86_64-specific implementations for pkey_{get,set}. -------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYS_MMAN_LINUX_X86_64_PKEY_COMMON_H_ +#define LLVM_SYS_MMAN_LINUX_X86_64_PKEY_COMMON_H_ + +#include + +#include "hdr/errno_macros.h" // For ENOSYS +#include "hdr/stdint_proxy.h" +#include "src/__support/common.h" +#include "src/__support/error_or.h" + +#if !defined(LIBC_TARGET_ARCH_IS_X86_64) +#error "Invalid include" +#endif + +namespace LIBC_NAMESPACE_DECL { +namespace pkey_common { + +constexpr int KEY_COUNT = 16; +constexpr int KEY_MASK = 0x3; +constexpr int BITS_PER_KEY = 2; + +// x86_64 implementation of pkey_get. +// Returns the access rights for the given pkey on success, errno otherwise. +[[gnu::target("pku")]] +LIBC_INLINE ErrorOr pkey_get(int pkey) { + if (pkey < 0 || pkey >= KEY_COUNT) { + return Error(EINVAL); + } + + uint32_t pkru = _rdpkru_u32(); + return (pkru >> (pkey * BITS_PER_KEY)) & KEY_MASK; +} + +// x86_64 implementation of pkey_set. +// Returns 0 on success, errno otherwise. +[[gnu::target("pku")]] +LIBC_INLINE ErrorOr pkey_set(int pkey, unsigned int access_rights) { + if (pkey < 0 || pkey >= KEY_COUNT || access_rights > KEY_MASK) { + return Error(EINVAL); + } + + uint32_t pkru = _rdpkru_u32(); + pkru &= ~(KEY_MASK << (pkey * BITS_PER_KEY)); + pkru |= ((access_rights & KEY_MASK) << (pkey * BITS_PER_KEY)); + _wrpkru(pkru); + + return 0; +} + +} // namespace pkey_common +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_SYS_MMAN_LINUX_X86_64_PKEY_COMMON_H_ diff --git a/libc/src/sys/mman/pkey_alloc.h b/libc/src/sys/mman/pkey_alloc.h new file mode 100644 index 0000000000000..c63c6a36c8021 --- /dev/null +++ b/libc/src/sys/mman/pkey_alloc.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pkey_alloc function -----------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_MMAN_PKEY_ALLOC_H +#define LLVM_LIBC_SRC_SYS_MMAN_PKEY_ALLOC_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int pkey_alloc(unsigned int flags, unsigned int access_rights); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_MMAN_PKEY_ALLOC_H diff --git a/libc/src/sys/mman/pkey_free.h b/libc/src/sys/mman/pkey_free.h new file mode 100644 index 0000000000000..a357e9b8c847b --- /dev/null +++ b/libc/src/sys/mman/pkey_free.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pkey_free function ------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_MMAN_PKEY_FREE_H +#define LLVM_LIBC_SRC_SYS_MMAN_PKEY_FREE_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int pkey_free(int pkey); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_MMAN_PKEY_FREE_H diff --git a/libc/src/sys/mman/pkey_get.h b/libc/src/sys/mman/pkey_get.h new file mode 100644 index 0000000000000..d41afe08ae371 --- /dev/null +++ b/libc/src/sys/mman/pkey_get.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pkey_get function -------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_MMAN_PKEY_GET_H +#define LLVM_LIBC_SRC_SYS_MMAN_PKEY_GET_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int pkey_get(int pkey); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_MMAN_PKEY_GET_H diff --git a/libc/src/sys/mman/pkey_mprotect.h b/libc/src/sys/mman/pkey_mprotect.h new file mode 100644 index 0000000000000..c02c61594ecc6 --- /dev/null +++ b/libc/src/sys/mman/pkey_mprotect.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pkey_mprotect function --------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_MMAN_PKEY_MPROTECT_H +#define LLVM_LIBC_SRC_SYS_MMAN_PKEY_MPROTECT_H + +#include "hdr/types/size_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int pkey_mprotect(void *addr, size_t len, int prot, int pkey); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_MMAN_PKEY_MPROTECT_H diff --git a/libc/src/sys/mman/pkey_set.h b/libc/src/sys/mman/pkey_set.h new file mode 100644 index 0000000000000..55bafbd11d709 --- /dev/null +++ b/libc/src/sys/mman/pkey_set.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pkey_set function -------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_MMAN_PKEY_SET_H +#define LLVM_LIBC_SRC_SYS_MMAN_PKEY_SET_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int pkey_set(int pkey, unsigned int access_rights); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_MMAN_PKEY_SET_H diff --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt index 32fee920321c0..8a290795e67f5 100644 --- a/libc/test/src/sys/mman/linux/CMakeLists.txt +++ b/libc/test/src/sys/mman/linux/CMakeLists.txt @@ -66,6 +66,31 @@ add_libc_unittest( libc.test.UnitTest.ErrnoSetterMatcher ) +# Disable sanitizers for pkey_test. +# This test intentionally triggers segfaults to verify pkey_mprotect behavior, +# and sanitizers register signal handlers that interfere with death testing. +if (NOT LLVM_USE_SANITIZER) + add_libc_unittest( + pkey_test + SUITE + libc_sys_mman_unittests + SRCS + pkey_test.cpp + DEPENDS + libc.hdr.errno_macros + libc.hdr.signal_macros + libc.hdr.types.size_t + libc.src.sys.mman.mmap + libc.src.sys.mman.munmap + libc.src.sys.mman.pkey_alloc + libc.src.sys.mman.pkey_free + libc.src.sys.mman.pkey_get + libc.src.sys.mman.pkey_mprotect + libc.src.sys.mman.pkey_set + libc.test.UnitTest.ErrnoCheckingTest + libc.test.UnitTest.ErrnoSetterMatcher + ) +endif() add_libc_unittest( posix_madvise_test diff --git a/libc/test/src/sys/mman/linux/pkey_test.cpp b/libc/test/src/sys/mman/linux/pkey_test.cpp new file mode 100644 index 0000000000000..9c6feae2d457b --- /dev/null +++ b/libc/test/src/sys/mman/linux/pkey_test.cpp @@ -0,0 +1,241 @@ +//===-- Unit tests for pkey functions -------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "hdr/errno_macros.h" +#include "hdr/signal_macros.h" +#include "hdr/types/size_t.h" +#include "src/sys/mman/mmap.h" +#include "src/sys/mman/munmap.h" +#include "src/sys/mman/pkey_alloc.h" +#include "src/sys/mman/pkey_free.h" +#include "src/sys/mman/pkey_get.h" +#include "src/sys/mman/pkey_mprotect.h" +#include "src/sys/mman/pkey_set.h" +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" +#include "test/UnitTest/LibcTest.h" +#include "test/UnitTest/TestLogger.h" + +#include // For EXEC_PAGESIZE. + +using LIBC_NAMESPACE::testing::tlog; +using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; +using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; + +using LlvmLibcProtectionKeyTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +constexpr size_t MMAP_SIZE = EXEC_PAGESIZE; + +// Wrapper around a pkey to ensure it is freed. +class PKeyGuard { +public: + int key; + + PKeyGuard() : key(-1) {} + + PKeyGuard(int key) : key(key) {} + + ~PKeyGuard() { + if (key != -1) { + LIBC_NAMESPACE::pkey_free(key); + } + } +}; + +// Wrapper around mmap to ensure munmap is called. +class MMapPageGuard { +public: + void *addr = nullptr; + size_t size = 0; + + static MMapPageGuard mmap(int prot) { + void *addr = LIBC_NAMESPACE::mmap(nullptr, MMAP_SIZE, prot, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (addr == MAP_FAILED) { + return MMapPageGuard(nullptr, 0); + } + return MMapPageGuard(addr, MMAP_SIZE); + } + + MMapPageGuard(void *addr, size_t size) : addr(addr), size(size) {} + + ~MMapPageGuard() { + if (addr != nullptr) { + LIBC_NAMESPACE::munmap(addr, size); + } + } +}; + +bool protection_keys_supported() { + static bool supported = []() { + PKeyGuard pkey(LIBC_NAMESPACE::pkey_alloc(0, 0)); + int err = libc_errno; + libc_errno = 0; + + if (pkey.key < 0 || (err == ENOSPC || err == ENOSYS || err == EINVAL)) { + tlog << "pkey_alloc failed with errno=" << err << "\n"; + return false; + } + + int access_rights = LIBC_NAMESPACE::pkey_get(pkey.key); + err = libc_errno; + libc_errno = 0; + if (access_rights < 0 || err == ENOSYS) { + tlog << "pkey_get failed with errno=" << err << "\n"; + return false; + } + + return true; + }(); + return supported; +} + +TEST_F(LlvmLibcProtectionKeyTest, MProtectWithPKeyDisablesWrite) { + if (!protection_keys_supported()) { + tlog << "Skipping test: pkey is not available\n"; + return; + } + + PKeyGuard pkey(LIBC_NAMESPACE::pkey_alloc(0, PKEY_DISABLE_WRITE)); + ASSERT_NE(pkey.key, -1); + + MMapPageGuard page = MMapPageGuard::mmap(PROT_READ | PROT_WRITE); + ASSERT_NE(page.addr, nullptr); + + volatile char *data = (char *)page.addr; + data[0] = 'a'; + + EXPECT_THAT(LIBC_NAMESPACE::pkey_mprotect(page.addr, page.size, + PROT_READ | PROT_WRITE, pkey.key), + Succeeds()); + + // Read is still allowed. + EXPECT_EQ(data[0], 'a'); + + // Write is not allowed. + EXPECT_DEATH([&data]() { data[0] = 'b'; }, WITH_SIGNAL(SIGSEGV)); +} + +TEST_F(LlvmLibcProtectionKeyTest, PKeySetChangesAccessRights) { + if (!protection_keys_supported()) { + tlog << "Skipping test: pkey is not available\n"; + return; + } + + PKeyGuard pkey(LIBC_NAMESPACE::pkey_alloc(0, 0)); + ASSERT_NE(pkey.key, -1); + + MMapPageGuard page = MMapPageGuard::mmap(PROT_READ | PROT_WRITE); + ASSERT_NE(page.addr, nullptr); + + EXPECT_THAT(LIBC_NAMESPACE::pkey_mprotect(page.addr, page.size, + PROT_READ | PROT_WRITE, pkey.key), + Succeeds()); + + // Write is allowed by default. + volatile char *data = (char *)page.addr; + data[0] = 'a'; + + EXPECT_THAT(LIBC_NAMESPACE::pkey_set(pkey.key, PKEY_DISABLE_WRITE), + Succeeds()); + + // Now read is allowed but write is not. + EXPECT_EQ(data[0], 'a'); + EXPECT_DEATH([&data]() { data[0] = 'b'; }, WITH_SIGNAL(SIGSEGV)); + + // Now neither read nor write is allowed. + EXPECT_THAT(LIBC_NAMESPACE::pkey_set(pkey.key, PKEY_DISABLE_ACCESS | + PKEY_DISABLE_WRITE), + Succeeds()); + EXPECT_DEATH([&data]() { (void)data[0]; }, WITH_SIGNAL(SIGSEGV)); + EXPECT_DEATH([&data]() { data[0] = 'b'; }, WITH_SIGNAL(SIGSEGV)); +} + +TEST_F(LlvmLibcProtectionKeyTest, FallsBackToMProtectForInvalidPKey) { + MMapPageGuard page = MMapPageGuard::mmap(PROT_READ | PROT_WRITE); + ASSERT_NE(page.addr, nullptr); + + volatile char *data = (char *)page.addr; + data[0] = 'a'; + + EXPECT_THAT( + LIBC_NAMESPACE::pkey_mprotect(page.addr, page.size, PROT_READ, -1), + Succeeds()); + + // Read is still allowed. + EXPECT_EQ(data[0], 'a'); + + // Write is not allowed. + EXPECT_DEATH([&data]() { data[0] = 'b'; }, WITH_SIGNAL(SIGSEGV)); +} + +TEST_F(LlvmLibcProtectionKeyTest, ExhaustedKeysFailsWithENOSPC) { + if (!protection_keys_supported()) { + tlog << "Skipping test: pkey is not available\n"; + return; + } + + // Use an unreasonably large limit to ensure test is cross-platform. + // This limit is intended to be much larger than the actual hardware limit. + constexpr int MAX_PKEYS = 64; + PKeyGuard pkeys[MAX_PKEYS]; + for (int i = 0; i < MAX_PKEYS; ++i) { + pkeys[i].key = LIBC_NAMESPACE::pkey_alloc(0, 0); + } + + // pkey allocation should eventually fail with ENOSPC. + PKeyGuard pkey(LIBC_NAMESPACE::pkey_alloc(0, 0)); + EXPECT_THAT(pkey.key, Fails(ENOSPC)); + libc_errno = 0; +} + +TEST_F(LlvmLibcProtectionKeyTest, Accessors) { + if (!protection_keys_supported()) { + tlog << "Skipping test: pkey is not available\n"; + return; + } + + PKeyGuard pkey(LIBC_NAMESPACE::pkey_alloc(0, PKEY_DISABLE_WRITE)); + ASSERT_NE(pkey.key, -1); + + // Check that pkey_alloc sets the access rights. + EXPECT_EQ(LIBC_NAMESPACE::pkey_get(pkey.key), PKEY_DISABLE_WRITE); + + // Check that pkey_set changes the access rights. + EXPECT_THAT(LIBC_NAMESPACE::pkey_set(pkey.key, PKEY_DISABLE_ACCESS), + Succeeds()); + EXPECT_EQ(LIBC_NAMESPACE::pkey_get(pkey.key), PKEY_DISABLE_ACCESS); +} + +TEST_F(LlvmLibcProtectionKeyTest, AccessorsErrorForInvalidValues) { + if (!protection_keys_supported()) { + tlog << "Skipping test: pkey is not available\n"; + return; + } + + PKeyGuard pkey(LIBC_NAMESPACE::pkey_alloc(0, PKEY_DISABLE_WRITE)); + ASSERT_NE(pkey.key, -1); + + // Pkey is out of bounds in pkey_get. + EXPECT_THAT(LIBC_NAMESPACE::pkey_get(100), Fails(EINVAL)); + EXPECT_THAT(LIBC_NAMESPACE::pkey_get(-1234), Fails(EINVAL)); + + // Pkey is out of bounds in pkey_set. + EXPECT_THAT(LIBC_NAMESPACE::pkey_set(100, PKEY_DISABLE_ACCESS), + Fails(EINVAL)); + EXPECT_THAT(LIBC_NAMESPACE::pkey_set(-1234, PKEY_DISABLE_ACCESS), + Fails(EINVAL)); + + // Non-zero flags are not supported in pkey_alloc. + EXPECT_THAT(LIBC_NAMESPACE::pkey_alloc(123, PKEY_DISABLE_WRITE), + Fails(EINVAL)); + + // Access rights are out of bounds. + EXPECT_THAT(LIBC_NAMESPACE::pkey_alloc(0, 1000), Fails(EINVAL)); + EXPECT_THAT(LIBC_NAMESPACE::pkey_set(pkey.key, 1000), Fails(EINVAL)); +} diff --git a/lldb/include/lldb/Utility/LLDBLog.h b/lldb/include/lldb/Utility/LLDBLog.h index 18e4a3ca73507..ac360bfdf8cee 100644 --- a/lldb/include/lldb/Utility/LLDBLog.h +++ b/lldb/include/lldb/Utility/LLDBLog.h @@ -50,7 +50,8 @@ enum class LLDBLog : Log::MaskType { OnDemand = Log::ChannelFlag<31>, Source = Log::ChannelFlag<32>, Disassembler = Log::ChannelFlag<33>, - LLVM_MARK_AS_BITMASK_ENUM(Disassembler), + InstrumentationRuntime = Log::ChannelFlag<34>, + LLVM_MARK_AS_BITMASK_ENUM(InstrumentationRuntime), }; LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); diff --git a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp index a8901beda3970..f124424a37f58 100644 --- a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -346,6 +346,16 @@ EmulateInstructionARM64::GetOpcodeForInstruction(const uint32_t opcode) { &EmulateInstructionARM64::EmulateLDRSTRImm, "LDR , [{, #}]"}, + {0x3f200c00, 0x3c000400, No_VFP, + &EmulateInstructionARM64::EmulateLDRSTRImm, + "LDR|STR , [], #"}, + {0x3f200c00, 0x3c000c00, No_VFP, + &EmulateInstructionARM64::EmulateLDRSTRImm, + "LDR|STR , [, #]!"}, + {0x3f000000, 0x3d000000, No_VFP, + &EmulateInstructionARM64::EmulateLDRSTRImm, + "LDR|STR , [{, #}]"}, + {0xfc000000, 0x14000000, No_VFP, &EmulateInstructionARM64::EmulateB, "B