diff --git a/azure-devops/checkout-sources.yml b/azure-devops/checkout-sources.yml new file mode 100644 index 00000000000..5dceb67f043 --- /dev/null +++ b/azure-devops/checkout-sources.yml @@ -0,0 +1,70 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +parameters: +- name: vcpkgSHAVar + type: string + default: vcpkgSHA +- name: llvmSHAVar + type: string + default: llvmSHA +steps: +- checkout: self + clean: true + submodules: false +- task: PowerShell@2 + displayName: 'Get submodule SHAs' + timeoutInMinutes: 1 + inputs: + targetType: inline + script: | + cd $(Build.SourcesDirectory) + $regexSubmoduleSHA = '^[ \-+]([0-9a-f]+) .*$' + $llvmSHA = git submodule status --cached llvm-project | %{$_ -replace $regexSubmoduleSHA, '$1'} + Write-Host "##vso[task.setvariable variable=${{ parameters.llvmSHAVar }};]$llvmSHA" + $vcpkgSHA = git submodule status --cached vcpkg | %{$_ -replace $regexSubmoduleSHA, '$1'} + Write-Host "##vso[task.setvariable variable=${{ parameters.vcpkgSHAVar }};]$vcpkgSHA" +- script: | + cd $(Build.SourcesDirectory) + if not exist "llvm-project" ( + mkdir llvm-project + ) + cd llvm-project + + if not exist ".git" ( + del /S /Q * + git init + ) + + git remote get-url llvm + if errorlevel 1 ( + git remote add llvm https://github.com/llvm/llvm-project.git + git config --local extensions.partialClone llvm + ) + + git fetch --filter=tree:0 --depth=1 llvm $(${{ parameters.llvmSHAVar }}) + git reset --quiet FETCH_HEAD + git sparse-checkout init --cone + git sparse-checkout set libcxx/test libcxx/utils/libcxx llvm/utils/lit + displayName: "Checkout LLVM source" +- script: | + cd $(Build.SourcesDirectory) + if not exist "vcpkg" ( + mkdir vcpkg + ) + cd vcpkg + + if not exist ".git" ( + del /S /Q * + git init + ) + + git remote get-url vcpkg + if errorlevel 1 ( + git remote add vcpkg https://github.com/Microsoft/vcpkg.git + git config --local extensions.partialClone vcpkg + ) + + git fetch --filter=tree:0 --depth=1 vcpkg $(${{ parameters.vcpkgSHAVar }}) + git checkout -f FETCH_HEAD + displayName: "Checkout vcpkg source" diff --git a/azure-devops/cmake-configure-build.yml b/azure-devops/cmake-configure-build.yml new file mode 100644 index 00000000000..02e1cd93fa4 --- /dev/null +++ b/azure-devops/cmake-configure-build.yml @@ -0,0 +1,52 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +parameters: +- name: hostArch + type: string +- name: targetArch + type: string +- name: vcpkgLocationVar + type: string + default: vcpkgLocation +- name: targetPlatform + type: string +- name: buildOutputLocationVar + type: string + default: buildOutputLocation +- name: cmakeAdditionalFlags + type: string + default: '' +steps: +- task: PowerShell@2 + displayName: 'Get Test Parallelism' + timeoutInMinutes: 1 + inputs: + targetType: inline + script: | + $testParallelism = $env:NUMBER_OF_PROCESSORS - 2 + Write-Host "##vso[task.setvariable variable=testParallelism;]$testParallelism" +- script: | + if exist "$(${{ parameters.buildOutputLocationVar }})" ( + rmdir /S /Q "$(${{ parameters.buildOutputLocationVar }})" + ) + call "%PROGRAMFILES(X86)%\Microsoft Visual Studio\2019\Preview\Common7\Tools\VsDevCmd.bat" ^ + -host_arch=${{ parameters.hostArch }} -arch=${{ parameters.targetArch }} -no_logo + cmake ${{ parameters.cmakeAdditionalFlags}} -G Ninja ^ + -DCMAKE_TOOLCHAIN_FILE=$(${{ parameters.vcpkgLocationVar }})\scripts\buildsystems\vcpkg.cmake ^ + -DVCPKG_TARGET_TRIPLET=${{ parameters.targetPlatform }}-windows ^ + -DCMAKE_CXX_COMPILER=cl ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DLIT_FLAGS=$(litFlags) ^ + -DCMAKE_CXX_FLAGS=/analyze:autolog- ^ + -S $(Build.SourcesDirectory) -B $(${{ parameters.buildOutputLocationVar }}) + displayName: 'Configure the STL' + timeoutInMinutes: 2 + env: { TMP: $(tmpDir), TEMP: $(tmpDir) } +- script: | + call "%PROGRAMFILES(X86)%\Microsoft Visual Studio\2019\Preview\Common7\Tools\VsDevCmd.bat" ^ + -host_arch=${{ parameters.hostArch }} -arch=${{ parameters.targetArch }} -no_logo + cmake --build $(${{ parameters.buildOutputLocationVar }}) + displayName: 'Build the STL' + timeoutInMinutes: 10 + env: { TMP: $(tmpDir), TEMP: $(tmpDir) } diff --git a/azure-devops/cross-build.yml b/azure-devops/cross-build.yml new file mode 100644 index 00000000000..1bcae239d5b --- /dev/null +++ b/azure-devops/cross-build.yml @@ -0,0 +1,51 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +parameters: +- name: hostArch + type: string + default: amd64 +- name: targetPlatform + type: string +- name: vsDevCmdArch + type: string +- name: buildOutputLocationVar + type: string + default: buildOutputLocation +- name: numShards + type: number + default: 8 +jobs: +- job: '${{ parameters.targetPlatform }}' + variables: + fixedFlags: '--timeout=240;--shuffle' + parallelismFlag: '-j$(testParallelism)' + xmlOutputFlag: '--xunit-xml-output=$(${{ parameters.buildOutputLocationVar }})/test-results.xml' + shardFlags: '--num-shards=$(System.TotalJobsInPhase);--run-shard=$(System.JobPositionInPhase)' + litFlags: '$(fixedFlags);$(parallelismFlag);$(xmlOutputFlag);$(shardFlags)' + strategy: + parallel: ${{ parameters.numShards }} + timeoutInMinutes: 360 + steps: + - script: | + if exist "$(tmpDir)" (rmdir /S /Q $(tmpDir)) + mkdir $(tmpDir) + displayName: 'Setup TMP Directory' + + - template: checkout-sources.yml + - template: vcpkg-dependencies.yml + parameters: + targetPlatform: ${{ parameters.targetPlatform }} + - template: cmake-configure-build.yml + parameters: + targetPlatform: ${{ parameters.targetPlatform }} + hostArch: ${{ parameters.hostArch }} + targetArch: ${{ parameters.vsDevCmdArch }} + cmakeAdditionalFlags: '-DTESTS_BUILD_ONLY=ON' + - template: run-tests.yml + parameters: + hostArch: ${{ parameters.hostArch }} + targetPlatform: ${{ parameters.targetPlatform }} + targetArch: ${{ parameters.vsDevCmdArch }} + displayName: 'Build Tests' + publishArtifact: true diff --git a/azure-devops/native-build-test.yml b/azure-devops/native-build-test.yml new file mode 100644 index 00000000000..17fa03732ae --- /dev/null +++ b/azure-devops/native-build-test.yml @@ -0,0 +1,45 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +parameters: +- name: targetPlatform + type: string +- name: vsDevCmdArch + type: string +- name: buildOutputLocationVar + type: string + default: buildOutputLocation +- name: numShards + type: number + default: 8 +jobs: +- job: '${{ parameters.targetPlatform }}' + variables: + fixedFlags: '--timeout=240;--shuffle' + parallelismFlag: '-j$(testParallelism)' + xmlOutputFlag: '--xunit-xml-output=$(${{ parameters.buildOutputLocationVar }})/test-results.xml' + shardFlags: '--num-shards=$(System.TotalJobsInPhase);--run-shard=$(System.JobPositionInPhase)' + litFlags: '$(fixedFlags);$(parallelismFlag);$(xmlOutputFlag);$(shardFlags)' + strategy: + parallel: ${{ parameters.numShards }} + timeoutInMinutes: 360 + steps: + - script: | + if exist "$(tmpDir)" (rmdir /S /Q $(tmpDir)) + mkdir $(tmpDir) + displayName: 'Setup TMP Directory' + + - template: checkout-sources.yml + - template: vcpkg-dependencies.yml + parameters: + targetPlatform: ${{ parameters.targetPlatform }} + - template: cmake-configure-build.yml + parameters: + targetPlatform: ${{ parameters.targetPlatform }} + targetArch: ${{ parameters.vsDevCmdArch }} + hostArch: ${{ parameters.vsDevCmdArch }} + - template: run-tests.yml + parameters: + hostArch: ${{ parameters.vsDevCmdArch }} + targetPlatform: ${{ parameters.targetPlatform }} + targetArch: ${{ parameters.vsDevCmdArch }} diff --git a/azure-devops/run-build.yml b/azure-devops/run-build.yml deleted file mode 100644 index 767b5c77bfe..00000000000 --- a/azure-devops/run-build.yml +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -jobs: -- job: '${{ parameters.targetPlatform }}_${{ parameters.shardNum }}' - timeoutInMinutes: 360 - - variables: - buildOutputLocation: 'D:\build\${{ parameters.targetPlatform }}' - litFlags: '-j$(testParallelism);--timeout=240;--shuffle;--xunit-xml-output=$(buildOutputLocation)/test-results.xml' - shardFlags: '--num-shards=${{ parameters.numShards }};--run-shard=${{ parameters.shardNum }}' - vcpkgLocation: '$(Build.SourcesDirectory)/vcpkg' - steps: - - script: | - if exist "$(tmpDir)" ( - rmdir /S /Q $(tmpDir) - ) - mkdir $(tmpDir) - displayName: 'Setup TMP Directory' - - checkout: self - clean: true - submodules: false - - task: PowerShell@2 - displayName: 'Get submodule SHAs' - timeoutInMinutes: 1 - inputs: - targetType: inline - script: | - cd $(Build.SourcesDirectory) - $regexSubmoduleSHA = '^[ \-+]([0-9a-f]+) .*$' - $llvmSHA = git submodule status --cached llvm-project | %{$_ -replace $regexSubmoduleSHA, '$1'} - Write-Host "##vso[task.setvariable variable=llvmSHA;]$llvmSHA" - $vcpkgSHA = git submodule status --cached vcpkg | %{$_ -replace $regexSubmoduleSHA, '$1'} - Write-Host "##vso[task.setvariable variable=vcpkgSHA;]$vcpkgSHA" - - script: | - cd $(Build.SourcesDirectory) - if not exist "llvm-project" ( - mkdir llvm-project - ) - cd llvm-project - git init - git remote add llvm https://github.com/llvm/llvm-project - git config --local extensions.partialClone llvm - git fetch --filter=tree:0 --depth=1 llvm $(llvmSHA) - git reset --quiet $(llvmSHA) - git sparse-checkout init --cone - git sparse-checkout set libcxx/test libcxx/utils/libcxx llvm/utils/lit - displayName: "Checkout LLVM source" - - script: | - cd $(Build.SourcesDirectory) - if not exist "vcpkg" ( - mkdir vcpkg - ) - cd vcpkg - git init - git remote add vcpkg https://github.com/Microsoft/vcpkg - git config --local extensions.partialClone vcpkg - git fetch --filter=tree:0 --depth=1 vcpkg $(vcpkgSHA) - git checkout $(vcpkgSHA) - displayName: "Checkout vcpkg source" - - task: Cache@2 - displayName: vcpkg/installed Caching - timeoutInMinutes: 10 - inputs: - key: '"${{ parameters.targetPlatform }}" | "$(vcpkgSHA)" | "2020-03-01.01"' - path: '$(vcpkgLocation)/installed' - cacheHitVar: CACHE_RESTORED - - task: run-vcpkg@0 - displayName: 'Run vcpkg to Install boost-build' - condition: and(ne(variables.CACHE_RESTORED, 'true'), contains('${{ parameters.targetPlatform }}', 'arm')) - timeoutInMinutes: 10 - inputs: - doNotUpdateVcpkg: true - vcpkgArguments: 'boost-build' - vcpkgDirectory: '$(vcpkgLocation)' - vcpkgTriplet: 'x86-windows' - env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - - task: run-vcpkg@0 - displayName: 'Run vcpkg to Install boost-math' - condition: ne(variables.CACHE_RESTORED, 'true') - timeoutInMinutes: 10 - inputs: - doNotUpdateVcpkg: true - vcpkgArguments: 'boost-math' - vcpkgDirectory: '$(vcpkgLocation)' - vcpkgTriplet: '${{ parameters.targetPlatform }}-windows' - env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - - task: PowerShell@2 - displayName: 'Get Test Parallelism' - timeoutInMinutes: 1 - inputs: - targetType: inline - script: | - $testParallelism = $env:NUMBER_OF_PROCESSORS - 2 - Write-Host "##vso[task.setvariable variable=testParallelism;]$testParallelism" - - script: | - if exist "$(buildOutputLocation)" ( - rmdir /S /Q "$(buildOutputLocation)" - ) - call "%PROGRAMFILES(X86)%\Microsoft Visual Studio\2019\Preview\Common7\Tools\VsDevCmd.bat" ^ - -host_arch=amd64 -arch=${{ parameters.vsDevCmdArch }} -no_logo - cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=$(vcpkgLocation)\scripts\buildsystems\vcpkg.cmake ^ - -DVCPKG_TARGET_TRIPLET=${{ parameters.targetPlatform }}-windows -DCMAKE_CXX_COMPILER=cl ^ - -DCMAKE_BUILD_TYPE=Release -DLIT_FLAGS=$(litFlags);$(shardFlags) ^ - -DCMAKE_CXX_FLAGS=/analyze:autolog- ^ - -S $(Build.SourcesDirectory) -B $(buildOutputLocation) - cmake --build $(buildOutputLocation) - displayName: 'Build the STL' - timeoutInMinutes: 10 - env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - - task: CmdLine@2 - displayName: 'Run Tests' - timeoutInMinutes: 120 - condition: and(succeeded(), in('${{ parameters.targetPlatform }}', 'x64', 'x86')) - inputs: - workingDirectory: $(buildOutputLocation) - script: | - call "%PROGRAMFILES(X86)%\Microsoft Visual Studio\2019\Preview\Common7\Tools\VsDevCmd.bat" ^ - -host_arch=${{ parameters.vsDevCmdArch }} -arch=${{ parameters.vsDevCmdArch }} -no_logo - ctest -V - env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - - task: PublishTestResults@2 - displayName: 'Publish Tests' - timeoutInMinutes: 10 - condition: and(succeededOrFailed(), in('${{ parameters.targetPlatform }}', 'x64', 'x86')) - inputs: - searchFolder: $(buildOutputLocation) - testResultsFormat: JUnit - testResultsFiles: '**/test-results.xml' - testRunTitle: 'test-${{ parameters.targetPlatform }}-${{ parameters.shardNum }}' diff --git a/azure-devops/run-tests.yml b/azure-devops/run-tests.yml new file mode 100644 index 00000000000..a247bfc43c4 --- /dev/null +++ b/azure-devops/run-tests.yml @@ -0,0 +1,48 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +parameters: +- name: buildOutputLocationVar + type: string + default: buildOutputLocation +- name: targetPlatform + type: string +- name: hostArch + type: string +- name: targetArch + type: string +- name: displayName + type: string + default: 'Run Tests' +- name: publishArtifact + type: boolean + default: false +steps: +- task: CmdLine@2 + displayName: ${{ parameters.displayName }} + timeoutInMinutes: 120 + condition: succeeded() + inputs: + workingDirectory: $(${{ parameters.buildOutputLocationVar }}) + script: | + call "%PROGRAMFILES(X86)%\Microsoft Visual Studio\2019\Preview\Common7\Tools\VsDevCmd.bat" ^ + -host_arch=${{ parameters.hostArch }} -arch=${{ parameters.targetArch }} -no_logo + ctest -V + env: { TMP: $(tmpDir), TEMP: $(tmpDir) } +- task: PublishTestResults@2 + displayName: 'Publish Tests' + timeoutInMinutes: 10 + condition: succeededOrFailed() + inputs: + searchFolder: $(${{ parameters.buildOutputLocationVar }}) + testResultsFormat: JUnit + testResultsFiles: '**/test-results.xml' + testRunTitle: 'test-${{ parameters.targetPlatform }}-$(System.JobPositionInPhase)' +- publish: $(${{ parameters.buildOutPutLocationVar }})/out + artifact: '${{ parameters.targetPlatform }}-$(System.JobPositionInPhase)-libs-$(System.JobId)' + condition: ${{ parameters.publishArtifact }} + displayName: 'Publish Libs and Headers Artifact' +- publish: $(${{ parameters.buildOutPutLocationVar }})/tests + artifact: '${{ parameters.targetPlatform }}-$(System.JobPositionInPhase)-tests-$(System.JobId)' + condition: ${{ parameters.publishArtifact }} + displayName: 'Publish Tests Artifact' diff --git a/azure-devops/vcpkg-dependencies.yml b/azure-devops/vcpkg-dependencies.yml new file mode 100644 index 00000000000..bd22c161de1 --- /dev/null +++ b/azure-devops/vcpkg-dependencies.yml @@ -0,0 +1,38 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +parameters: +- name: targetPlatform + type: string +- name: vcpkgLocationVar + type: string + default: vcpkgLocation +- name: vcpkgSHAVar + type: string + default: vcpkgSHA +steps: +- task: Cache@2 + displayName: vcpkg/installed Caching + timeoutInMinutes: 10 + inputs: + key: '"${{ parameters.targetPlatform }}" | "$(${{ parameters.vcpkgSHAVar }})" | "2020-03-01.01"' + path: '$(${{ parameters.vcpkgLocationVar }})/installed' + cacheHitVar: CACHE_RESTORED +- task: run-vcpkg@0 + displayName: 'Run vcpkg to Install boost-build' + condition: ne(variables.CACHE_RESTORED, 'true') + timeoutInMinutes: 10 + inputs: + doNotUpdateVcpkg: true + vcpkgArguments: 'boost-build' + vcpkgDirectory: '$(${{ parameters.vcpkgLocationVar }})' + vcpkgTriplet: 'x86-windows' +- task: run-vcpkg@0 + displayName: 'Run vcpkg to Install boost-math' + condition: ne(variables.CACHE_RESTORED, 'true') + timeoutInMinutes: 10 + inputs: + doNotUpdateVcpkg: true + vcpkgArguments: 'boost-math' + vcpkgDirectory: '$(${{ parameters.vcpkgLocationVar }})' + vcpkgTriplet: '${{ parameters.targetPlatform }}-windows' diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f342d73784b..1451cb51321 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -5,6 +5,8 @@ variables: tmpDir: 'D:\Temp' + buildOutputLocation: 'D:\build' + vcpkgLocation: '$(Build.SourcesDirectory)/vcpkg' pool: 'StlBuild-2021-01-20-2' @@ -56,131 +58,39 @@ stages: failOnStandardError: true arguments: '$(buildOutputLocation)/validate/validate.exe' env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - - stage: Build_And_Test + + - stage: Build_And_Test_x86 + dependsOn: Code_Format displayName: 'Build and Test' jobs: - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x86 - vsDevCmdArch: x86 - numShards: 8 - shardNum: 1 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x86 - vsDevCmdArch: x86 - numShards: 8 - shardNum: 2 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x86 - vsDevCmdArch: x86 - numShards: 8 - shardNum: 3 - - - template: azure-devops/run-build.yml + - template: azure-devops/native-build-test.yml parameters: targetPlatform: x86 vsDevCmdArch: x86 - numShards: 8 - shardNum: 4 - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x86 - vsDevCmdArch: x86 - numShards: 8 - shardNum: 5 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x86 - vsDevCmdArch: x86 - numShards: 8 - shardNum: 6 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x86 - vsDevCmdArch: x86 - numShards: 8 - shardNum: 7 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x86 - vsDevCmdArch: x86 - numShards: 8 - shardNum: 8 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x64 - vsDevCmdArch: amd64 - numShards: 8 - shardNum: 1 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x64 - vsDevCmdArch: amd64 - numShards: 8 - shardNum: 2 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x64 - vsDevCmdArch: amd64 - numShards: 8 - shardNum: 3 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x64 - vsDevCmdArch: amd64 - numShards: 8 - shardNum: 4 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x64 - vsDevCmdArch: amd64 - numShards: 8 - shardNum: 5 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x64 - vsDevCmdArch: amd64 - numShards: 8 - shardNum: 6 - - - template: azure-devops/run-build.yml - parameters: - targetPlatform: x64 - vsDevCmdArch: amd64 - numShards: 8 - shardNum: 7 - - - template: azure-devops/run-build.yml + - stage: Build_And_Test_x64 + dependsOn: Code_Format + displayName: 'Build and Test' + jobs: + - template: azure-devops/native-build-test.yml parameters: targetPlatform: x64 vsDevCmdArch: amd64 - numShards: 8 - shardNum: 8 - - template: azure-devops/run-build.yml + - stage: Build_ARM + dependsOn: Code_Format + displayName: 'Build' + jobs: + - template: azure-devops/cross-build.yml parameters: targetPlatform: arm vsDevCmdArch: arm - numShards: 1 - shardNum: 1 - - template: azure-devops/run-build.yml + - stage: Build_ARM64 + dependsOn: Code_Format + displayName: 'Build' + jobs: + - template: azure-devops/cross-build.yml parameters: targetPlatform: arm64 vsDevCmdArch: arm64 - numShards: 1 - shardNum: 1 diff --git a/stl/inc/atomic b/stl/inc/atomic index 5e229aefe28..ca7c2ca2974 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -75,6 +75,84 @@ extern "C" _NODISCARD char __stdcall __std_atomic_has_cmpxchg16b() noexcept; #define _ATOMIC_HAS_DCAS 0 #endif // _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 || !defined(_M_X64) || defined(_M_ARM64EC) +#if defined(_M_ARM64) && defined(__clang__) && __clang_major__ == 11 // TRANSITION, LLVM 12 +inline unsigned char _InterlockedCompareExchange128( + __int64 volatile* _Destination, __int64 _Val_high, __int64 _Val_low, __int64* _Comparand) { + auto _Dest = reinterpret_cast<__int128 volatile*>(_Destination); + auto _Cmp = reinterpret_cast<__int128*>(_Comparand); + __int128 _Val; + reinterpret_cast<__int64*>(&_Val)[0] = _Val_low; + reinterpret_cast<__int64*>(&_Val)[1] = _Val_high; + + __int128 _Stored; + do { + if (_Stored = __builtin_arm_ldaex(_Dest); _Stored != *_Cmp) { + *_Cmp = _Stored; + return 0; + } + } while (__builtin_arm_stlex(_Val, _Dest)); + + return 1; +} + +inline unsigned char _InterlockedCompareExchange128_acq( + __int64 volatile* _Destination, __int64 _Val_high, __int64 _Val_low, __int64* _Comparand) { + auto _Dest = reinterpret_cast<__int128 volatile*>(_Destination); + auto _Cmp = reinterpret_cast<__int128*>(_Comparand); + __int128 _Val; + reinterpret_cast<__int64*>(&_Val)[0] = _Val_low; + reinterpret_cast<__int64*>(&_Val)[1] = _Val_high; + + __int128 _Stored; + do { + if (_Stored = __builtin_arm_ldaex(_Dest); _Stored != *_Cmp) { + *_Cmp = _Stored; + return 0; + } + } while (__builtin_arm_strex(_Val, _Dest)); + + return 1; +} + +inline unsigned char _InterlockedCompareExchange128_nf( + __int64 volatile* _Destination, __int64 _Val_high, __int64 _Val_low, __int64* _Comparand) { + auto _Dest = reinterpret_cast<__int128 volatile*>(_Destination); + auto _Cmp = reinterpret_cast<__int128*>(_Comparand); + __int128 _Val; + reinterpret_cast<__int64*>(&_Val)[0] = _Val_low; + reinterpret_cast<__int64*>(&_Val)[1] = _Val_high; + + __int128 _Stored; + do { + if (_Stored = __builtin_arm_ldrex(_Dest); _Stored != *_Cmp) { + *_Cmp = _Stored; + return 0; + } + } while (__builtin_arm_strex(_Val, _Dest)); + + return 1; +} + +inline unsigned char _InterlockedCompareExchange128_rel( + __int64 volatile* _Destination, __int64 _Val_high, __int64 _Val_low, __int64* _Comparand) { + auto _Dest = reinterpret_cast<__int128 volatile*>(_Destination); + auto _Cmp = reinterpret_cast<__int128*>(_Comparand); + __int128 _Val; + reinterpret_cast<__int64*>(&_Val)[0] = _Val_low; + reinterpret_cast<__int64*>(&_Val)[1] = _Val_high; + + __int128 _Stored; + do { + if (_Stored = __builtin_arm_ldaex(_Dest); _Stored != *_Cmp) { + *_Cmp = _Stored; + return 0; + } + } while (__builtin_arm_stlex(_Val, _Dest)); + + return 1; +} +#endif // ^^^ ARM64 && LLVM 11 workaround ^^^ + // MACRO _ATOMIC_CHOOSE_INTRINSIC #if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC)) #define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \ @@ -471,18 +549,6 @@ bool __stdcall _Atomic_wait_compare_non_lock_free( #ifdef _WIN64 inline bool __stdcall _Atomic_wait_compare_16_bytes(const void* _Storage, void* _Comparand, size_t, void*) noexcept { -#if defined(__clang__) && defined(_M_ARM64) // TRANSITION, Clang 12 - const auto _Dest = static_cast<__int128*>(const_cast(_Storage)); - const auto _Cmp = static_cast(_Comparand); - - do { - if (__builtin_arm_ldrex(_Dest) != *_Cmp) { - return false; - } - } while (__builtin_arm_strex(*_Cmp, _Dest)); - - return true; -#else // ^^^ workaround / no workaround vvv const auto _Dest = static_cast(const_cast(_Storage)); const auto _Cmp = static_cast(_Comparand); alignas(16) long long _Tmp[2] = {_Cmp[0], _Cmp[1]}; @@ -491,7 +557,6 @@ inline bool __stdcall _Atomic_wait_compare_16_bytes(const void* _Storage, void* #else // ^^^ _M_X64 / ARM64 vvv return _InterlockedCompareExchange128_nf(_Dest, _Tmp[1], _Tmp[0], _Tmp) != 0; #endif // ^^^ ARM64 ^^^ -#endif // TRANSITION, Clang 12 } #endif // _WIN64 #endif // _HAS_CXX20 diff --git a/stl/inc/bit b/stl/inc/bit index d933364942c..56e6cdcb37f 100644 --- a/stl/inc/bit +++ b/stl/inc/bit @@ -211,6 +211,24 @@ _NODISCARD int _Checked_x86_x64_popcount(const _Ty _Val) noexcept { #if defined(_M_ARM) || defined(_M_ARM64) +#ifdef __clang__ // TRANSITION, GH-1586 +_NODISCARD constexpr int _Clang_arm_arm64_countl_zero(const unsigned short _Val) { + return __builtin_clzs(_Val); +} + +_NODISCARD constexpr int _Clang_arm_arm64_countl_zero(const unsigned int _Val) { + return __builtin_clz(_Val); +} + +_NODISCARD constexpr int _Clang_arm_arm64_countl_zero(const unsigned long _Val) { + return __builtin_clzl(_Val); +} + +_NODISCARD constexpr int _Clang_arm_arm64_countl_zero(const unsigned long long _Val) { + return __builtin_clzll(_Val); +} +#endif // TRANSITION, GH-1586 + template _NODISCARD int _Checked_arm_arm64_countl_zero(const _Ty _Val) noexcept { constexpr int _Digits = numeric_limits<_Ty>::digits; @@ -218,11 +236,20 @@ _NODISCARD int _Checked_arm_arm64_countl_zero(const _Ty _Val) noexcept { return _Digits; } +#ifdef __clang__ // TRANSITION, GH-1586 + if constexpr (is_same_v, unsigned char>) { + return _Clang_arm_arm64_countl_zero(static_cast(_Val)) + - (numeric_limits::digits - _Digits); + } else { + return _Clang_arm_arm64_countl_zero(_Val); + } +#else // ^^^ workaround / no workaround vvv if constexpr (_Digits <= 32) { - return _CountLeadingZeros(_Val); + return static_cast(_CountLeadingZeros(_Val)); } else { - return _CountLeadingZeros64(_Val); + return static_cast(_CountLeadingZeros64(_Val)); } +#endif // TRANSITION, GH-1586 } #endif // defined(_M_ARM) || defined(_M_ARM64) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fab5573e6b1..76a64ab60d2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,6 +12,8 @@ set(LLVM_PROJECT_SOURCE_DIR "${STL_SOURCE_DIR}/llvm-project" CACHE PATH set(LIBCXX_SOURCE_DIR "${LLVM_PROJECT_SOURCE_DIR}/libcxx" CACHE PATH "Location of the libcxx source tree") +option(TESTS_BUILD_ONLY "Only run the build steps of tests" OFF) + add_subdirectory(libcxx) add_subdirectory(std) add_subdirectory(tr1) diff --git a/tests/libcxx/lit.site.cfg.in b/tests/libcxx/lit.site.cfg.in index fb530312e8a..0557736b467 100644 --- a/tests/libcxx/lit.site.cfg.in +++ b/tests/libcxx/lit.site.cfg.in @@ -30,6 +30,7 @@ lit_config.test_subdirs[config.name] = ['@LIBCXX_SOURCE_DIR@/test/std'] lit_config.cxx_runtime = '@CMAKE_RUNTIME_OUTPUT_DIRECTORY@' lit_config.target_arch = '@VCLIBS_TARGET_ARCHITECTURE@' +lit_config.build_only = '@TESTS_BUILD_ONLY@'.lower() in ['1', 'true', 'on'] # Add parameters and features to the config stl.test.config.configure( diff --git a/tests/std/include/test_atomic_wait.hpp b/tests/std/include/test_atomic_wait.hpp index a3d9b4471c2..87c032eea95 100644 --- a/tests/std/include/test_atomic_wait.hpp +++ b/tests/std/include/test_atomic_wait.hpp @@ -187,6 +187,8 @@ struct big_char_like { friend bool operator==(big_char_like, big_char_like) = delete; }; +#pragma warning(push) +#pragma warning(disable : 4324) // structure was padded due to alignment specifier template struct with_padding_bits { alignas(size) char value; @@ -197,6 +199,7 @@ struct with_padding_bits { friend bool operator==(with_padding_bits, with_padding_bits) = delete; }; +#pragma warning(pop) inline void test_atomic_wait() { // wait for all the threads to be waiting; if this value is too small the test might be ineffective but should not @@ -249,7 +252,9 @@ inline void test_atomic_wait() { test_pad_bits>(waiting_duration); test_pad_bits>(waiting_duration); test_pad_bits>(waiting_duration); +#ifndef _M_ARM test_pad_bits>(waiting_duration); test_pad_bits>(waiting_duration); +#endif // ^^^ !ARM ^^^ #endif // __clang__, TRANSITION, LLVM-46685 } diff --git a/tests/std/lit.site.cfg.in b/tests/std/lit.site.cfg.in index 6455f31677a..653f76d16a3 100644 --- a/tests/std/lit.site.cfg.in +++ b/tests/std/lit.site.cfg.in @@ -30,6 +30,7 @@ lit_config.test_subdirs[config.name] = ['@CMAKE_CURRENT_SOURCE_DIR@/tests'] lit_config.cxx_headers = '@STL_TESTED_HEADERS_DIR@' lit_config.cxx_runtime = '@CMAKE_RUNTIME_OUTPUT_DIRECTORY@' lit_config.target_arch = '@VCLIBS_TARGET_ARCHITECTURE@' +lit_config.build_only = '@TESTS_BUILD_ONLY@'.lower() in ['1', 'true', 'on'] # Add parameters and features to the config stl.test.config.configure( diff --git a/tests/std/tests/GH_000690_overaligned_function/test.cpp b/tests/std/tests/GH_000690_overaligned_function/test.cpp index effd03765af..0e5623f2054 100644 --- a/tests/std/tests/GH_000690_overaligned_function/test.cpp +++ b/tests/std/tests/GH_000690_overaligned_function/test.cpp @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// UNSUPPORTED: arm + #include #include #include diff --git a/tests/std/tests/P0898R3_concepts/test.cpp b/tests/std/tests/P0898R3_concepts/test.cpp index 6a3ece735e0..4ae135c53ad 100644 --- a/tests/std/tests/P0898R3_concepts/test.cpp +++ b/tests/std/tests/P0898R3_concepts/test.cpp @@ -2876,10 +2876,13 @@ namespace test_invocable_concepts { #define MCALLCONV __thiscall #include "invocable_cc.hpp" +#if !defined(_M_ARM) && !defined(_M_ARM64) #define NAME test_vector_vector #define CALLCONV __vectorcall #define MCALLCONV __vectorcall #include "invocable_cc.hpp" +#endif // ^^^ !ARM && !ARM64 ^^^ + } // namespace test_invocable_concepts namespace test_predicate { diff --git a/tests/tr1/lit.site.cfg.in b/tests/tr1/lit.site.cfg.in index 8e6afee6d49..a0d226bca8c 100644 --- a/tests/tr1/lit.site.cfg.in +++ b/tests/tr1/lit.site.cfg.in @@ -29,6 +29,7 @@ lit_config.test_subdirs[config.name] = ['@CMAKE_CURRENT_SOURCE_DIR@/tests'] lit_config.cxx_runtime = '@CMAKE_RUNTIME_OUTPUT_DIRECTORY@' lit_config.target_arch = '@VCLIBS_TARGET_ARCHITECTURE@' +lit_config.build_only = '@TESTS_BUILD_ONLY@'.lower() in ['1', 'true', 'on'] # Add parameters and features to the config stl.test.config.configure( diff --git a/tests/utils/stl/test/format.py b/tests/utils/stl/test/format.py index 85fa6ff80bd..c9d40635dd2 100644 --- a/tests/utils/stl/test/format.py +++ b/tests/utils/stl/test/format.py @@ -152,11 +152,11 @@ class SharedState: shared.env['TEMPDIR'] = execDir return [ - ('Build setup', self.getBuildSetupSteps(test, litConfig, shared)), - ('Build', self.getBuildSteps(test, litConfig, shared)), - ('Intellisense response file', self.getIsenseRspFileSteps(test, litConfig, shared)), - ('Test setup', self.getTestSetupSteps(test, litConfig, shared)), - ('Test', self.getTestSteps(test, litConfig, shared))] + ('Build setup', self.getBuildSetupSteps(test, litConfig, shared), True), + ('Build', self.getBuildSteps(test, litConfig, shared), True), + ('Intellisense response file', self.getIsenseRspFileSteps(test, litConfig, shared), False), + ('Test setup', self.getTestSetupSteps(test, litConfig, shared), False), + ('Test', self.getTestSteps(test, litConfig, shared), False)] def getBuildSetupSteps(self, test, litConfig, shared): shutil.rmtree(shared.execDir, ignore_errors=True) @@ -210,17 +210,17 @@ def execute(self, test, litConfig): if result: return result - if test.expectedResult and test.expectedResult.isFailure: - failVar = lit.Test.XFAIL - passVar = lit.Test.XPASS - else: - failVar = lit.Test.FAIL - passVar = lit.Test.PASS + # This test is expected to fail at some point, but we're not sure if + # it should fail during the build phase or the test phase. + someFail = test.expectedResult and test.expectedResult.isFailure stages = self.getStages(test, litConfig) report = '' - for stageName, steps in stages: + for stageName, steps, isBuildStep in stages: + if not isBuildStep and litConfig.build_only: + continue + report += stageName + ' steps:\n' for step in steps: cmd, out, err, rc = self.runStep(step, litConfig) @@ -232,9 +232,11 @@ def execute(self, test, litConfig): report += stl.util.makeReport(cmd, out, err, rc) if (step.shouldFail and rc == 0) or (not step.shouldFail and rc != 0): - return (failVar, report) + if someFail: + test.xfails = ['*'] + return (lit.Test.FAIL, report) - return (passVar, '') + return (lit.Test.PASS, '') except Exception as e: litConfig.error(repr(e)) diff --git a/tests/utils/stl/test/tests.py b/tests/utils/stl/test/tests.py index 3fda56ede3d..3f337d28210 100644 --- a/tests/utils/stl/test/tests.py +++ b/tests/utils/stl/test/tests.py @@ -7,13 +7,13 @@ # #===----------------------------------------------------------------------===## -from enum import Flag, auto +from enum import auto, Flag from itertools import chain import copy import os import shutil -from lit.Test import SKIPPED, Result, Test, UNRESOLVED, UNSUPPORTED +from lit.Test import Result, SKIPPED, Test, UNRESOLVED, UNSUPPORTED from libcxx.test.dsl import Feature import lit @@ -79,6 +79,15 @@ def configureTest(self, litConfig): self.compileFlags.extend(['/dE--write-isense-rsp', '/dE' + self.isenseRspPath]) self._configureTestType() + + forceFail = self.expectedResult and self.expectedResult.isFailure + buildFail = forceFail and TestType.COMPILE|TestType.LINK in self.testType + + if (litConfig.build_only and buildFail): + self.xfails = ['*'] + elif (not litConfig.build_only and forceFail): + self.xfails = ['*'] + return None def _parseTest(self): @@ -163,8 +172,6 @@ def _configureExpectedResult(self, litConfig): if self.expectedResult is not None: if self.expectedResult == SKIPPED: return Result(SKIPPED, 'This test was explicitly marked as skipped') - elif self.expectedResult.isFailure: - self.xfails = ['*'] elif self.config.unsupported: return Result(UNSUPPORTED, 'This test was marked as unsupported by a lit.cfg') @@ -202,6 +209,10 @@ def _handleEnvlst(self, litConfig): self.compileFlags.append('-m64') elif (targetArch == 'x86'.casefold()): self.compileFlags.append('-m32') + elif (targetArch == 'arm'.casefold()): + return Result(UNSUPPORTED, 'clang targeting arm is not supported') + elif (targetArch == 'arm64'.casefold()): + self.compileFlags.append('--target=arm64-pc-windows-msvc') if ('nvcc'.casefold() in os.path.basename(cxx).casefold()): # nvcc only supports targeting x64