diff --git a/.ci/generate_test_report_lib.py b/.ci/generate_test_report_lib.py
index 36c95852452ac..7820fbda803d7 100644
--- a/.ci/generate_test_report_lib.py
+++ b/.ci/generate_test_report_lib.py
@@ -41,10 +41,12 @@ def _parse_ninja_log(ninja_log: list[str]) -> list[tuple[str, str]]:
# touch test/4.stamp
#
# index will point to the line that starts with Failed:. The progress
- # indicator is the line before this ([4/5] test/4.stamp) and contains a pretty
- # printed version of the target being built (test/4.stamp). We use this line
- # and remove the progress information to get a succinct name for the target.
- failing_action = ninja_log[index - 1].split("] ")[1]
+ # indicator is sometimes the line before this ([4/5] test/4.stamp) and
+ # will contain a pretty printed version of the target being built
+ # (test/4.stamp) when accurate. We instead parse the failed line rather
+ # than the progress indicator as the progress indicator may not be
+ # aligned with the failure.
+ failing_action = ninja_log[index].split("FAILED: ")[1]
failure_log = []
while (
index < len(ninja_log)
diff --git a/.ci/generate_test_report_lib_test.py b/.ci/generate_test_report_lib_test.py
index 431e10da6405a..4068a3b7300a4 100644
--- a/.ci/generate_test_report_lib_test.py
+++ b/.ci/generate_test_report_lib_test.py
@@ -39,7 +39,7 @@ def test_find_failure_ninja_logs(self):
self.assertEqual(
failures[0],
(
- "test/4.stamp",
+ "touch test/4.stamp",
dedent(
"""\
FAILED: touch test/4.stamp
@@ -77,7 +77,7 @@ def test_ninja_log_end(self):
self.assertEqual(
failures[0],
(
- "test/3.stamp",
+ "touch test/3.stamp",
dedent(
"""\
FAILED: touch test/3.stamp
@@ -106,7 +106,7 @@ def test_ninja_log_multiple_failures(self):
self.assertEqual(
failures[0],
(
- "test/2.stamp",
+ "touch test/2.stamp",
dedent(
"""\
FAILED: touch test/2.stamp
@@ -117,7 +117,7 @@ def test_ninja_log_multiple_failures(self):
self.assertEqual(
failures[1],
(
- "test/4.stamp",
+ "touch test/4.stamp",
dedent(
"""\
FAILED: touch test/4.stamp
@@ -150,7 +150,7 @@ def test_ninja_log_runtimes_failure(self):
self.assertEqual(
failures[0],
(
- "test/2.stamp",
+ "touch test/2.stamp",
dedent(
"""\
FAILED: touch test/2.stamp
@@ -159,6 +159,34 @@ def test_ninja_log_runtimes_failure(self):
),
)
+ # Test that we correctly handle cases where the FAILED: line does not
+ # match up with the progress indicator.
+ def test_ninja_log_mismatched_failed(self):
+ failures = generate_test_report_lib.find_failure_in_ninja_logs(
+ [
+ [
+ "[1/5] test/1.stamp",
+ "[2/5] test/2.stamp",
+ "ModuleNotFoundError: No module named 'mount_langley'",
+ "FAILED: tools/check-langley",
+ "Wow! This system is really broken!",
+ "[5/5] test/5.stamp",
+ ]
+ ]
+ )
+ self.assertEqual(len(failures), 1)
+ self.assertEqual(
+ failures[0],
+ (
+ "tools/check-langley",
+ dedent(
+ """\
+ FAILED: tools/check-langley
+ Wow! This system is really broken!"""
+ ),
+ ),
+ )
+
def test_title_only(self):
self.assertEqual(
generate_test_report_lib.generate_report("Foo", 0, [], []),
@@ -448,7 +476,7 @@ def test_no_failures_multiple_build_failed_ninja_log(self):
All tests passed but another part of the build **failed**. Click on a failure below to see the details.
- test/2.stamp
+ touch test/2.stamp
```
FAILED: touch test/2.stamp
@@ -456,7 +484,7 @@ def test_no_failures_multiple_build_failed_ninja_log(self):
```
- test/4.stamp
+ touch test/4.stamp
```
FAILED: touch test/4.stamp
diff --git a/.github/workflows/build-ci-container-tooling.yml b/.github/workflows/build-ci-container-tooling.yml
index c77c78617666d..992947eb2fffb 100644
--- a/.github/workflows/build-ci-container-tooling.yml
+++ b/.github/workflows/build-ci-container-tooling.yml
@@ -63,7 +63,7 @@ jobs:
podman save ${{ steps.vars.outputs.container-name-lint-tag }} > ${{ steps.vars.outputs.container-lint-filename }}
- name: Upload container image
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: container-amd64
path: "*.tar"
diff --git a/.github/workflows/check-ci.yml b/.github/workflows/check-ci.yml
index f18a69c192ee9..6ecad5536109b 100644
--- a/.github/workflows/check-ci.yml
+++ b/.github/workflows/check-ci.yml
@@ -28,7 +28,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
- python-version: 3.13
+ python-version: 3.14
cache: 'pip'
- name: Install Python Dependencies
run: |
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index b5f3413fe3b6b..7374777cb759c 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -97,7 +97,7 @@ jobs:
- name: Setup Python env
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
- python-version: '3.13'
+ python-version: '3.14'
cache: 'pip'
cache-dependency-path: 'llvm/docs/requirements-hashed.txt'
- name: Install python dependencies
diff --git a/.github/workflows/gha-codeql.yml b/.github/workflows/gha-codeql.yml
index 63388ebc706bd..6d490ca2c4b29 100644
--- a/.github/workflows/gha-codeql.yml
+++ b/.github/workflows/gha-codeql.yml
@@ -29,9 +29,9 @@ jobs:
sparse-checkout: |
.github/
- name: Initialize CodeQL
- uses: github/codeql-action/init@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # v3.30.4
+ uses: github/codeql-action/init@5d5cd550d3e189c569da8f16ea8de2d821c9bf7a # v3.31.2
with:
languages: actions
queries: security-extended
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # v3.30.4
+ uses: github/codeql-action/analyze@5d5cd550d3e189c569da8f16ea8de2d821c9bf7a # v3.31.2
diff --git a/.github/workflows/hlsl-test-all.yaml b/.github/workflows/hlsl-test-all.yaml
index dcb852312d41a..ce6ccfa23df6a 100644
--- a/.github/workflows/hlsl-test-all.yaml
+++ b/.github/workflows/hlsl-test-all.yaml
@@ -54,7 +54,7 @@ jobs:
path: golden-images
- name: Setup Windows
if: runner.os == 'Windows'
- uses: llvm/actions/setup-windows@main
+ uses: llvm/actions/setup-windows@42d80571b13f4599bbefbc7189728b64723c7f78 # main
with:
arch: amd64
- name: Build DXC
@@ -80,7 +80,7 @@ jobs:
ninja check-hlsl-unit
ninja ${{ inputs.TestTarget }}
- name: Publish Test Results
- uses: EnricoMi/publish-unit-test-result-action/macos@3a74b2957438d0b6e2e61d67b05318aa25c9e6c6 # v2.20.0
+ uses: EnricoMi/publish-unit-test-result-action/macos@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0
if: always() && runner.os == 'macOS'
with:
comment_mode: off
diff --git a/.github/workflows/libclang-abi-tests.yml b/.github/workflows/libclang-abi-tests.yml
index 5ccf976848197..432c45744abda 100644
--- a/.github/workflows/libclang-abi-tests.yml
+++ b/.github/workflows/libclang-abi-tests.yml
@@ -100,7 +100,7 @@ jobs:
repo: ${{ github.repository }}
steps:
- name: Install Ninja
- uses: llvm/actions/install-ninja@main
+ uses: llvm/actions/install-ninja@42d80571b13f4599bbefbc7189728b64723c7f78 # main
- name: Install abi-compliance-checker
run: |
sudo apt-get update
diff --git a/.github/workflows/libcxx-build-containers.yml b/.github/workflows/libcxx-build-containers.yml
index 312cb47fc3d93..4bce86145fc0c 100644
--- a/.github/workflows/libcxx-build-containers.yml
+++ b/.github/workflows/libcxx-build-containers.yml
@@ -55,7 +55,7 @@ jobs:
TAG: ${{ github.sha }}
- name: Log in to GitHub Container Registry
- uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
+ uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
diff --git a/.github/workflows/libcxx-run-benchmarks.yml b/.github/workflows/libcxx-run-benchmarks.yml
index 9e8f55859fc7a..e2ca940d2f0b3 100644
--- a/.github/workflows/libcxx-run-benchmarks.yml
+++ b/.github/workflows/libcxx-run-benchmarks.yml
@@ -35,7 +35,7 @@ jobs:
steps:
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
- python-version: '3.13'
+ python-version: '3.14'
- name: Extract information from the PR
id: vars
diff --git a/.github/workflows/llvm-abi-tests.yml b/.github/workflows/llvm-abi-tests.yml
index f73d180bb0005..961f1cc79389d 100644
--- a/.github/workflows/llvm-abi-tests.yml
+++ b/.github/workflows/llvm-abi-tests.yml
@@ -88,7 +88,7 @@ jobs:
repo: ${{ github.repository }}
steps:
- name: Install Ninja
- uses: llvm/actions/install-ninja@main
+ uses: llvm/actions/install-ninja@42d80571b13f4599bbefbc7189728b64723c7f78 # main
- name: Install abi-compliance-checker
run: |
sudo apt-get update
diff --git a/.github/workflows/llvm-bugs.yml b/.github/workflows/llvm-bugs.yml
index 7d42abfadde7b..3274f1adf9e61 100644
--- a/.github/workflows/llvm-bugs.yml
+++ b/.github/workflows/llvm-bugs.yml
@@ -39,6 +39,12 @@ jobs:
repo: context.repo.repo
})
.then((issue) => {
+ var maybeTruncatedBody = issue.data.body;
+ if (maybeTruncatedBody.length > 15000) {
+ maybeTruncatedBody = maybeTruncatedBody.substring(0,
+ 15000) +
+ "Please see the issue for the entire body."
+ }
const payload = {
author : issue.data.user.login,
issue : issue.data.number,
@@ -46,7 +52,7 @@ jobs:
url : issue.data.html_url,
labels : issue.data.labels.map((label) => label.name),
assignee : issue.data.assignees.map((assignee) => assignee.login),
- body : issue.data.body
+ body : maybeTruncatedBody
};
const data = {
diff --git a/.github/workflows/new-issues.yml b/.github/workflows/new-issues.yml
index 8480a657cc717..a5dcad28dbe24 100644
--- a/.github/workflows/new-issues.yml
+++ b/.github/workflows/new-issues.yml
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-24.04
if: github.repository == 'llvm/llvm-project'
steps:
- - uses: llvm/actions/issue-labeler@main
+ - uses: llvm/actions/issue-labeler@42d80571b13f4599bbefbc7189728b64723c7f78 # main
with:
repo-token: ${{ secrets.ISSUE_SUBSCRIBER_TOKEN }}
configuration-path: .github/new-issues-labeler.yml
diff --git a/.github/workflows/premerge.yaml b/.github/workflows/premerge.yaml
index 6303a119750b5..973d3abf358ce 100644
--- a/.github/workflows/premerge.yaml
+++ b/.github/workflows/premerge.yaml
@@ -190,7 +190,7 @@ jobs:
with:
max-size: "2000M"
- name: Install Ninja
- uses: llvm/actions/install-ninja@main
+ uses: llvm/actions/install-ninja@42d80571b13f4599bbefbc7189728b64723c7f78 # main
- name: Build and Test
run: |
source <(git diff --name-only HEAD~1...HEAD | python3 .ci/compute_projects.py)
diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml
index fa73b9d9fe8d0..25f426b7814df 100644
--- a/.github/workflows/release-binaries.yml
+++ b/.github/workflows/release-binaries.yml
@@ -68,7 +68,7 @@ jobs:
# due to https://github.com/actions/runner-images/issues/10385
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
- python-version: '3.13'
+ python-version: '3.14'
- name: Checkout LLVM
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -138,7 +138,6 @@ jobs:
target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_LTO=OFF"
fi
- echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT
case "${{ inputs.runs-on }}" in
ubuntu-22.04*)
build_runs_on="depot-${{ inputs.runs-on }}-16"
@@ -157,6 +156,23 @@ jobs:
build_runs_on=$test_runs_on
;;
esac
+
+ case "$build_runs_on" in
+ # These runners cannot build the full release package faster than
+ # the 6 hours timeout limit, so we need to use a configuration
+ # that builds more quickly.
+ macos-14)
+ bootstrap_prefix="BOOTSTRAP"
+ target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_LTO=OFF -DLLVM_RELEASE_ENABLE_PGO=OFF"
+ ;;
+ *)
+ bootstrap_prefix="BOOTSTRAP_BOOTSTRAP"
+ ;;
+ esac
+
+ target_cmake_flags="$target_cmake_flags -D${bootstrap_prefix}_CPACK_PACKAGE_FILE_NAME=$release_binary_basename"
+
+ echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT
echo "build-runs-on=$build_runs_on" >> $GITHUB_OUTPUT
echo "test-runs-on=$test_runs_on" >> $GITHUB_OUTPUT
@@ -173,11 +189,11 @@ jobs:
ref: ${{ needs.prepare.outputs.ref }}
- name: Install Ninja
- uses: llvm/actions/install-ninja@a1ea791b03c8e61f53a0e66f2f73db283aa0f01e # main
+ uses: llvm/actions/install-ninja@42d80571b13f4599bbefbc7189728b64723c7f78 # main
- name: Setup Windows
if: startsWith(runner.os, 'Windows')
- uses: llvm/actions/setup-windows@main
+ uses: llvm/actions/setup-windows@42d80571b13f4599bbefbc7189728b64723c7f78 # main
with:
arch: amd64
@@ -200,8 +216,7 @@ jobs:
# so we need to set some extra cmake flags to disable this.
cmake -G Ninja -S llvm -B ${{ steps.setup-stage.outputs.build-prefix }}/build \
${{ needs.prepare.outputs.target-cmake-flags }} \
- -C clang/cmake/caches/Release.cmake \
- -DBOOTSTRAP_BOOTSTRAP_CPACK_PACKAGE_FILE_NAME="${{ needs.prepare.outputs.release-binary-basename }}"
+ -C clang/cmake/caches/Release.cmake
- name: Build
shell: bash
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index c07df338cf989..bd3277a8b452c 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -36,7 +36,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
+ uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
results_file: results.sarif
results_format: sarif
diff --git a/bolt/README.md b/bolt/README.md
index 902d1eb6e7694..55f742c5019f5 100644
--- a/bolt/README.md
+++ b/bolt/README.md
@@ -173,7 +173,7 @@ Once you have `perf.fdata` ready, you can use it for optimizations with
BOLT. Assuming your environment is setup to include the right path, execute
`llvm-bolt`:
```
-$ llvm-bolt -o .bolt -data=perf.fdata -reorder-blocks=ext-tsp -reorder-functions=hfsort -split-functions -split-all-cold -split-eh -dyno-stats
+$ llvm-bolt -o .bolt -data=perf.fdata -reorder-blocks=ext-tsp -reorder-functions=cdsort -split-functions -split-all-cold -split-eh -dyno-stats
```
If you do need an updated debug info, then add `-update-debug-sections` option
diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md
index 43ceceee7de45..7c6e01d669b74 100644
--- a/bolt/docs/CommandLineArgumentReference.md
+++ b/bolt/docs/CommandLineArgumentReference.md
@@ -381,11 +381,6 @@
Set verbosity level for diagnostic output
-- `--write-dwp`
-
- Output a single dwarf package file (dwp) instead of multiple non-relocatable
- dwarf object files (dwo).
-
### BOLT optimization options:
- `--align-blocks`
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index d666c10885ad5..5e349cd69fb43 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -840,6 +840,16 @@ class MCPlusBuilder {
return false;
}
+ virtual bool isLDRWl(const MCInst &Inst) const {
+ llvm_unreachable("not implemented");
+ return false;
+ }
+
+ virtual bool isLDRXl(const MCInst &Inst) const {
+ llvm_unreachable("not implemented");
+ return false;
+ }
+
virtual bool isMOVW(const MCInst &Inst) const {
llvm_unreachable("not implemented");
return false;
@@ -1789,6 +1799,19 @@ class MCPlusBuilder {
llvm_unreachable("not implemented");
}
+ /// Take \p LDRInst and return ADRP+LDR instruction sequence - for
+ ///
+ /// ldr x0, [label]
+ ///
+ /// the following sequence will be generated:
+ ///
+ /// adrp x0, PageBase(label)
+ /// ldr x0, [x0, PageOffset(label)]
+ virtual InstructionListType createAdrpLdr(const MCInst &LDRInst,
+ MCContext *Ctx) const {
+ llvm_unreachable("not implemented");
+ }
+
/// Return not 0 if the instruction CurInst, in combination with the recent
/// history of disassembled instructions supplied by [Begin, End), is a linker
/// generated veneer/stub that needs patching. This happens in AArch64 when
diff --git a/bolt/include/bolt/Passes/ADRRelaxationPass.h b/bolt/include/bolt/Passes/AArch64RelaxationPass.h
similarity index 51%
rename from bolt/include/bolt/Passes/ADRRelaxationPass.h
rename to bolt/include/bolt/Passes/AArch64RelaxationPass.h
index b9f92dec7f03b..b9185a1e34388 100644
--- a/bolt/include/bolt/Passes/ADRRelaxationPass.h
+++ b/bolt/include/bolt/Passes/AArch64RelaxationPass.h
@@ -1,4 +1,4 @@
-//===- bolt/Passes/ADRRelaxationPass.h --------------------------*- C++ -*-===//
+//===- bolt/Passes/AArch64RelaxationPass.h ----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,29 +6,29 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares the ADRRelaxationPass class, which replaces AArch64
-// non-local ADR instructions with ADRP + ADD due to small offset range of ADR
-// instruction (+- 1MB) which could be easily overflowed after BOLT
-// optimizations. Such problems are usually connected with errata 843419
-// https://developer.arm.com/documentation/epm048406/2100/
+// This file declares the AArch64RelaxationPass class, which replaces AArch64
+// non-local ADR/LDR instructions with ADRP + ADD/LDR due to small offset
+// range of ADR and LDR instruction (+- 1MB) which could be easily overflowed
+// after BOLT optimizations. Such problems are usually connected with errata
+// 843419: https://developer.arm.com/documentation/epm048406/2100/
// The linker could replace ADRP instruction with ADR in some cases.
//
//===----------------------------------------------------------------------===//
-#ifndef BOLT_PASSES_ADRRELAXATIONPASS_H
-#define BOLT_PASSES_ADRRELAXATIONPASS_H
+#ifndef BOLT_PASSES_AARCH64RELAXATIONPASS_H
+#define BOLT_PASSES_AARCH64RELAXATIONPASS_H
#include "bolt/Passes/BinaryPasses.h"
namespace llvm {
namespace bolt {
-class ADRRelaxationPass : public BinaryFunctionPass {
+class AArch64RelaxationPass : public BinaryFunctionPass {
public:
- explicit ADRRelaxationPass(const cl::opt &PrintPass)
+ explicit AArch64RelaxationPass(const cl::opt &PrintPass)
: BinaryFunctionPass(PrintPass) {}
- const char *getName() const override { return "adr-relaxation"; }
+ const char *getName() const override { return "aarch64-relaxation"; }
/// Pass entry point
Error runOnFunctions(BinaryContext &BC) override;
diff --git a/bolt/include/bolt/Passes/FixRelaxationPass.h b/bolt/include/bolt/Passes/FixRelaxationPass.h
index 50b64480aa62e..cf5a8a1fcb134 100644
--- a/bolt/include/bolt/Passes/FixRelaxationPass.h
+++ b/bolt/include/bolt/Passes/FixRelaxationPass.h
@@ -1,4 +1,4 @@
-//===- bolt/Passes/ADRRelaxationPass.h --------------------------*- C++ -*-===//
+//===- bolt/Passes/FixRelaxationPass.h --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index a383ced1712e3..7af32c8c56635 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -78,6 +78,11 @@ cl::opt CompDirOverride(
"to *.dwo files."),
cl::Hidden, cl::init(""), cl::cat(BoltCategory));
+static cl::opt CloneConstantIsland("clone-constant-island",
+ cl::desc("clone constant islands"),
+ cl::Hidden, cl::init(true),
+ cl::ZeroOrMore, cl::cat(BoltCategory));
+
static cl::opt
FailOnInvalidPadding("fail-on-invalid-padding", cl::Hidden, cl::init(false),
cl::desc("treat invalid code padding as error"),
@@ -461,7 +466,8 @@ BinaryContext::handleAddressRef(uint64_t Address, BinaryFunction &BF,
// of dynamic relocs, as we currently do not support cloning them.
// Notice: we might fail to link because of this, if the original constant
// island we are referring would be emitted too far away.
- if (IslandIter->second->hasDynamicRelocationAtIsland()) {
+ if (IslandIter->second->hasDynamicRelocationAtIsland() ||
+ !opts::CloneConstantIsland) {
MCSymbol *IslandSym =
IslandIter->second->getOrCreateIslandAccess(Address);
if (IslandSym)
@@ -469,6 +475,12 @@ BinaryContext::handleAddressRef(uint64_t Address, BinaryFunction &BF,
} else if (MCSymbol *IslandSym =
IslandIter->second->getOrCreateProxyIslandAccess(Address,
BF)) {
+ LLVM_DEBUG(
+ dbgs() << "BOLT-DEBUG: clone constant island at address 0x"
+ << Twine::utohexstr(IslandIter->first) << " with size of 0x"
+ << Twine::utohexstr(
+ IslandIter->second->estimateConstantIslandSize())
+ << " bytes, referenced by " << BF << "\n");
BF.createIslandDependency(IslandSym, IslandIter->second);
return std::make_pair(IslandSym, 0);
}
@@ -778,13 +790,17 @@ void BinaryContext::populateJumpTables() {
}
if (opts::StrictMode && DataPCRelocations.size()) {
- LLVM_DEBUG({
- dbgs() << DataPCRelocations.size()
- << " unclaimed PC-relative relocations left in data:\n";
- for (uint64_t Reloc : DataPCRelocations)
- dbgs() << Twine::utohexstr(Reloc) << '\n';
- });
- assert(0 && "unclaimed PC-relative relocations left in data\n");
+ this->errs() << "BOLT-ERROR: " << DataPCRelocations.size()
+ << " unclaimed PC-relative relocation(s) left in data";
+ if (opts::Verbosity) {
+ this->errs() << ":\n";
+ for (uint64_t RelocOffset : DataPCRelocations)
+ this->errs() << " @0x" << Twine::utohexstr(RelocOffset) << '\n';
+ } else {
+ this->errs() << ". Re-run with -v=1 to see the list\n";
+ }
+ this->errs() << "BOLT-ERROR: unable to proceed with --strict\n";
+ exit(1);
}
clearList(DataPCRelocations);
}
diff --git a/bolt/lib/Passes/ADRRelaxationPass.cpp b/bolt/lib/Passes/AArch64RelaxationPass.cpp
similarity index 67%
rename from bolt/lib/Passes/ADRRelaxationPass.cpp
rename to bolt/lib/Passes/AArch64RelaxationPass.cpp
index c3954c94a7f92..610adad58cfcb 100644
--- a/bolt/lib/Passes/ADRRelaxationPass.cpp
+++ b/bolt/lib/Passes/AArch64RelaxationPass.cpp
@@ -1,4 +1,4 @@
-//===- bolt/Passes/ADRRelaxationPass.cpp ----------------------------------===//
+//===- bolt/Passes/AArch64RelaxationPass.cpp ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the ADRRelaxationPass class.
+// This file implements the AArch64RelaxationPass class.
//
//===----------------------------------------------------------------------===//
-#include "bolt/Passes/ADRRelaxationPass.h"
+#include "bolt/Passes/AArch64RelaxationPass.h"
#include "bolt/Core/ParallelUtilities.h"
#include "bolt/Utils/CommandLineOpts.h"
#include
@@ -20,10 +20,10 @@ using namespace llvm;
namespace opts {
extern cl::OptionCategory BoltCategory;
-static cl::opt
- AdrPassOpt("adr-relaxation",
- cl::desc("Replace ARM non-local ADR instructions with ADRP"),
- cl::init(true), cl::cat(BoltCategory), cl::ReallyHidden);
+static cl::opt AArch64PassOpt(
+ "aarch64-relaxation",
+ cl::desc("Replace ARM non-local ADR/LDR instructions with ADRP"),
+ cl::init(true), cl::cat(BoltCategory), cl::ReallyHidden);
} // namespace opts
namespace llvm {
@@ -35,7 +35,7 @@ namespace bolt {
// jobs and checking the exit flag after it.
static bool PassFailed = false;
-void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
+void AArch64RelaxationPass::runOnFunction(BinaryFunction &BF) {
if (PassFailed)
return;
@@ -43,10 +43,13 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
for (BinaryBasicBlock &BB : BF) {
for (auto It = BB.begin(); It != BB.end(); ++It) {
MCInst &Inst = *It;
- if (!BC.MIB->isADR(Inst))
+ bool IsADR = BC.MIB->isADR(Inst);
+
+ // TODO: Handle other types of LDR (literal, PC-relative) instructions.
+ if (!IsADR && !BC.MIB->isLDRXl(Inst) && !BC.MIB->isLDRWl(Inst))
continue;
- const MCSymbol *Symbol = BC.MIB->getTargetSymbol(Inst);
+ const MCSymbol *Symbol = BC.MIB->getTargetSymbol(Inst, IsADR ? 0 : 1);
if (!Symbol)
continue;
@@ -56,25 +59,27 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
continue;
}
- // Don't relax ADR if it points to the same function and is in the main
- // fragment and BF initial size is < 1MB.
+ // Don't relax ADR/LDR if it points to the same function and is in the
+ // main fragment and BF initial size is < 1MB.
const unsigned OneMB = 0x100000;
if (BF.getSize() < OneMB) {
BinaryFunction *TargetBF = BC.getFunctionForSymbol(Symbol);
if (TargetBF == &BF && !BB.isSplit())
continue;
- // No relaxation needed if ADR references a basic block in the same
+ // No relaxation needed if ADR/LDR references a basic block in the same
// fragment.
if (BinaryBasicBlock *TargetBB = BF.getBasicBlockForLabel(Symbol))
if (BB.getFragmentNum() == TargetBB->getFragmentNum())
continue;
}
- InstructionListType AdrpAdd;
+ InstructionListType AdrpMaterialization;
{
auto L = BC.scopeLock();
- AdrpAdd = BC.MIB->undoAdrpAddRelaxation(Inst, BC.Ctx.get());
+ AdrpMaterialization =
+ IsADR ? BC.MIB->undoAdrpAddRelaxation(Inst, BC.Ctx.get())
+ : BC.MIB->createAdrpLdr(Inst, BC.Ctx.get());
}
if (It != BB.begin() && BC.MIB->isNoop(*std::prev(It))) {
@@ -88,18 +93,18 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
// invalidate this offset, so we have to rely on linker-inserted NOP to
// replace it with ADRP, and abort if it is not present.
auto L = BC.scopeLock();
- BC.errs() << "BOLT-ERROR: cannot relax ADR in non-simple function "
- << BF << '\n';
+ BC.errs() << "BOLT-ERROR: cannot relax " << (IsADR ? "ADR" : "LDR")
+ << " in non-simple function " << BF << '\n';
PassFailed = true;
return;
}
- It = BB.replaceInstruction(It, AdrpAdd);
+ It = BB.replaceInstruction(It, AdrpMaterialization);
}
}
}
-Error ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
- if (!opts::AdrPassOpt || !BC.HasRelocations)
+Error AArch64RelaxationPass::runOnFunctions(BinaryContext &BC) {
+ if (!opts::AArch64PassOpt || !BC.HasRelocations)
return Error::success();
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
@@ -108,7 +113,7 @@ Error ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, nullptr,
- "ADRRelaxationPass");
+ "AArch64RelaxationPass");
if (PassFailed)
return createFatalBOLTError("");
diff --git a/bolt/lib/Passes/CMakeLists.txt b/bolt/lib/Passes/CMakeLists.txt
index d7519518f186f..3197e62faad21 100644
--- a/bolt/lib/Passes/CMakeLists.txt
+++ b/bolt/lib/Passes/CMakeLists.txt
@@ -1,5 +1,5 @@
add_llvm_library(LLVMBOLTPasses
- ADRRelaxationPass.cpp
+ AArch64RelaxationPass.cpp
Aligner.cpp
AllocCombiner.cpp
AsmDump.cpp
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index 4e062038a3e4c..8554683bc3cf8 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -564,13 +564,18 @@ void DataAggregator::imputeFallThroughs() {
// Skip fall-throughs in external code.
if (Trace.From == Trace::EXTERNAL)
continue;
- std::pair CurrentBranch(Trace.Branch, Trace.From);
+ if (std::pair CurrentBranch(Trace.Branch, Trace.From);
+ CurrentBranch != PrevBranch) {
+ // New group: reset aggregates.
+ AggregateCount = AggregateFallthroughSize = 0;
+ PrevBranch = CurrentBranch;
+ }
// BR_ONLY must be the last trace in the group
if (Trace.To == Trace::BR_ONLY) {
// If the group is not empty, use aggregate values, otherwise 0-length
// for unconditional jumps (call/ret/uncond branch) or 1-length for others
uint64_t InferredBytes =
- PrevBranch == CurrentBranch
+ AggregateFallthroughSize
? AggregateFallthroughSize / AggregateCount
: !checkUnconditionalControlTransfer(Trace.From);
Trace.To = Trace.From + InferredBytes;
@@ -578,16 +583,11 @@ void DataAggregator::imputeFallThroughs() {
<< " bytes)\n");
++InferredTraces;
} else {
- // Trace with a valid fall-through
- // New group: reset aggregates.
- if (CurrentBranch != PrevBranch)
- AggregateCount = AggregateFallthroughSize = 0;
// Only use valid fall-through lengths
if (Trace.To != Trace::EXTERNAL)
AggregateFallthroughSize += (Trace.To - Trace.From) * Info.TakenCount;
AggregateCount += Info.TakenCount;
}
- PrevBranch = CurrentBranch;
}
if (opts::Verbosity >= 1)
outs() << "BOLT-INFO: imputed " << InferredTraces << " traces\n";
diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp
index 782137e807662..1a0f6d75d63e8 100644
--- a/bolt/lib/Rewrite/BinaryPassManager.cpp
+++ b/bolt/lib/Rewrite/BinaryPassManager.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "bolt/Rewrite/BinaryPassManager.h"
-#include "bolt/Passes/ADRRelaxationPass.h"
+#include "bolt/Passes/AArch64RelaxationPass.h"
#include "bolt/Passes/Aligner.h"
#include "bolt/Passes/AllocCombiner.h"
#include "bolt/Passes/AsmDump.h"
@@ -129,10 +129,10 @@ static cl::opt PrintJTFootprintReduction(
cl::desc("print function after jt-footprint-reduction pass"), cl::Hidden,
cl::cat(BoltOptCategory));
-static cl::opt
- PrintAdrRelaxation("print-adr-relaxation",
- cl::desc("print functions after ADR Relaxation pass"),
- cl::Hidden, cl::cat(BoltOptCategory));
+static cl::opt PrintAArch64Relaxation(
+ "print-adr-ldr-relaxation",
+ cl::desc("print functions after ADR/LDR Relaxation pass"), cl::Hidden,
+ cl::cat(BoltOptCategory));
static cl::opt
PrintLongJmp("print-longjmp",
@@ -517,7 +517,7 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
if (BC.isAArch64()) {
Manager.registerPass(
- std::make_unique(PrintAdrRelaxation));
+ std::make_unique(PrintAArch64Relaxation));
// Tighten branches according to offset differences between branch and
// targets. No extra instructions after this pass, otherwise we may have
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 7769162d67eaf..57db6a436c5c6 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -142,6 +142,7 @@ static InstructionListType createIncMemory(MCPhysReg RegTo, MCPhysReg RegTmp) {
atomicAdd(Insts.back(), RegTo, RegTmp);
return Insts;
}
+
class AArch64MCPlusBuilder : public MCPlusBuilder {
public:
using MCPlusBuilder::MCPlusBuilder;
@@ -583,6 +584,14 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
return Inst.getOpcode() == AArch64::ADDXri;
}
+ bool isLDRWl(const MCInst &Inst) const override {
+ return Inst.getOpcode() == AArch64::LDRWl;
+ }
+
+ bool isLDRXl(const MCInst &Inst) const override {
+ return Inst.getOpcode() == AArch64::LDRXl;
+ }
+
MCPhysReg getADRReg(const MCInst &Inst) const {
assert((isADR(Inst) || isADRP(Inst)) && "Not an ADR instruction");
assert(MCPlus::getNumPrimeOperands(Inst) != 0 &&
@@ -602,6 +611,39 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
return materializeAddress(Target, Ctx, Reg, Addend);
}
+ InstructionListType createAdrpLdr(const MCInst &LDRInst,
+ MCContext *Ctx) const override {
+ assert((isLDRXl(LDRInst) || isLDRWl(LDRInst)) &&
+ "LDR (literal, 32 or 64-bit integer load) instruction expected");
+ assert(LDRInst.getOperand(0).isReg() &&
+ "unexpected operand in LDR instruction");
+ const MCPhysReg DataReg = LDRInst.getOperand(0).getReg();
+ const MCPhysReg AddrReg =
+ isLDRXl(LDRInst) ? DataReg
+ : (MCPhysReg)RegInfo->getMatchingSuperReg(
+ DataReg, AArch64::sub_32,
+ &RegInfo->getRegClass(AArch64::GPR64RegClassID));
+ const MCSymbol *Target = getTargetSymbol(LDRInst, 1);
+ assert(Target && "missing target symbol in LDR instruction");
+
+ InstructionListType Insts(2);
+ Insts[0].setOpcode(AArch64::ADRP);
+ Insts[0].clear();
+ Insts[0].addOperand(MCOperand::createReg(AddrReg));
+ Insts[0].addOperand(MCOperand::createImm(0));
+ setOperandToSymbolRef(Insts[0], /* OpNum */ 1, Target, 0, Ctx,
+ ELF::R_AARCH64_NONE);
+ Insts[1].setOpcode(isLDRXl(LDRInst) ? AArch64::LDRXui : AArch64::LDRWui);
+ Insts[1].clear();
+ Insts[1].addOperand(MCOperand::createReg(DataReg));
+ Insts[1].addOperand(MCOperand::createReg(AddrReg));
+ Insts[1].addOperand(MCOperand::createImm(0));
+ Insts[1].addOperand(MCOperand::createImm(0));
+ setOperandToSymbolRef(Insts[1], /* OpNum */ 2, Target, 0, Ctx,
+ ELF::R_AARCH64_ADD_ABS_LO12_NC);
+ return Insts;
+ }
+
bool isTB(const MCInst &Inst) const {
return (Inst.getOpcode() == AArch64::TBNZW ||
Inst.getOpcode() == AArch64::TBNZX ||
@@ -2762,7 +2804,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
BitVector WrittenRegs(RegInfo->getNumRegs());
const BitVector &SizeRegAliases = getAliases(SizeReg);
- for (auto InstIt = BB.begin(); InstIt != CallInst; ++InstIt) {
+ for (auto InstIt = CallInst; InstIt != BB.begin(); --InstIt) {
const MCInst &Inst = *InstIt;
WrittenRegs.reset();
getWrittenRegs(Inst, WrittenRegs);
diff --git a/bolt/test/AArch64/ldr-relaxation.s b/bolt/test/AArch64/ldr-relaxation.s
new file mode 100644
index 0000000000000..7632504a01635
--- /dev/null
+++ b/bolt/test/AArch64/ldr-relaxation.s
@@ -0,0 +1,122 @@
+## Check that LDR relaxation will fail since LDR is inside a non-simple
+## function and there is no NOP next to it.
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \
+# RUN: --defsym FAIL=1 %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.so -Wl,-q
+# RUN: not llvm-bolt %t.so -o %t.bolt 2>&1 | FileCheck %s --check-prefix=FAIL
+
+# FAIL: BOLT-ERROR: cannot relax LDR in non-simple function _start
+
+.ifdef FAIL
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ .cfi_startproc
+ br x2
+ ldr x0, _foo
+ ret
+ .cfi_endproc
+.size _start, .-_start
+.endif
+
+## Check that LDR relaxation is not needed since the reference is not far away.
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \
+# RUN: --defsym NOT_NEEDED=1 %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.so -Wl,-q
+# RUN: llvm-bolt %t.so -o %t.bolt
+# RUN: llvm-objdump -d %t.bolt | FileCheck %s --check-prefix=NOT_NEEDED
+
+# NOT_NEEDED: <_start>
+# NOT_NEEDED-NEXT: ldr
+
+.ifdef NOT_NEEDED
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ .cfi_startproc
+ ldr x0, _start
+ ret
+ .cfi_endproc
+.size _start, .-_start
+.endif
+
+## Check that LDR relaxation is done in a simple function, where NOP will
+## be inserted as needed.
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \
+# RUN: --defsym RELAX_SIMPLE=1 %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.so -Wl,-q
+# RUN: llvm-bolt %t.so -o %t.bolt
+# RUN: llvm-objdump -d %t.bolt | FileCheck %s --check-prefix=RELAX
+
+# RELAX: adrp
+# RELAX-NEXT: ldr
+
+.ifdef RELAX_SIMPLE
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ .cfi_startproc
+ ldr x0, _foo
+ ret
+ .cfi_endproc
+.size _start, .-_start
+.endif
+
+## Check that LDR relaxation is done in a non-simple function, where NOP
+## exists next to LDR.
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \
+# RUN: --defsym RELAX_NON_SIMPLE=1 %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.so -Wl,-q
+# RUN: llvm-bolt %t.so -o %t.bolt
+# RUN: llvm-objdump -d %t.bolt | FileCheck %s --check-prefix=RELAX
+
+.ifdef RELAX_NON_SIMPLE
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ .cfi_startproc
+ br x2
+ ldr x0, _foo
+ nop
+ ret
+ .cfi_endproc
+.size _start, .-_start
+.endif
+
+## Check LDR relaxation works on loading W (low 32-bit of X) registers.
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \
+# RUN: --defsym RELAX_SIMPLE_WREG=1 %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.so -Wl,-q
+# RUN: llvm-bolt %t.so -o %t.bolt
+# RUN: llvm-objdump -d %t.bolt | FileCheck %s --check-prefix=RELAXW
+
+# RELAXW: adrp x0
+# RELAXW-NEXT: ldr w0
+
+.ifdef RELAX_SIMPLE_WREG
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ .cfi_startproc
+ ldr w0, _foo
+ ret
+ .cfi_endproc
+.size _start, .-_start
+.endif
+
+ .section .text_cold
+ .global _foo
+ .align 3
+_foo:
+ .long 0x12345678
+.size _foo, .-_foo
diff --git a/bolt/test/X86/callcont-fallthru.s b/bolt/test/X86/callcont-fallthru.s
index 8c05491e7bca0..ef0bb55df1faf 100644
--- a/bolt/test/X86/callcont-fallthru.s
+++ b/bolt/test/X86/callcont-fallthru.s
@@ -15,6 +15,8 @@
# External return to a landing pad/entry point call continuation
# RUN: link_fdata %s %t %t.pa-eret PREAGG-ERET
# RUN-DISABLED: link_fdata %s %t %t.pa-plt PREAGG-PLT
+## Fall-through imputing test cases
+# RUN: link_fdata %s %t %t.pa-imp PREAGG-IMP
# RUN: llvm-strip --strip-unneeded %t -o %t.strip
# RUN: llvm-objcopy --remove-section=.eh_frame %t.strip %t.noeh
@@ -63,6 +65,11 @@
# RUN-DISABLED: --check-prefix=CHECK-PLT
# CHECK-PLT: traces mismatching disassembled function contents: 0
+## Check --impute-trace-fall-throughs accepting duplicate branch-only traces
+# RUN: perf2bolt %t --pa -p %t.pa-imp -o %t.pa-imp.fdata --impute-trace-fall-through
+# RUN: FileCheck %s --check-prefix=CHECK-IMP --input-file %t.pa-imp.fdata
+# CHECK-IMP: 0 [unknown] 0 1 main {{.*}} 0 3
+
.globl foo
.type foo, %function
foo:
@@ -102,6 +109,8 @@ Ltmp1:
Ltmp4:
cmpl $0x0, -0x14(%rbp)
+# PREAGG-IMP: B X:0 #Ltmp4_br# 1 0
+# PREAGG-IMP: B X:0 #Ltmp4_br# 2 0
Ltmp4_br:
je Ltmp0
diff --git a/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test b/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test
index 673e86bb1533a..a08e352d605fe 100644
--- a/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test
+++ b/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test
@@ -1,4 +1,4 @@
-# UNSUPPORTED: true
+# REQUIRES: system-linux
; RUN: rm -rf %t
; RUN: mkdir %t
; RUN: cd %t
@@ -8,7 +8,8 @@
; RUN: llvm-dwp -e main.exe -o main.exe.dwp
; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.exe.dwp | FileCheck -check-prefix=PRE-BOLT %s
; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.dwp | FileCheck -check-prefix=PRE-BOLT-DWP-TU-INDEX %s
-; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --write-dwp
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwp -e main.exe.bolt -o main.exe.bolt.dwp
; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.exe.bolt.dwp | FileCheck -check-prefix=BOLT %s
; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s
diff --git a/bolt/test/X86/unclaimed-pc-rel.s b/bolt/test/X86/unclaimed-pc-rel.s
new file mode 100644
index 0000000000000..5292cccba754d
--- /dev/null
+++ b/bolt/test/X86/unclaimed-pc-rel.s
@@ -0,0 +1,24 @@
+## Check that unclaimed PC-relative relocation from data to code is detected
+## and reported to the user.
+
+# REQUIRES: system-linux
+
+# RUN: %clang %cflags -no-pie %s -o %t.exe -Wl,-q -nostartfiles
+# RUN: not llvm-bolt %t.exe -o %t.bolt --strict 2>&1 | FileCheck %s
+
+# CHECK: BOLT-ERROR: 1 unclaimed PC-relative relocation(s) left in data
+
+ .text
+ .globl _start
+ .type _start, %function
+_start:
+ movl $42, %eax
+.L0:
+ ret
+ .size _start, .-_start
+
+## Force relocation mode.
+ .reloc 0, R_X86_64_NONE
+
+ .section .rodata
+ .long .L0-.
diff --git a/bolt/test/runtime/AArch64/inline-memcpy.s b/bolt/test/runtime/AArch64/inline-memcpy.s
index dc59a08b889a7..badff299603a0 100644
--- a/bolt/test/runtime/AArch64/inline-memcpy.s
+++ b/bolt/test/runtime/AArch64/inline-memcpy.s
@@ -7,7 +7,7 @@
# RUN: llvm-bolt %t.exe --inline-memcpy -o %t.bolt 2>&1 | FileCheck %s --check-prefix=CHECK-INLINE
# RUN: llvm-objdump -d %t.bolt | FileCheck %s --check-prefix=CHECK-ASM
-# Verify BOLT reports that it inlined memcpy calls (11 successful inlines out of 16 total calls)
+# Verify BOLT reports that it inlined memcpy calls (11 successful inlines out of 17 total calls)
# CHECK-INLINE: BOLT-INFO: inlined 11 memcpy() calls
# Each function should use optimal size-specific instructions and NO memcpy calls
@@ -84,6 +84,9 @@
# CHECK-ASM-LABEL: :
# CHECK-ASM: bl{{.*}}:
+# CHECK-ASM: bl{{.*}}:
# CHECK-ASM: bl{{.*}}`_
+for `Extra Clang Tools `_ project.
+.. contents::
+ :depth: 2
+ :local:
Active Maintainers
==================
diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 2e21a4c4fd1f9..611717a64b768 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -73,6 +73,7 @@
#include "SizeofExpressionCheck.h"
#include "SpuriouslyWakeUpFunctionsCheck.h"
#include "StandaloneEmptyCheck.h"
+#include "StdNamespaceModificationCheck.h"
#include "StringConstructorCheck.h"
#include "StringIntegerAssignmentCheck.h"
#include "StringLiteralWithEmbeddedNulCheck.h"
@@ -237,6 +238,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-spuriously-wake-up-functions");
CheckFactories.registerCheck(
"bugprone-standalone-empty");
+ CheckFactories.registerCheck(
+ "bugprone-std-namespace-modification");
CheckFactories.registerCheck(
"bugprone-string-constructor");
CheckFactories.registerCheck(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index 31a0e6906866a..6c96996458040 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangTidyBugproneModule STATIC
SmartPtrArrayMismatchCheck.cpp
SpuriouslyWakeUpFunctionsCheck.cpp
StandaloneEmptyCheck.cpp
+ StdNamespaceModificationCheck.cpp
StringConstructorCheck.cpp
StringIntegerAssignmentCheck.cpp
StringLiteralWithEmbeddedNulCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
similarity index 95%
rename from clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp
rename to clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
index 79fbc66b5f8a3..13e5c03d7c4d3 100644
--- a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "DontModifyStdNamespaceCheck.h"
+#include "StdNamespaceModificationCheck.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
@@ -36,9 +36,9 @@ AST_POLYMORPHIC_MATCHER_P(
} // namespace
-namespace clang::tidy::cert {
+namespace clang::tidy::bugprone {
-void DontModifyStdNamespaceCheck::registerMatchers(MatchFinder *Finder) {
+void StdNamespaceModificationCheck::registerMatchers(MatchFinder *Finder) {
auto HasStdParent =
hasDeclContext(namespaceDecl(hasAnyName("std", "posix"),
unless(hasParent(namespaceDecl())))
@@ -96,7 +96,7 @@ void DontModifyStdNamespaceCheck::registerMatchers(MatchFinder *Finder) {
.bind("decl"),
this);
}
-} // namespace clang::tidy::cert
+} // namespace clang::tidy::bugprone
static const NamespaceDecl *getTopLevelLexicalNamespaceDecl(const Decl *D) {
const NamespaceDecl *LastNS = nullptr;
@@ -108,7 +108,7 @@ static const NamespaceDecl *getTopLevelLexicalNamespaceDecl(const Decl *D) {
return LastNS;
}
-void clang::tidy::cert::DontModifyStdNamespaceCheck::check(
+void clang::tidy::bugprone::StdNamespaceModificationCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *D = Result.Nodes.getNodeAs("decl");
const auto *NS = Result.Nodes.getNodeAs("nmspc");
diff --git a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.h b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.h
similarity index 61%
rename from clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.h
rename to clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.h
index cfcd878644ddb..0f62dc3d9ab70 100644
--- a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.h
@@ -6,21 +6,21 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DONT_MODIFY_STD_NAMESPACE_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DONT_MODIFY_STD_NAMESPACE_H
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STDNAMESPACEMODIFICATIONCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STDNAMESPACEMODIFICATIONCHECK_H
#include "../ClangTidyCheck.h"
-namespace clang::tidy::cert {
+namespace clang::tidy::bugprone {
/// Modification of the std or posix namespace can result in undefined behavior.
/// This check warns for such modifications.
///
/// For the user-facing documentation see:
-/// https://clang.llvm.org/extra/clang-tidy/checks/cert/dcl58-cpp.html
-class DontModifyStdNamespaceCheck : public ClangTidyCheck {
+/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/std-namespace-modification.html
+class StdNamespaceModificationCheck : public ClangTidyCheck {
public:
- DontModifyStdNamespaceCheck(StringRef Name, ClangTidyContext *Context)
+ StdNamespaceModificationCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
@@ -29,6 +29,6 @@ class DontModifyStdNamespaceCheck : public ClangTidyCheck {
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
-} // namespace clang::tidy::cert
+} // namespace clang::tidy::bugprone
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DONT_MODIFY_STD_NAMESPACE_H
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STDNAMESPACEMODIFICATIONCHECK_H
diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
index d5179770008e5..15592d5c03c06 100644
--- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -19,6 +19,7 @@
#include "../bugprone/SignedCharMisuseCheck.h"
#include "../bugprone/SizeofExpressionCheck.h"
#include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h"
+#include "../bugprone/StdNamespaceModificationCheck.h"
#include "../bugprone/SuspiciousMemoryComparisonCheck.h"
#include "../bugprone/ThrowingStaticInitializationCheck.h"
#include "../bugprone/UncheckedStringToNumberConversionCheck.h"
@@ -36,7 +37,6 @@
#include "../performance/MoveConstructorInitCheck.h"
#include "../readability/EnumInitialValueCheck.h"
#include "../readability/UppercaseLiteralSuffixCheck.h"
-#include "DontModifyStdNamespaceCheck.h"
#include "FloatLoopCounter.h"
#include "LimitedRandomnessCheck.h"
#include "MutatingCopyCheck.h"
@@ -251,7 +251,8 @@ class CERTModule : public ClangTidyModule {
"cert-dcl51-cpp");
CheckFactories.registerCheck(
"cert-dcl54-cpp");
- CheckFactories.registerCheck("cert-dcl58-cpp");
+ CheckFactories.registerCheck(
+ "cert-dcl58-cpp");
CheckFactories.registerCheck(
"cert-dcl59-cpp");
// ERR
diff --git a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
index db3b2f5a08286..27cf392ce0bb1 100644
--- a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
@@ -5,7 +5,6 @@ set(LLVM_LINK_COMPONENTS
add_clang_library(clangTidyCERTModule STATIC
CERTTidyModule.cpp
- DontModifyStdNamespaceCheck.cpp
FloatLoopCounter.cpp
LimitedRandomnessCheck.cpp
MutatingCopyCheck.cpp
diff --git a/clang-tools-extra/clangd/refactor/tweaks/OverridePureVirtuals.cpp b/clang-tools-extra/clangd/refactor/tweaks/OverridePureVirtuals.cpp
index 16febeca70809..b557066d979f5 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/OverridePureVirtuals.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/OverridePureVirtuals.cpp
@@ -79,7 +79,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Type.h"
+#include "clang/AST/TypeBase.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
@@ -116,7 +116,8 @@ std::string removePureVirtualSyntax(const std::string &MethodDecl,
DeclString += Tk.text();
if (Tk.Kind != tok::l_paren && Next.Kind != tok::comma &&
- Next.Kind != tok::r_paren && Next.Kind != tok::l_paren)
+ Next.Kind != tok::r_paren && Next.Kind != tok::l_paren &&
+ Tk.Kind != tok::coloncolon && Next.Kind != tok::coloncolon)
DeclString += ' ';
}
// Trim the last whitespace.
diff --git a/clang-tools-extra/clangd/unittests/tweaks/OverridePureVirtualsTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/OverridePureVirtualsTests.cpp
index b7dcbee1650ec..72095ab2f5982 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/OverridePureVirtualsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/OverridePureVirtualsTests.cpp
@@ -715,6 +715,45 @@ class D : public B {
EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;
}
+TEST_F(OverridePureVirtualsTests, QualifiedNames) {
+ constexpr auto Before = R"cpp(
+namespace foo { struct S{}; namespace bar { struct S2{}; } }
+
+class B {
+public:
+ virtual foo::S foo(int var = 0) = 0;
+ virtual foo::bar::S2 bar(int var = 0) = 0;
+};
+
+class ^D : public B {};
+)cpp";
+
+ constexpr auto Expected = R"cpp(
+namespace foo { struct S{}; namespace bar { struct S2{}; } }
+
+class B {
+public:
+ virtual foo::S foo(int var = 0) = 0;
+ virtual foo::bar::S2 bar(int var = 0) = 0;
+};
+
+class D : public B {
+public:
+ foo::S foo(int var = 0) override {
+ // TODO: Implement this pure virtual method.
+ static_assert(false, "Method `foo` is not implemented.");
+ }
+
+ foo::bar::S2 bar(int var = 0) override {
+ // TODO: Implement this pure virtual method.
+ static_assert(false, "Method `bar` is not implemented.");
+ }
+};
+)cpp";
+ auto Applied = apply(Before);
+ EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/docs/Maintainers.rst b/clang-tools-extra/docs/Maintainers.rst
new file mode 100644
index 0000000000000..f78e9ecf279a6
--- /dev/null
+++ b/clang-tools-extra/docs/Maintainers.rst
@@ -0,0 +1 @@
+.. include:: ../Maintainers.rst
\ No newline at end of file
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 35a64395f04e9..88eb0ebff4501 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -244,6 +244,11 @@ New check aliases
`
keeping initial check as an alias to the new one.
+- Renamed :doc:`cert-dcl58-cpp ` to
+ :doc:`bugprone-std-namespace-modification
+ `
+ keeping initial check as an alias to the new one.
+
- Renamed :doc:`cert-env33-c ` to
:doc:`bugprone-command-processor
`
@@ -379,7 +384,8 @@ Changes in existing checks
` check to avoid false
positives when pointers is transferred to non-const references
and avoid false positives of function pointer and fix false
- positives on return of non-const pointer.
+ positives on return of non-const pointer and fix false positives on
+ pointer-to-member operator.
- Improved :doc:`misc-header-include-cycle
` check performance.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.rst
new file mode 100644
index 0000000000000..c6e5608280264
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.rst
@@ -0,0 +1,63 @@
+.. title:: clang-tidy - bugprone-std-namespace-modification
+
+bugprone-std-namespace-modification
+===================================
+
+Warns on modifications of the ``std`` or ``posix`` namespaces which can
+result in undefined behavior.
+
+The ``std`` (or ``posix``) namespace is allowed to be extended with (class or
+function) template specializations that depend on an user-defined type (a type
+that is not defined in the standard system headers).
+
+The check detects the following (user provided) declarations in namespace ``std`` or ``posix``:
+
+- Anything that is not a template specialization.
+- Explicit specializations of any standard library function template or class template, if it does not have any user-defined type as template argument.
+- Explicit specializations of any member function of a standard library class template.
+- Explicit specializations of any member function template of a standard library class or class template.
+- Explicit or partial specialization of any member class template of a standard library class or class template.
+
+Examples:
+
+.. code-block:: c++
+
+ namespace std {
+ int x; // warning: modification of 'std' namespace can result in undefined behavior [bugprone-dont-modify-std-namespace]
+ }
+
+ namespace posix::a { // warning: modification of 'posix' namespace can result in undefined behavior
+ }
+
+ template <>
+ struct ::std::hash { // warning: modification of 'std' namespace can result in undefined behavior
+ unsigned long operator()(const long &K) const {
+ return K;
+ }
+ };
+
+ struct MyData { long data; };
+
+ template <>
+ struct ::std::hash { // no warning: specialization with user-defined type
+ unsigned long operator()(const MyData &K) const {
+ return K.data;
+ }
+ };
+
+ namespace std {
+ template <>
+ void swap(bool &a, bool &b); // warning: modification of 'std' namespace can result in undefined behavior
+
+ template <>
+ bool less::operator()(MyData &&, MyData &&) const { // warning: modification of 'std' namespace can result in undefined behavior
+ return true;
+ }
+ }
+
+References
+----------
+
+This check corresponds to the CERT C++ Coding Standard rule
+`DCL58-CPP. Do not modify the standard namespaces
+`_.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/cert/dcl58-cpp.rst b/clang-tools-extra/docs/clang-tidy/checks/cert/dcl58-cpp.rst
index fbcc6281a8898..1b8c2c4f97dde 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/cert/dcl58-cpp.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/cert/dcl58-cpp.rst
@@ -3,57 +3,9 @@
cert-dcl58-cpp
==============
-Modification of the ``std`` or ``posix`` namespace can result in undefined
-behavior.
-This check warns for such modifications.
-The ``std`` (or ``posix``) namespace is allowed to be extended with (class or
-function) template specializations that depend on an user-defined type (a type
-that is not defined in the standard system headers).
-
-The check detects the following (user provided) declarations in namespace ``std`` or ``posix``:
-
-- Anything that is not a template specialization.
-- Explicit specializations of any standard library function template or class template, if it does not have any user-defined type as template argument.
-- Explicit specializations of any member function of a standard library class template.
-- Explicit specializations of any member function template of a standard library class or class template.
-- Explicit or partial specialization of any member class template of a standard library class or class template.
-
-Examples:
-
-.. code-block:: c++
-
- namespace std {
- int x; // warning: modification of 'std' namespace can result in undefined behavior [cert-dcl58-cpp]
- }
-
- namespace posix::a { // warning: modification of 'posix' namespace can result in undefined behavior
- }
-
- template <>
- struct ::std::hash { // warning: modification of 'std' namespace can result in undefined behavior
- unsigned long operator()(const long &K) const {
- return K;
- }
- };
-
- struct MyData { long data; };
-
- template <>
- struct ::std::hash { // no warning: specialization with user-defined type
- unsigned long operator()(const MyData &K) const {
- return K.data;
- }
- };
-
- namespace std {
- template <>
- void swap(bool &a, bool &b); // warning: modification of 'std' namespace can result in undefined behavior
-
- template <>
- bool less::operator()(MyData &&, MyData &&) const { // warning: modification of 'std' namespace can result in undefined behavior
- return true;
- }
- }
+The `cert-dcl58-cpp` is an aliaes, please see
+`bugprone-std-namespace-modification <../bugprone/std-namespace-modification.html>`_
+for more information.
This check corresponds to the CERT C++ Coding Standard rule
`DCL58-CPP. Do not modify the standard namespaces
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index e14ac715cfeeb..5094bcc90caf3 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -141,6 +141,7 @@ Clang-Tidy Checks
:doc:`bugprone-sizeof-expression `,
:doc:`bugprone-spuriously-wake-up-functions `,
:doc:`bugprone-standalone-empty `, "Yes"
+ :doc:`bugprone-std-namespace-modification `,
:doc:`bugprone-string-constructor `, "Yes"
:doc:`bugprone-string-integer-assignment `, "Yes"
:doc:`bugprone-string-literal-with-embedded-nul `,
@@ -175,7 +176,6 @@ Clang-Tidy Checks
:doc:`bugprone-unused-return-value `,
:doc:`bugprone-use-after-move `,
:doc:`bugprone-virtual-near-miss `, "Yes"
- :doc:`cert-dcl58-cpp `,
:doc:`cert-err33-c `,
:doc:`cert-err60-cpp `,
:doc:`cert-flp30-c `,
@@ -441,6 +441,7 @@ Check aliases
:doc:`cert-dcl50-cpp `, :doc:`modernize-avoid-variadic-functions `,
:doc:`cert-dcl51-cpp `, :doc:`bugprone-reserved-identifier `, "Yes"
:doc:`cert-dcl54-cpp `, :doc:`misc-new-delete-overloads `,
+ :doc:`cert-dcl58-cpp `, :doc:`bugprone-std-namespace-modification `,
:doc:`cert-dcl59-cpp `, :doc:`google-build-namespaces `,
:doc:`cert-env33-c `, :doc:`bugprone-command-processor `,
:doc:`cert-err09-cpp `, :doc:`misc-throw-by-value-catch-by-reference `,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvm/twine-local.rst b/clang-tools-extra/docs/clang-tidy/checks/llvm/twine-local.rst
index ec9ef1c60913c..6c994a48d83de 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/llvm/twine-local.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/llvm/twine-local.rst
@@ -14,3 +14,21 @@ should be generally avoided.
// becomes
static std::string Moo = (Twine("bark") + "bah").str();
+
+The ``Twine`` does not own the memory of its contents, so it is not
+recommended to use ``Twine`` created from temporary strings or string literals.
+
+.. code-block:: c++
+
+ static Twine getModuleIdentifier(StringRef moduleName) {
+ return moduleName + "_module";
+ }
+ void foo() {
+ Twine result = getModuleIdentifier(std::string{"abc"} + "def");
+ // temporary std::string is destroyed here, result is dangling
+ }
+
+After applying this fix-it hints, the code will use ``std::string`` instead of
+``Twine`` for local variables. However, ``Twine`` has lots of methods that
+are incompatible with ``std::string``, so the user may need to adjust the code
+manually after applying the fix-it hints.
diff --git a/clang-tools-extra/docs/index.rst b/clang-tools-extra/docs/index.rst
index 3f3a99d1b70c6..eba4a2cdbc558 100644
--- a/clang-tools-extra/docs/index.rst
+++ b/clang-tools-extra/docs/index.rst
@@ -22,6 +22,7 @@ Contents
pp-trace
clangd
clang-doc
+ Maintainers
Doxygen Documentation
diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h
index b6977cd9ce6c6..0870f60eaa39b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/system-header-simulation.h
@@ -59,7 +59,7 @@ struct X {};
} // namespace std
// Template specializations that are in a system-header file.
-// The purpose is to test cert-dcl58-cpp (no warnings here).
+// The purpose is to test bugprone-std-namespace-modification (no warnings here).
namespace std {
template <>
void swap(short &, short &){};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert/dcl58-cpp.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification.cpp
similarity index 97%
rename from clang-tools-extra/test/clang-tidy/checkers/cert/dcl58-cpp.cpp
rename to clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification.cpp
index 01964e7dc6c76..32bcbcaa21c0d 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cert/dcl58-cpp.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/std-namespace-modification.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy -std=c++17-or-later %s cert-dcl58-cpp %t -- -- -I %clang_tidy_headers
+// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-std-namespace-modification %t -- -- -I %clang_tidy_headers
#include "system-header-simulation.h"
@@ -15,7 +15,7 @@ namespace A {
}
namespace posix {
-// CHECK-MESSAGES: :[[@LINE+2]]:11: warning: modification of 'posix' namespace can result in undefined behavior [cert-dcl58-cpp]
+// CHECK-MESSAGES: :[[@LINE+2]]:11: warning: modification of 'posix' namespace can result in undefined behavior [bugprone-std-namespace-modification]
// CHECK-MESSAGES: :[[@LINE-2]]:11: note: 'posix' namespace opened here
namespace foo {
int foobar;
diff --git a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp
index ea9896e1cfde2..fccbd9b3740bd 100644
--- a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp
+++ b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp
@@ -39,7 +39,6 @@
// CHECK-NEXT: Reason: EnterFile
// CHECK-NEXT: FileType: C_User
// CHECK-NEXT: PrevFID: (invalid)
-// CHECK: - Callback: MacroDefined
// CHECK: - Callback: FileChanged
// CHECK-NEXT: Loc: ":1:1"
// CHECK-NEXT: Reason: ExitFile
diff --git a/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp b/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp
index 7c2a231101070..5bd38e0dade28 100644
--- a/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp
+++ b/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp
@@ -40,7 +40,6 @@ X
// CHECK-NEXT: MacroNameTok: __STDC_EMBED_EMPTY__
// CHECK-NEXT: MacroDirective: MD_Define
// CHECK: - Callback: MacroDefined
-// CHECK: - Callback: MacroDefined
// CHECK-NEXT: MacroNameTok: MACRO
// CHECK-NEXT: MacroDirective: MD_Define
// CHECK-NEXT: - Callback: MacroExpands
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index baa0bbb5ea631..b7c18c2b5c6cf 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2409,6 +2409,16 @@ those modes.
Use ``__has_feature(c_fixed_enum)`` to determine whether support for fixed
underlying types is available in C23 and later.
+Enumerations with no enumerators
+--------------------------------
+
+Clang provides support for Microsoft extensions to support enumerations with no enumerators.
+
+.. code-block:: c++
+
+ typedef enum empty { } A;
+
+
Interoperability with C++11 lambdas
-----------------------------------
diff --git a/clang/docs/LibClang.rst b/clang/docs/LibClang.rst
index e747022b9c173..6c62bcb5f8c29 100644
--- a/clang/docs/LibClang.rst
+++ b/clang/docs/LibClang.rst
@@ -38,6 +38,7 @@ Code example
.. code-block:: cpp
+ // main.cpp
#include
#include
@@ -57,6 +58,22 @@ Code example
CXCursor cursor = clang_getTranslationUnitCursor(unit); //Obtain a cursor at the root of the translation unit
}
+.. code-block:: cmake
+
+ # CMakeLists.txt
+ cmake_minimum_required(VERSION 3.20)
+ project(my_clang_tool VERSION 0.1.0)
+
+ # This will find the default system installation of Clang; if you want to
+ # use a different build of clang, pass -DClang_DIR=/foobar/lib/cmake/clang
+ # to the CMake configure command, where /foobar is the build directory where
+ # you built Clang.
+ find_package(Clang CONFIG REQUIRED)
+
+ add_executable(my_clang_tool main.cpp)
+ target_include_directories(my_clang_tool PRIVATE ${CLANG_INCLUDE_DIRS})
+ target_link_libraries(my_clang_tool PRIVATE libclang)
+
Visiting elements of an AST
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The elements of an AST can be recursively visited with pre-order traversal with ``clang_visitChildren``.
@@ -283,6 +300,7 @@ Complete example code
.. code-block:: cpp
+ // main.cpp
#include
#include
@@ -356,6 +374,21 @@ Complete example code
);
}
+.. code-block:: cmake
+
+ # CMakeLists.txt
+ cmake_minimum_required(VERSION 3.20)
+ project(my_clang_tool VERSION 0.1.0)
+
+ # This will find the default system installation of Clang; if you want to
+ # use a different build of clang, pass -DClang_DIR=/foobar/lib/cmake/clang
+ # to the CMake configure command, where /foobar is the build directory where
+ # you built Clang.
+ find_package(Clang CONFIG REQUIRED)
+
+ add_executable(my_clang_tool main.cpp)
+ target_include_directories(my_clang_tool PRIVATE ${CLANG_INCLUDE_DIRS})
+ target_link_libraries(my_clang_tool PRIVATE libclang)
.. _Index.h: https://github.com/llvm/llvm-project/blob/main/clang/include/clang-c/Index.h
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6959e61cac980..32f669f8d70d8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -209,6 +209,8 @@ C23 Feature Support
`WG14 N2710 `_.
- Fixed accepting as compatible unnamed tag types with the same fields within
the same translation unit but from different types.
+- ``-MG`` now silences the "file not found" errors with ``#embed`` when
+ scanning for dependencies and encountering an unknown file. #GH165632
Non-comprehensive list of changes in this release
-------------------------------------------------
@@ -355,7 +357,7 @@ Improvements to Clang's diagnostics
potential misaligned members get processed before they can get discarded.
(#GH144729)
-- Clang now emits dignostic with correct message in case of assigning to const reference captured in lambda. (#GH105647)
+- Clang now emits a diagnostic with the correct message in case of assigning to const reference captured in lambda. (#GH105647)
- Fixed false positive in ``-Wmissing-noreturn`` diagnostic when it was requiring the usage of
``[[noreturn]]`` on lambdas before C++23 (#GH154493).
@@ -395,6 +397,11 @@ Improvements to Clang's diagnostics
that were previously incorrectly accepted in case of other irrelevant
conditions are now consistently diagnosed, identical to C++ mode.
+- Fix false-positive unused label diagnostic when a label is used in a named break
+ or continue (#GH166013)
+- Clang now emits a diagnostic in case `vector_size` or `ext_vector_type`
+ attributes are used with a negative size (#GH165463).
+
Improvements to Clang's time-trace
----------------------------------
@@ -437,6 +444,7 @@ Bug Fixes in This Version
- Fixed a failed assertion with empty filename arguments in ``__has_embed``. (#GH159898)
- Fixed a failed assertion with empty filename in ``#embed`` directive. (#GH162951)
- Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)
+- Accept empty enumerations in MSVC-compatible C mode. (#GH114402)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -457,6 +465,7 @@ Bug Fixes to Attribute Support
- Fix a crash when the function name is empty in the `swift_name` attribute. (#GH157075)
- Fixes crashes or missing diagnostics with the `device_kernel` attribute. (#GH161905)
- Fix handling of parameter indexes when an attribute is applied to a C++23 explicit object member function.
+- Fixed several false positives and false negatives in function effect (`nonblocking`) analysis. (#GH166078) (#GH166101) (#GH166110)
Bug Fixes to C++ Support
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -471,7 +480,7 @@ Bug Fixes to C++ Support
casts that are guaranteed to fail (#GH137518).
- Fix bug rejecting partial specialization of variable templates with auto NTTPs (#GH118190).
- Fix a crash if errors "member of anonymous [...] redeclares" and
- "intializing multiple members of union" coincide (#GH149985).
+ "initializing multiple members of union" coincide (#GH149985).
- Fix a crash when using ``explicit(bool)`` in pre-C++11 language modes. (#GH152729)
- Fix the parsing of variadic member functions when the ellipis immediately follows a default argument.(#GH153445)
- Fixed a bug that caused ``this`` captured by value in a lambda with a dependent explicit object parameter to not be
@@ -501,6 +510,7 @@ Bug Fixes to C++ Support
nontrivial member when another member has an initializer. (#GH81774)
- Fixed a template depth issue when parsing lambdas inside a type constraint. (#GH162092)
- Diagnose unresolved overload sets in non-dependent compound requirements. (#GH51246) (#GH97753)
+- Fix a crash when extracting unavailable member type from alias in template deduction. (#GH165560)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/APNumericStorage.h b/clang/include/clang/AST/APNumericStorage.h
index e1948a552bf7e..04424086b98cf 100644
--- a/clang/include/clang/AST/APNumericStorage.h
+++ b/clang/include/clang/AST/APNumericStorage.h
@@ -41,9 +41,8 @@ class APNumericStorage {
llvm::APInt getIntValue() const {
unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
if (NumWords > 1)
- return llvm::APInt(BitWidth, NumWords, pVal);
- else
- return llvm::APInt(BitWidth, VAL);
+ return llvm::APInt(BitWidth, llvm::ArrayRef(pVal, NumWords));
+ return llvm::APInt(BitWidth, VAL);
}
void setIntValue(const ASTContext &C, const llvm::APInt &Val);
};
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 0d187eb49d6ca..064a342aa0684 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -173,7 +173,7 @@ class DataStreamBasicReader : public BasicReaderBase {
llvm::SmallVector data;
for (uint32_t i = 0; i != numWords; ++i)
data.push_back(asImpl().readUInt64());
- return llvm::APInt(bitWidth, numWords, &data[0]);
+ return llvm::APInt(bitWidth, data);
}
llvm::FixedPointSemantics readFixedPointSemantics() {
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
index 91ffbb169f947..eb532bc8be3a7 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
@@ -23,7 +23,11 @@
#include "clang/Analysis/Analyses/LifetimeSafety/Facts.h"
#include "clang/Analysis/Analyses/LifetimeSafety/LiveOrigins.h"
#include "clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h"
+#include "clang/Analysis/Analyses/LifetimeSafety/Origins.h"
#include "clang/Analysis/AnalysisDeclContext.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/raw_ostream.h"
+#include
namespace clang::lifetimes {
@@ -44,10 +48,6 @@ class LifetimeSafetyReporter {
Confidence Confidence) {}
};
-/// The main entry point for the analysis.
-void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
- LifetimeSafetyReporter *Reporter);
-
namespace internal {
/// An object to hold the factories for immutable collections, ensuring
/// that all created states share the same underlying memory management.
@@ -60,6 +60,7 @@ struct LifetimeFactory {
/// Running the lifetime safety analysis and querying its results. It
/// encapsulates the various dataflow analyses.
class LifetimeSafetyAnalysis {
+
public:
LifetimeSafetyAnalysis(AnalysisDeclContext &AC,
LifetimeSafetyReporter *Reporter);
@@ -82,6 +83,12 @@ class LifetimeSafetyAnalysis {
std::unique_ptr LoanPropagation;
};
} // namespace internal
+
+/// The main entry point for the analysis.
+std::unique_ptr
+runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
+ LifetimeSafetyReporter *Reporter);
+
} // namespace clang::lifetimes
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h
index ba138b078b379..26686a63e9204 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h
@@ -16,7 +16,10 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/TypeBase.h"
#include "clang/Analysis/Analyses/LifetimeSafety/Utils.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/raw_ostream.h"
namespace clang::lifetimes::internal {
@@ -76,6 +79,8 @@ class OriginManager {
void dump(OriginID OID, llvm::raw_ostream &OS) const;
+ const llvm::StringMap getMissingOrigins() const;
+
private:
OriginID getNextOriginID() { return NextOriginID++; }
@@ -85,6 +90,7 @@ class OriginManager {
llvm::SmallVector AllOrigins;
llvm::DenseMap DeclToOriginID;
llvm::DenseMap ExprToOriginID;
+ llvm::StringMap ExprTypeToMissingOriginCount;
};
} // namespace clang::lifetimes::internal
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 2b400b012d6ed..0275447e1090a 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5235,6 +5235,12 @@ def HLSLGetSpirvSpecConstant : LangBuiltin<"HLSL_LANG">, HLSLScalarTemplate {
let Prototype = "T(unsigned int, T)";
}
+def HLSLF16ToF32 : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_elementwise_f16tof32"];
+ let Attributes = [NoThrow, Const, CustomTypeChecking];
+ let Prototype = "void(...)";
+}
+
// Builtins for XRay.
def XRayCustomEvent : Builtin {
let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td
index 9e877b92eac68..4388c09423a21 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -1765,75 +1765,48 @@ let Features = "avx512vl", Attributes = [NoThrow, RequiredVectorWidth<256>] in {
def scattersiv8si : X86Builtin<"void(void *, unsigned char, _Vector<8, int>, _Vector<8, int>, _Constant int)">;
}
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
+let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
def vpermi2vard128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>)">;
-}
-
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
- def vpermi2vard256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">;
-}
-
-let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
- def vpermi2vard512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">;
-}
-
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
- def vpermi2varpd128 : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, long long int>, _Vector<2, double>)">;
-}
-
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
- def vpermi2varpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, long long int>, _Vector<4, double>)">;
-}
-
-let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
- def vpermi2varpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, long long int>, _Vector<8, double>)">;
-}
-
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
- def vpermi2varps128 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, int>, _Vector<4, float>)">;
-}
-
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
- def vpermi2varps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>, _Vector<8, float>)">;
-}
-
-let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
- def vpermi2varps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, int>, _Vector<16, float>)">;
-}
-
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
def vpermi2varq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>, _Vector<2, long long int>)">;
+ def vpermi2varps128 : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, int>, _Vector<4, float>)">;
+ def vpermi2varpd128 : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, long long int>, _Vector<2, double>)">;
}
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
+let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
+ def vpermi2vard256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>)">;
def vpermi2varq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Vector<4, long long int>)">;
+ def vpermi2varps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>, _Vector<8, float>)">;
+ def vpermi2varpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, long long int>, _Vector<4, double>)">;
}
-let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
+let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
+ def vpermi2vard512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">;
def vpermi2varq512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<8, long long int>, _Vector<8, long long int>)">;
+ def vpermi2varps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, int>, _Vector<16, float>)">;
+ def vpermi2varpd512 : X86Builtin<"_Vector<8, double>(_Vector<8, double>, _Vector<8, long long int>, _Vector<8, double>)">;
}
-let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
+let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
def vpermi2varqi128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Vector<16, char>)">;
}
-let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
+let Features = "avx512vbmi,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
def vpermi2varqi256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Vector<32, char>)">;
}
-let Features = "avx512vbmi", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
+let Features = "avx512vbmi", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
def vpermi2varqi512 : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>, _Vector<64, char>)">;
}
-let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
+let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
def vpermi2varhi128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>, _Vector<8, short>)">;
}
-let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
+let Features = "avx512vl,avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
def vpermi2varhi256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>, _Vector<16, short>)">;
}
-let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
+let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
def vpermi2varhi512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<32, short>, _Vector<32, short>)">;
}
diff --git a/clang/include/clang/Basic/DebugOptions.def b/clang/include/clang/Basic/DebugOptions.def
index a768b12fa4e0d..ea3636ffa1af1 100644
--- a/clang/include/clang/Basic/DebugOptions.def
+++ b/clang/include/clang/Basic/DebugOptions.def
@@ -46,6 +46,8 @@ ENUM_DEBUGOPT(EmitDwarfUnwind, EmitDwarfUnwindType, 2,
DEBUGOPT(NoDwarfDirectoryAsm , 1, 0, Benign) ///< Set when -fno-dwarf-directory-asm
///< is enabled.
+DEBUGOPT(Dwarf2CFIAsm, 1, 0, NotCompatible) ///< Set when -fdwarf2-cfi-asm is enabled.
+
DEBUGOPT(NoInlineLineTables, 1, 0, Benign) ///< Whether debug info should contain
///< inline line tables.
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 8aa3489a2a62b..1e0321de3f4b6 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1436,6 +1436,7 @@ def MicrosoftDrectveSection : DiagGroup<"microsoft-drectve-section">;
def MicrosoftInclude : DiagGroup<"microsoft-include">;
def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">;
def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">;
+def MicrosoftEmptyEnum : DiagGroup<"microsoft-empty-enum">;
def MicrosoftSealed : DiagGroup<"microsoft-sealed">;
def MicrosoftAbstract : DiagGroup<"microsoft-abstract">;
def MicrosoftUnqualifiedFriend : DiagGroup<"microsoft-unqualified-friend">;
@@ -1489,7 +1490,8 @@ def Microsoft : DiagGroup<"microsoft",
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
MicrosoftCommentPaste, MicrosoftEndOfFile,
MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined,
- MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>;
+ MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction,
+ MicrosoftEmptyEnum]>;
def ClangClPch : DiagGroup<"clang-cl-pch">;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index e5e071f43fa75..aa0ccb0c05101 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -116,6 +116,9 @@ def err_enumerator_unnamed_no_def : Error<
def ext_ms_c_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a Microsoft extension">,
InGroup;
+def ext_ms_c_empty_enum_type : Extension<
+ "empty enumeration types are a Microsoft extension">,
+ InGroup;
def ext_c23_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a C23 extension">,
InGroup;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4e369be0bbb92..fa509536bf021 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3510,6 +3510,8 @@ def err_init_method_bad_return_type : Error<
"init methods must return an object pointer type, not %0">;
def err_attribute_invalid_size : Error<
"vector size not an integral multiple of component size">;
+def err_attribute_vec_negative_size
+ : Error<"vector must have non-negative size">;
def err_attribute_zero_size : Error<"zero %0 size">;
def err_attribute_size_too_large : Error<"%0 size too large">;
def err_typecheck_sve_rvv_ambiguous : Error<
diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index ed967fd47dc83..6d9d074d78026 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -1286,16 +1286,7 @@ class SourceManager : public RefCountedBase {
/// If the location is an expansion record, walk through it until we find
/// the final location expanded.
FileIDAndOffset getDecomposedExpansionLoc(SourceLocation Loc) const {
- FileID FID = getFileID(Loc);
- auto *E = getSLocEntryOrNull(FID);
- if (!E)
- return std::make_pair(FileID(), 0);
-
- unsigned Offset = Loc.getOffset()-E->getOffset();
- if (Loc.isFileID())
- return std::make_pair(FID, Offset);
-
- return getDecomposedExpansionLocSlowCase(E);
+ return getDecomposedLoc(getExpansionLoc(Loc));
}
/// Decompose the specified location into a raw FileID + Offset pair.
@@ -1303,15 +1294,7 @@ class SourceManager : public RefCountedBase {
/// If the location is an expansion record, walk through it until we find
/// its spelling record.
FileIDAndOffset getDecomposedSpellingLoc(SourceLocation Loc) const {
- FileID FID = getFileID(Loc);
- auto *E = getSLocEntryOrNull(FID);
- if (!E)
- return std::make_pair(FileID(), 0);
-
- unsigned Offset = Loc.getOffset()-E->getOffset();
- if (Loc.isFileID())
- return std::make_pair(FID, Offset);
- return getDecomposedSpellingLocSlowCase(E, Offset);
+ return getDecomposedLoc(getSpellingLoc(Loc));
}
/// Returns the "included/expanded in" decomposed location of the given
@@ -1979,10 +1962,6 @@ class SourceManager : public RefCountedBase {
SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
SourceLocation getFileLocSlowCase(SourceLocation Loc) const;
- FileIDAndOffset
- getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const;
- FileIDAndOffset getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
- unsigned Offset) const;
void computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const;
void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
FileID FID,
diff --git a/clang/include/clang/Basic/riscv_sifive_vector.td b/clang/include/clang/Basic/riscv_sifive_vector.td
index 89e644a078682..0371279aafc08 100644
--- a/clang/include/clang/Basic/riscv_sifive_vector.td
+++ b/clang/include/clang/Basic/riscv_sifive_vector.td
@@ -121,6 +121,13 @@ multiclass RVVVQMACCQOQBuiltinSet> suffixes_prototypes> {
defm NAME : RVVOutOp1Op2BuiltinSet;
}
+multiclass RVVVFEXPBuiltinSet> suffixes_prototypes, string type_range> {
+ let UnMaskedPolicyScheme = HasPassthruOperand,
+ OverloadedName = NAME,
+ Log2LMUL = [-2, -1, 0, 1, 2, 3] in
+ defm NAME : RVVOutBuiltinSet;
+}
+
multiclass RVVVFNRCLIPBuiltinSet {
let Log2LMUL = [-3, -2, -1, 0, 1, 2],
Name = NAME,
@@ -145,6 +152,26 @@ let UnMaskedPolicyScheme = HasPolicyOperand in
defm sf_vqmaccsu_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>;
}
+let RequiredFeatures = ["xsfvfbfexp16e"] in {
+ defm sf_vfexp : RVVVFEXPBuiltinSet<[["v", "v", "vv"]], "y">;
+}
+
+let RequiredFeatures = ["xsfvfexp16e"] in {
+ defm sf_vfexp : RVVVFEXPBuiltinSet<[["v", "v", "vv"]], "x">;
+}
+
+let RequiredFeatures = ["xsfvfexp32e"] in {
+ defm sf_vfexp : RVVVFEXPBuiltinSet<[["v", "v", "vv"]], "f">;
+}
+
+let RequiredFeatures = ["xsfvfexpa"] in {
+ defm sf_vfexpa : RVVVFEXPBuiltinSet<[["v", "v", "vv"]], "xf">;
+}
+
+let RequiredFeatures = ["xsfvfexpa64e"] in {
+ defm sf_vfexpa : RVVVFEXPBuiltinSet<[["v", "v", "vv"]], "d">;
+}
+
let UnMaskedPolicyScheme = HasPolicyOperand in
let RequiredFeatures = ["xsfvfwmaccqqq"] in
defm sf_vfwmacc_4x4x4 : RVVVFWMACCBuiltinSet<[["", "Fw", "FwFwSvv"]]>;
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 2b361ed0982c6..6f9a69e697cc3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4171,6 +4171,16 @@ def CIR_ATanOp : CIR_UnaryFPToFPBuiltinOp<"atan", "ATanOp"> {
}];
}
+def CIR_CeilOp : CIR_UnaryFPToFPBuiltinOp<"ceil", "FCeilOp"> {
+ let summary = "Computes the ceiling of the specified value";
+ let description = [{
+ `cir.ceil` computes the ceiling of a given value and returns a result
+ of the same type.
+
+ Floating-point exceptions are ignored, and it does not set `errno`.
+ }];
+}
+
def CIR_CosOp : CIR_UnaryFPToFPBuiltinOp<"cos", "CosOp"> {
let summary = "Computes the floating-point cosine value";
let description = [{
@@ -4181,6 +4191,16 @@ def CIR_CosOp : CIR_UnaryFPToFPBuiltinOp<"cos", "CosOp"> {
}];
}
+def CIR_ExpOp : CIR_UnaryFPToFPBuiltinOp<"exp", "ExpOp"> {
+ let summary = "Computes the floating-point base-e exponential value";
+ let description = [{
+ `cir.exp` computes the exponential of a floating-point operand and returns
+ a result of the same type.
+
+ Floating-point exceptions are ignored, and it does not set `errno`.
+ }];
+}
+
def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> {
let summary = "Computes the floating-point absolute value";
let description = [{
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 48ef8be9fb782..6f099a7027a10 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -180,6 +180,8 @@ struct MissingFeatures {
static bool atomicSyncScopeID() { return false; }
static bool atomicTypes() { return false; }
static bool atomicUseLibCall() { return false; }
+ static bool atomicMicrosoftVolatile() { return false; }
+ static bool atomicOpenMP() { return false; }
// Global ctor handling
static bool globalCtorLexOrder() { return false; }
diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h b/clang/include/clang/CodeGen/ModuleBuilder.h
index f1b8229edd362..4298ba06c472e 100644
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -120,6 +120,23 @@ CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags,
llvm::LLVMContext &C,
CoverageSourceInfo *CoverageInfo = nullptr);
+namespace CodeGen {
+/// Demangle the artificial function name (\param FuncName) used to encode trap
+/// reasons used in debug info for traps (e.g. __builtin_verbose_trap). See
+/// `CGDebugInfo::CreateTrapFailureMessageFor`.
+///
+/// \param FuncName - The function name to demangle.
+///
+/// \return A std::optional. If demangling succeeds the optional will contain
+/// a pair of StringRefs where the first field is the trap category and the
+/// second is the trap message. These can both be empty. If demangling fails the
+/// optional will not contain a value. Note the returned StringRefs if non-empty
+/// point into the underlying storage for \param FuncName and thus have the same
+/// lifetime.
+std::optional>
+DemangleTrapReasonInDebugInfo(StringRef FuncName);
+} // namespace CodeGen
+
} // end namespace clang
#endif
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 20955ef1b852e..11e81e032d5fc 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -741,6 +741,7 @@ def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>,
"Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
"Flang will use the GCC installation with the largest version">;
def gcc_triple_EQ : Joined<["--"], "gcc-triple=">,
+ Visibility<[ClangOption, FlangOption]>,
HelpText<"Search for the GCC installation with the specified triple.">;
def CC : Flag<["-"], "CC">, Visibility<[ClangOption, CC1Option]>,
Group,
@@ -950,9 +951,9 @@ def Xarch__
the host system, which can be used to suppress incompatible GPU arguments.}]>,
MetaVarName<" ">;
def Xarch_host : Separate<["-"], "Xarch_host">, Flags<[NoXarchOption]>,
- HelpText<"Pass to the CUDA/HIP host compilation">, MetaVarName<"">;
+ HelpText<"Pass to host compilation in the offloading toolchain">, MetaVarName<"">;
def Xarch_device : Separate<["-"], "Xarch_device">, Flags<[NoXarchOption]>,
- HelpText<"Pass to the CUDA/HIP device compilation">, MetaVarName<"">;
+ HelpText<"Pass to device compilation in the offloading toolchain">, MetaVarName<"">;
def Xassembler : Separate<["-"], "Xassembler">,
HelpText<"Pass to the assembler">, MetaVarName<"">,
Group;
@@ -2154,8 +2155,12 @@ defm dollars_in_identifiers : BoolFOption<"dollars-in-identifiers",
PosFlag,
NegFlag,
BothFlags<[], [ClangOption, CC1Option], " '$' in identifiers">>;
-def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group;
-def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group;
+
+defm dwarf2_cfi_asm
+ : BoolFOption<"dwarf2-cfi-asm", CodeGenOpts<"Dwarf2CFIAsm">, DefaultFalse,
+ PosFlag,
+ NegFlag>;
+
defm dwarf_directory_asm : BoolFOption<"dwarf-directory-asm",
CodeGenOpts<"NoDwarfDirectoryAsm">, DefaultFalse,
NegFlag,
diff --git a/clang/include/clang/Sema/AnalysisBasedWarnings.h b/clang/include/clang/Sema/AnalysisBasedWarnings.h
index 4103c3f006a8f..604039ef61cb7 100644
--- a/clang/include/clang/Sema/AnalysisBasedWarnings.h
+++ b/clang/include/clang/Sema/AnalysisBasedWarnings.h
@@ -14,7 +14,10 @@
#define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H
#include "clang/AST/Decl.h"
+#include "clang/Analysis/Analyses/LifetimeSafety/Facts.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
#include
namespace clang {
@@ -95,6 +98,9 @@ class AnalysisBasedWarnings {
/// a single function.
unsigned MaxUninitAnalysisBlockVisitsPerFunction;
+ /// Map from expressions missing origin in OriginManager to their counts.
+ llvm::StringMap MissingOriginCount;
+
/// @}
public:
@@ -116,6 +122,9 @@ class AnalysisBasedWarnings {
Policy &getPolicyOverrides() { return PolicyOverrides; }
void PrintStats() const;
+
+ void FindMissingOrigins(AnalysisDeclContext &AC,
+ clang::lifetimes::internal::FactManager &FactMgr);
};
} // namespace sema
diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp
index fd0903f2e652c..638028f84ff24 100644
--- a/clang/lib/AST/ByteCode/Disasm.cpp
+++ b/clang/lib/AST/ByteCode/Disasm.cpp
@@ -436,8 +436,28 @@ LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned Offset,
FO += ElemDesc->getAllocSize();
}
+ } else if (isPrimitiveArray()) {
+ OS.indent(Spaces) << "Elements: " << getNumElems() << '\n';
+ OS.indent(Spaces) << "Element type: " << primTypeToString(getPrimType())
+ << '\n';
+ unsigned FO = Offset + sizeof(InitMapPtr);
+ for (unsigned I = 0; I != getNumElems(); ++I) {
+ OS.indent(Spaces) << "Element " << I << " offset: " << FO << '\n';
+ FO += getElemSize();
+ }
} else if (isRecord()) {
ElemRecord->dump(OS, Indent + 1, Offset);
+ unsigned I = 0;
+ for (const Record::Field &F : ElemRecord->fields()) {
+ OS.indent(Spaces) << "- Field " << I << ": ";
+ {
+ ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_RED, true});
+ OS << F.Decl->getName();
+ }
+ OS << ". Offset " << (Offset + F.Offset) << "\n";
+ F.Desc->dumpFull(Offset + F.Offset, Indent + 1);
+ ++I;
+ }
} else if (isPrimitive()) {
} else {
}
diff --git a/clang/lib/AST/ByteCode/Floating.h b/clang/lib/AST/ByteCode/Floating.h
index 659892e720abf..cc918dc12deb6 100644
--- a/clang/lib/AST/ByteCode/Floating.h
+++ b/clang/lib/AST/ByteCode/Floating.h
@@ -45,7 +45,8 @@ class Floating final {
if (singleWord())
return APFloat(getSemantics(), APInt(BitWidth, Val));
unsigned NumWords = numWords();
- return APFloat(getSemantics(), APInt(BitWidth, NumWords, Memory));
+ return APFloat(getSemantics(),
+ APInt(BitWidth, llvm::ArrayRef(Memory, NumWords)));
}
public:
diff --git a/clang/lib/AST/ByteCode/IntegralAP.h b/clang/lib/AST/ByteCode/IntegralAP.h
index 6683db941c736..b11e6eea28e3f 100644
--- a/clang/lib/AST/ByteCode/IntegralAP.h
+++ b/clang/lib/AST/ByteCode/IntegralAP.h
@@ -63,7 +63,7 @@ template class IntegralAP final {
if (singleWord())
return APInt(BitWidth, Val, Signed);
unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
- return llvm::APInt(BitWidth, NumWords, Memory);
+ return llvm::APInt(BitWidth, llvm::ArrayRef(Memory, NumWords));
}
public:
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 8b57b963c538f..9991e365addb8 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3415,18 +3415,46 @@ static bool interp__builtin_ia32_shuffle_generic(
GetSourceIndex) {
assert(Call->getNumArgs() == 3);
- unsigned ShuffleMask = popToAPSInt(S, Call->getArg(2)).getZExtValue();
+
+ unsigned ShuffleMask = 0;
+ Pointer A, MaskVector, B;
+
+ QualType Arg2Type = Call->getArg(2)->getType();
+ bool IsVectorMask = false;
+ if (Arg2Type->isVectorType()) {
+ IsVectorMask = true;
+ B = S.Stk.pop();
+ MaskVector = S.Stk.pop();
+ A = S.Stk.pop();
+ } else if (Arg2Type->isIntegerType()) {
+ ShuffleMask = popToAPSInt(S, Call->getArg(2)).getZExtValue();
+ B = S.Stk.pop();
+ A = S.Stk.pop();
+ } else {
+ return false;
+ }
QualType Arg0Type = Call->getArg(0)->getType();
const auto *VecT = Arg0Type->castAs();
PrimType ElemT = *S.getContext().classify(VecT->getElementType());
unsigned NumElems = VecT->getNumElements();
- const Pointer &B = S.Stk.pop();
- const Pointer &A = S.Stk.pop();
const Pointer &Dst = S.Stk.peek();
+ PrimType MaskElemT = PT_Uint32;
+ if (IsVectorMask) {
+ QualType Arg1Type = Call->getArg(1)->getType();
+ const auto *MaskVecT = Arg1Type->castAs();
+ QualType MaskElemType = MaskVecT->getElementType();
+ MaskElemT = *S.getContext().classify(MaskElemType);
+ }
+
for (unsigned DstIdx = 0; DstIdx != NumElems; ++DstIdx) {
+ if (IsVectorMask) {
+ INT_TYPE_SWITCH(MaskElemT, {
+ ShuffleMask = static_cast(MaskVector.elem(DstIdx));
+ });
+ }
auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
if (SrcIdx < 0) {
@@ -4434,6 +4462,60 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
return std::pair{0, static_cast(DstIdx)};
}
});
+ case X86::BI__builtin_ia32_vpermi2varq128:
+ case X86::BI__builtin_ia32_vpermi2varpd128:
+ return interp__builtin_ia32_shuffle_generic(
+ S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x1;
+ unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ });
+ case X86::BI__builtin_ia32_vpermi2vard128:
+ case X86::BI__builtin_ia32_vpermi2varps128:
+ case X86::BI__builtin_ia32_vpermi2varq256:
+ case X86::BI__builtin_ia32_vpermi2varpd256:
+ return interp__builtin_ia32_shuffle_generic(
+ S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x3;
+ unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ });
+ case X86::BI__builtin_ia32_vpermi2varhi128:
+ case X86::BI__builtin_ia32_vpermi2vard256:
+ case X86::BI__builtin_ia32_vpermi2varps256:
+ case X86::BI__builtin_ia32_vpermi2varq512:
+ case X86::BI__builtin_ia32_vpermi2varpd512:
+ return interp__builtin_ia32_shuffle_generic(
+ S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x7;
+ unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ });
+ case X86::BI__builtin_ia32_vpermi2varqi128:
+ case X86::BI__builtin_ia32_vpermi2varhi256:
+ case X86::BI__builtin_ia32_vpermi2vard512:
+ case X86::BI__builtin_ia32_vpermi2varps512:
+ return interp__builtin_ia32_shuffle_generic(
+ S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0xF;
+ unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ });
+ case X86::BI__builtin_ia32_vpermi2varqi256:
+ case X86::BI__builtin_ia32_vpermi2varhi512:
+ return interp__builtin_ia32_shuffle_generic(
+ S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x1F;
+ unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ });
+ case X86::BI__builtin_ia32_vpermi2varqi512:
+ return interp__builtin_ia32_shuffle_generic(
+ S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x3F;
+ unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ });
case X86::BI__builtin_ia32_pshufb128:
case X86::BI__builtin_ia32_pshufb256:
case X86::BI__builtin_ia32_pshufb512:
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index e0b2852f0e906..2425373ab2ef8 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -218,21 +218,42 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init) {
return std::nullopt;
Global *NewGlobal = Globals[*Idx];
+ // Note that this loop has one iteration where Redecl == VD.
for (const Decl *Redecl : VD->redecls()) {
- unsigned &PIdx = GlobalIndices[Redecl];
+
+ // If this redecl was registered as a dummy variable, it is now a proper
+ // global variable and points to the block we just created.
+ if (auto DummyIt = DummyVariables.find(Redecl);
+ DummyIt != DummyVariables.end()) {
+ assert(!Globals[DummyIt->second]->block()->hasPointers());
+ Globals[DummyIt->second] = NewGlobal;
+ DummyVariables.erase(DummyIt);
+ }
+ // If the redeclaration hasn't been registered yet at all, we just set its
+ // global index to Idx. If it has been registered yet, it might have
+ // pointers pointing to it and we need to transfer those pointers to the new
+ // block.
+ auto [Iter, Inserted] = GlobalIndices.try_emplace(Redecl);
+ if (Inserted) {
+ GlobalIndices[Redecl] = *Idx;
+ continue;
+ }
+
if (Redecl != VD) {
- if (Block *RedeclBlock = Globals[PIdx]->block();
+ if (Block *RedeclBlock = Globals[Iter->second]->block();
RedeclBlock->isExtern()) {
- Globals[PIdx] = NewGlobal;
+
// All pointers pointing to the previous extern decl now point to the
// new decl.
// A previous iteration might've already fixed up the pointers for this
// global.
if (RedeclBlock != NewGlobal->block())
RedeclBlock->movePointersTo(NewGlobal->block());
+
+ Globals[Iter->second] = NewGlobal;
}
}
- PIdx = *Idx;
+ Iter->second = *Idx;
}
return *Idx;
diff --git a/clang/lib/AST/ByteCode/Program.h b/clang/lib/AST/ByteCode/Program.h
index 28fcc97f5339d..cc9127dc77860 100644
--- a/clang/lib/AST/ByteCode/Program.h
+++ b/clang/lib/AST/ByteCode/Program.h
@@ -205,7 +205,6 @@ class Program final {
const Block *block() const { return &B; }
private:
- /// Required metadata - does not actually track pointers.
Block B;
};
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 97eeba8b9d6cc..8fab6efafb983 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11628,21 +11628,38 @@ static bool evalShuffleGeneric(
if (!VT)
return false;
- APSInt MaskImm;
- if (!EvaluateInteger(Call->getArg(2), MaskImm, Info))
- return false;
- unsigned ShuffleMask = static_cast(MaskImm.getZExtValue());
+ unsigned ShuffleMask = 0;
+ APValue A, MaskVector, B;
+ bool IsVectorMask = false;
- APValue A, B;
- if (!EvaluateAsRValue(Info, Call->getArg(0), A) ||
- !EvaluateAsRValue(Info, Call->getArg(1), B))
+ QualType Arg2Type = Call->getArg(2)->getType();
+ if (Arg2Type->isVectorType()) {
+ IsVectorMask = true;
+ if (!EvaluateAsRValue(Info, Call->getArg(0), A) ||
+ !EvaluateAsRValue(Info, Call->getArg(1), MaskVector) ||
+ !EvaluateAsRValue(Info, Call->getArg(2), B))
+ return false;
+ } else if (Arg2Type->isIntegerType()) {
+ APSInt MaskImm;
+ if (!EvaluateInteger(Call->getArg(2), MaskImm, Info))
+ return false;
+ ShuffleMask = static_cast(MaskImm.getZExtValue());
+ if (!EvaluateAsRValue(Info, Call->getArg(0), A) ||
+ !EvaluateAsRValue(Info, Call->getArg(1), B))
+ return false;
+ } else {
return false;
+ }
unsigned NumElts = VT->getNumElements();
- SmallVector ResultElements;
+ SmallVector ResultElements;
ResultElements.reserve(NumElts);
for (unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
+ if (IsVectorMask) {
+ ShuffleMask = static_cast(
+ MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
+ }
auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
if (SrcIdx < 0) {
@@ -13080,6 +13097,84 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
+ case X86::BI__builtin_ia32_vpermi2varq128:
+ case X86::BI__builtin_ia32_vpermi2varpd128: {
+ APValue R;
+ if (!evalShuffleGeneric(Info, E, R,
+ [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x1;
+ unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ }))
+ return false;
+ return Success(R, E);
+ }
+ case X86::BI__builtin_ia32_vpermi2vard128:
+ case X86::BI__builtin_ia32_vpermi2varps128:
+ case X86::BI__builtin_ia32_vpermi2varq256:
+ case X86::BI__builtin_ia32_vpermi2varpd256: {
+ APValue R;
+ if (!evalShuffleGeneric(Info, E, R,
+ [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x3;
+ unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ }))
+ return false;
+ return Success(R, E);
+ }
+ case X86::BI__builtin_ia32_vpermi2varhi128:
+ case X86::BI__builtin_ia32_vpermi2vard256:
+ case X86::BI__builtin_ia32_vpermi2varps256:
+ case X86::BI__builtin_ia32_vpermi2varq512:
+ case X86::BI__builtin_ia32_vpermi2varpd512: {
+ APValue R;
+ if (!evalShuffleGeneric(Info, E, R,
+ [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x7;
+ unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ }))
+ return false;
+ return Success(R, E);
+ }
+ case X86::BI__builtin_ia32_vpermi2varqi128:
+ case X86::BI__builtin_ia32_vpermi2varhi256:
+ case X86::BI__builtin_ia32_vpermi2vard512:
+ case X86::BI__builtin_ia32_vpermi2varps512: {
+ APValue R;
+ if (!evalShuffleGeneric(Info, E, R,
+ [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0xF;
+ unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ }))
+ return false;
+ return Success(R, E);
+ }
+ case X86::BI__builtin_ia32_vpermi2varqi256:
+ case X86::BI__builtin_ia32_vpermi2varhi512: {
+ APValue R;
+ if (!evalShuffleGeneric(Info, E, R,
+ [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x1F;
+ unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ }))
+ return false;
+ return Success(R, E);
+ }
+ case X86::BI__builtin_ia32_vpermi2varqi512: {
+ APValue R;
+ if (!evalShuffleGeneric(Info, E, R,
+ [](unsigned DstIdx, unsigned ShuffleMask) {
+ int Offset = ShuffleMask & 0x3F;
+ unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
+ return std::pair{SrcIdx, Offset};
+ }))
+ return false;
+ return Success(R, E);
+ }
}
}
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index 75b17c545bb78..54c30c05c3e19 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -746,11 +746,14 @@ ExprMutationAnalyzer::Analyzer::findPointeeMemberMutation(const Expr *Exp) {
Stm, Context));
if (MemberCallExpr)
return MemberCallExpr;
- const auto Matches =
- match(stmt(forEachDescendant(
- memberExpr(hasObjectExpression(canResolveToExprPointee(Exp)))
- .bind(NodeID::value))),
- Stm, Context);
+ const auto Matches = match(
+ stmt(forEachDescendant(
+ expr(anyOf(memberExpr(
+ hasObjectExpression(canResolveToExprPointee(Exp))),
+ binaryOperator(hasOperatorName("->*"),
+ hasLHS(canResolveToExprPointee(Exp)))))
+ .bind(NodeID::value))),
+ Stm, Context);
return findExprMutation(Matches);
}
diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
index 00c7ed90503e7..d183ce976f946 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
@@ -23,9 +23,11 @@
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeProfiler.h"
+#include "llvm/Support/raw_ostream.h"
#include
namespace clang::lifetimes {
@@ -69,9 +71,12 @@ void LifetimeSafetyAnalysis::run() {
}
} // namespace internal
-void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
- LifetimeSafetyReporter *Reporter) {
- internal::LifetimeSafetyAnalysis Analysis(AC, Reporter);
- Analysis.run();
+std::unique_ptr
+runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
+ LifetimeSafetyReporter *Reporter) {
+ std::unique_ptr Analysis =
+ std::make_unique(AC, Reporter);
+ Analysis->run();
+ return Analysis;
}
} // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety/Origins.cpp b/clang/lib/Analysis/LifetimeSafety/Origins.cpp
index ea51a75324e06..b8f705e3377c2 100644
--- a/clang/lib/Analysis/LifetimeSafety/Origins.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Origins.cpp
@@ -7,6 +7,9 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Analyses/LifetimeSafety/Origins.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/TypeBase.h"
+#include "llvm/ADT/StringMap.h"
namespace clang::lifetimes::internal {
@@ -22,6 +25,10 @@ void OriginManager::dump(OriginID OID, llvm::raw_ostream &OS) const {
OS << ")";
}
+const llvm::StringMap OriginManager::getMissingOrigins() const {
+ return ExprTypeToMissingOriginCount;
+}
+
Origin &OriginManager::addOrigin(OriginID ID, const clang::ValueDecl &D) {
AllOrigins.emplace_back(ID, &D);
return AllOrigins.back();
@@ -37,6 +44,18 @@ OriginID OriginManager::get(const Expr &E) {
auto It = ExprToOriginID.find(&E);
if (It != ExprToOriginID.end())
return It->second;
+
+ // if the expression has no specific origin, increment the missing origin
+ // counter.
+ // const QualType ExprType = E.getType();
+ std::string ExprStr(E.getStmtClassName());
+ ExprStr = ExprStr + "<" + E.getType().getAsString() + ">";
+ auto CountIt = ExprTypeToMissingOriginCount.find(ExprStr);
+ if (CountIt == ExprTypeToMissingOriginCount.end()) {
+ ExprTypeToMissingOriginCount[ExprStr] = 1;
+ } else {
+ CountIt->second++;
+ }
// If the expression itself has no specific origin, and it's a reference
// to a declaration, its origin is that of the declaration it refers to.
// For pointer types, where we don't pre-emptively create an origin for the
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index 938c6485125ee..7dc81c50f87a2 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -907,58 +907,27 @@ getExpansionLocSlowCase(SourceLocation Loc) const {
SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
do {
- FileIDAndOffset LocInfo = getDecomposedLoc(Loc);
- Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc();
- Loc = Loc.getLocWithOffset(LocInfo.second);
+ const SLocEntry &Entry = getSLocEntry(getFileID(Loc));
+ Loc = Entry.getExpansion().getSpellingLoc().getLocWithOffset(
+ Loc.getOffset() - Entry.getOffset());
} while (!Loc.isFileID());
return Loc;
}
SourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const {
do {
- if (isMacroArgExpansion(Loc))
- Loc = getImmediateSpellingLoc(Loc);
- else
- Loc = getImmediateExpansionRange(Loc).getBegin();
+ const SLocEntry &Entry = getSLocEntry(getFileID(Loc));
+ const ExpansionInfo &ExpInfo = Entry.getExpansion();
+ if (ExpInfo.isMacroArgExpansion()) {
+ Loc = ExpInfo.getSpellingLoc().getLocWithOffset(Loc.getOffset() -
+ Entry.getOffset());
+ } else {
+ Loc = ExpInfo.getExpansionLocStart();
+ }
} while (!Loc.isFileID());
return Loc;
}
-FileIDAndOffset SourceManager::getDecomposedExpansionLocSlowCase(
- const SrcMgr::SLocEntry *E) const {
- // If this is an expansion record, walk through all the expansion points.
- FileID FID;
- SourceLocation Loc;
- unsigned Offset;
- do {
- Loc = E->getExpansion().getExpansionLocStart();
-
- FID = getFileID(Loc);
- E = &getSLocEntry(FID);
- Offset = Loc.getOffset()-E->getOffset();
- } while (!Loc.isFileID());
-
- return std::make_pair(FID, Offset);
-}
-
-FileIDAndOffset
-SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
- unsigned Offset) const {
- // If this is an expansion record, walk through all the expansion points.
- FileID FID;
- SourceLocation Loc;
- do {
- Loc = E->getExpansion().getSpellingLoc();
- Loc = Loc.getLocWithOffset(Offset);
-
- FID = getFileID(Loc);
- E = &getSLocEntry(FID);
- Offset = Loc.getOffset()-E->getOffset();
- } while (!Loc.isFileID());
-
- return std::make_pair(FID, Offset);
-}
-
/// getImmediateSpellingLoc - Given a SourceLocation object, return the
/// spelling location referenced by the ID. This is the first level down
/// towards the place where the characters that make up the lexed token can be
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 7db6e283ec0a5..cd4c1f0e5b769 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -27,6 +27,7 @@ class AtomicInfo {
CharUnits atomicAlign;
CharUnits valueAlign;
TypeEvaluationKind evaluationKind = cir::TEK_Scalar;
+ bool useLibCall = true;
LValue lvalue;
mlir::Location loc;
@@ -62,8 +63,8 @@ class AtomicInfo {
assert(!cir::MissingFeatures::atomicInfo());
cgf.cgm.errorNYI(loc, "AtomicInfo: non-simple lvalue");
}
-
- assert(!cir::MissingFeatures::atomicUseLibCall());
+ useLibCall = !ctx.getTargetInfo().hasBuiltinAtomic(
+ atomicSizeInBits, ctx.toBits(lvalue.getAlignment()));
}
QualType getValueType() const { return valueTy; }
@@ -75,6 +76,8 @@ class AtomicInfo {
assert(!cir::MissingFeatures::atomicInfoGetAtomicPointer());
return nullptr;
}
+ bool shouldUseLibCall() const { return useLibCall; }
+ const LValue &getAtomicLValue() const { return lvalue; }
Address getAtomicAddress() const {
mlir::Type elemTy;
if (lvalue.isSimple()) {
@@ -96,6 +99,8 @@ class AtomicInfo {
bool emitMemSetZeroIfNecessary() const;
+ mlir::Value getScalarRValValueOrNull(RValue rvalue) const;
+
/// Cast the given pointer to an integer pointer suitable for atomic
/// operations on the source.
Address castToAtomicIntPointer(Address addr) const;
@@ -105,6 +110,9 @@ class AtomicInfo {
/// copy the value across.
Address convertToAtomicIntPointer(Address addr) const;
+ /// Converts a rvalue to integer value.
+ mlir::Value convertRValueToInt(RValue rvalue, bool cmpxchg = false) const;
+
/// Copy an atomic r-value into atomic-layout memory.
void emitCopyIntoMemory(RValue rvalue) const;
@@ -195,6 +203,12 @@ Address AtomicInfo::createTempAlloca() const {
return tempAlloca;
}
+mlir::Value AtomicInfo::getScalarRValValueOrNull(RValue rvalue) const {
+ if (rvalue.isScalar() && (!hasPadding() || !lvalue.isSimple()))
+ return rvalue.getValue();
+ return nullptr;
+}
+
Address AtomicInfo::castToAtomicIntPointer(Address addr) const {
auto intTy = mlir::dyn_cast(addr.getElementType());
// Don't bother with int casts if the integer size is the same.
@@ -211,10 +225,38 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
return false;
cgf.cgm.errorNYI(loc,
- "AtomicInfo::emitMemSetZeroIfNecessary: emit memset zero");
+ "AtomicInfo::emitMemSetZeroIfNecaessary: emit memset zero");
return false;
}
+/// Return true if \param valueTy is a type that should be casted to integer
+/// around the atomic memory operation. If \param cmpxchg is true, then the
+/// cast of a floating point type is made as that instruction can not have
+/// floating point operands. TODO: Allow compare-and-exchange and FP - see
+/// comment in CIRGenAtomicExpandPass.cpp.
+static bool shouldCastToInt(mlir::Type valueTy, bool cmpxchg) {
+ if (cir::isAnyFloatingPointType(valueTy))
+ return isa(valueTy) || cmpxchg;
+ return !isa(valueTy) && !isa(valueTy);
+}
+
+mlir::Value AtomicInfo::convertRValueToInt(RValue rvalue, bool cmpxchg) const {
+ // If we've got a scalar value of the right size, try to avoid going
+ // through memory. Floats get casted if needed by AtomicExpandPass.
+ if (mlir::Value value = getScalarRValValueOrNull(rvalue)) {
+ if (!shouldCastToInt(value.getType(), cmpxchg))
+ return cgf.emitToMemory(value, valueTy);
+
+ cgf.cgm.errorNYI(
+ loc, "AtomicInfo::convertRValueToInt: cast scalar rvalue to int");
+ return nullptr;
+ }
+
+ cgf.cgm.errorNYI(
+ loc, "AtomicInfo::convertRValueToInt: cast non-scalar rvalue to int");
+ return nullptr;
+}
+
/// Copy an r-value into memory as part of storing to an atomic type.
/// This needs to create a bit-pattern suitable for atomic operations.
void AtomicInfo::emitCopyIntoMemory(RValue rvalue) const {
@@ -815,6 +857,79 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
e->getExprLoc());
}
+void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue dest, bool isInit) {
+ bool isVolatile = dest.isVolatileQualified();
+ auto order = cir::MemOrder::SequentiallyConsistent;
+ if (!dest.getType()->isAtomicType()) {
+ assert(!cir::MissingFeatures::atomicMicrosoftVolatile());
+ }
+ return emitAtomicStore(rvalue, dest, order, isVolatile, isInit);
+}
+
+/// Emit a store to an l-value of atomic type.
+///
+/// Note that the r-value is expected to be an r-value of the atomic type; this
+/// means that for aggregate r-values, it should include storage for any padding
+/// that was necessary.
+void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue dest,
+ cir::MemOrder order, bool isVolatile,
+ bool isInit) {
+ // If this is an aggregate r-value, it should agree in type except
+ // maybe for address-space qualification.
+ mlir::Location loc = dest.getPointer().getLoc();
+ assert(!rvalue.isAggregate() ||
+ rvalue.getAggregateAddress().getElementType() ==
+ dest.getAddress().getElementType());
+
+ AtomicInfo atomics(*this, dest, loc);
+ LValue lvalue = atomics.getAtomicLValue();
+
+ if (lvalue.isSimple()) {
+ // If this is an initialization, just put the value there normally.
+ if (isInit) {
+ atomics.emitCopyIntoMemory(rvalue);
+ return;
+ }
+
+ // Check whether we should use a library call.
+ if (atomics.shouldUseLibCall()) {
+ assert(!cir::MissingFeatures::atomicUseLibCall());
+ cgm.errorNYI(loc, "emitAtomicStore: atomic store with library call");
+ return;
+ }
+
+ // Okay, we're doing this natively.
+ mlir::Value valueToStore = atomics.convertRValueToInt(rvalue);
+
+ // Do the atomic store.
+ Address addr = atomics.getAtomicAddress();
+ if (mlir::Value value = atomics.getScalarRValValueOrNull(rvalue)) {
+ if (shouldCastToInt(value.getType(), /*CmpXchg=*/false)) {
+ addr = atomics.castToAtomicIntPointer(addr);
+ valueToStore =
+ builder.createIntCast(valueToStore, addr.getElementType());
+ }
+ }
+ cir::StoreOp store = builder.createStore(loc, valueToStore, addr);
+
+ // Initializations don't need to be atomic.
+ if (!isInit) {
+ assert(!cir::MissingFeatures::atomicOpenMP());
+ store.setMemOrder(order);
+ }
+
+ // Other decoration.
+ if (isVolatile)
+ store.setIsVolatile(true);
+
+ assert(!cir::MissingFeatures::opLoadStoreTbaa());
+ return;
+ }
+
+ cgm.errorNYI(loc, "emitAtomicStore: non-simple atomic lvalue");
+ assert(!cir::MissingFeatures::opLoadStoreAtomic());
+}
+
void CIRGenFunction::emitAtomicInit(Expr *init, LValue dest) {
AtomicInfo atomics(*this, dest, getLoc(init->getSourceRange()));
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index e35100ffe4b6b..0803910f2e83a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -211,6 +211,28 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
assert(!cir::MissingFeatures::fastMathFlags());
return emitUnaryMaybeConstrainedFPBuiltin(*this, *e);
+ case Builtin::BIceil:
+ case Builtin::BIceilf:
+ case Builtin::BIceill:
+ case Builtin::BI__builtin_ceil:
+ case Builtin::BI__builtin_ceilf:
+ case Builtin::BI__builtin_ceilf16:
+ case Builtin::BI__builtin_ceill:
+ case Builtin::BI__builtin_ceilf128:
+ assert(!cir::MissingFeatures::fastMathFlags());
+ return emitUnaryMaybeConstrainedFPBuiltin(*this, *e);
+
+ case Builtin::BIexp:
+ case Builtin::BIexpf:
+ case Builtin::BIexpl:
+ case Builtin::BI__builtin_exp:
+ case Builtin::BI__builtin_expf:
+ case Builtin::BI__builtin_expf16:
+ case Builtin::BI__builtin_expl:
+ case Builtin::BI__builtin_expf128:
+ assert(!cir::MissingFeatures::fastMathFlags());
+ return emitUnaryMaybeConstrainedFPBuiltin(*this, *e);
+
case Builtin::BIfabs:
case Builtin::BIfabsf:
case Builtin::BIfabsl:
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
index 851328a7db680..437db306f3369 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
@@ -147,8 +147,8 @@ void *EHScopeStack::pushCleanup(CleanupKind kind, size_t size) {
assert(!cir::MissingFeatures::innermostEHScope());
- EHCleanupScope *scope = new (buffer)
- EHCleanupScope(size, branchFixups.size(), innermostNormalCleanup);
+ EHCleanupScope *scope = new (buffer) EHCleanupScope(
+ size, branchFixups.size(), innermostNormalCleanup, innermostEHScope);
if (isNormalCleanup)
innermostNormalCleanup = stable_begin();
@@ -191,7 +191,9 @@ void EHScopeStack::popCleanup() {
EHCatchScope *EHScopeStack::pushCatch(unsigned numHandlers) {
char *buffer = allocate(EHCatchScope::getSizeForNumHandlers(numHandlers));
assert(!cir::MissingFeatures::innermostEHScope());
- EHCatchScope *scope = new (buffer) EHCatchScope(numHandlers);
+ EHCatchScope *scope =
+ new (buffer) EHCatchScope(numHandlers, innermostEHScope);
+ innermostEHScope = stable_begin();
return scope;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.h b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
index 61a09a59b05c0..a035d792ef6d1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
@@ -30,6 +30,8 @@ struct CatchTypeInfo {
/// A protected scope for zero-cost EH handling.
class EHScope {
+ EHScopeStack::stable_iterator enclosingEHScope;
+
class CommonBitFields {
friend class EHScope;
unsigned kind : 3;
@@ -79,7 +81,10 @@ class EHScope {
public:
enum Kind { Cleanup, Catch, Terminate, Filter };
- EHScope(Kind kind) { commonBits.kind = kind; }
+ EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
+ : enclosingEHScope(enclosingEHScope) {
+ commonBits.kind = kind;
+ }
Kind getKind() const { return static_cast(commonBits.kind); }
@@ -90,6 +95,10 @@ class EHScope {
assert(!cir::MissingFeatures::ehstackBranches());
return false;
}
+
+ EHScopeStack::stable_iterator getEnclosingEHScope() const {
+ return enclosingEHScope;
+ }
};
/// A scope which attempts to handle some, possibly all, types of
@@ -111,6 +120,8 @@ class EHCatchScope : public EHScope {
/// The catch handler for this type.
mlir::Region *region;
+
+ bool isCatchAll() const { return type.rtti == nullptr; }
};
private:
@@ -118,12 +129,18 @@ class EHCatchScope : public EHScope {
Handler *getHandlers() { return reinterpret_cast(this + 1); }
+ const Handler *getHandlers() const {
+ return reinterpret_cast(this + 1);
+ }
+
public:
static size_t getSizeForNumHandlers(unsigned n) {
return sizeof(EHCatchScope) + n * sizeof(Handler);
}
- EHCatchScope(unsigned numHandlers) : EHScope(Catch) {
+ EHCatchScope(unsigned numHandlers,
+ EHScopeStack::stable_iterator enclosingEHScope)
+ : EHScope(Catch, enclosingEHScope) {
catchBits.numHandlers = numHandlers;
assert(catchBits.numHandlers == numHandlers && "NumHandlers overflow?");
}
@@ -136,6 +153,11 @@ class EHCatchScope : public EHScope {
getHandlers()[i].region = region;
}
+ const Handler &getHandler(unsigned i) const {
+ assert(i < getNumHandlers());
+ return getHandlers()[i];
+ }
+
// Clear all handler blocks.
// FIXME: it's better to always call clearHandlerBlocks in DTOR and have a
// 'takeHandler' or some such function which removes ownership from the
@@ -144,6 +166,10 @@ class EHCatchScope : public EHScope {
// The blocks are owned by TryOp, nothing to delete.
}
+ using iterator = const Handler *;
+ iterator begin() const { return getHandlers(); }
+ iterator end() const { return getHandlers() + getNumHandlers(); }
+
static bool classof(const EHScope *scope) {
return scope->getKind() == Catch;
}
@@ -176,9 +202,10 @@ class alignas(EHScopeStack::ScopeStackAlignment) EHCleanupScope
}
EHCleanupScope(unsigned cleanupSize, unsigned fixupDepth,
- EHScopeStack::stable_iterator enclosingNormal)
- : EHScope(EHScope::Cleanup), enclosingNormal(enclosingNormal),
- fixupDepth(fixupDepth) {
+ EHScopeStack::stable_iterator enclosingNormal,
+ EHScopeStack::stable_iterator enclosingEH)
+ : EHScope(EHScope::Cleanup, enclosingEH),
+ enclosingNormal(enclosingNormal), fixupDepth(fixupDepth) {
// TODO(cir): When exception handling is upstreamed, isNormalCleanup and
// isEHCleanup will be arguments to the constructor.
cleanupBits.isNormalCleanup = true;
@@ -235,13 +262,45 @@ class EHScopeStack::iterator {
EHScope *get() const { return reinterpret_cast(ptr); }
+ EHScope *operator->() const { return get(); }
EHScope &operator*() const { return *get(); }
+
+ iterator &operator++() {
+ size_t size;
+ switch (get()->getKind()) {
+ case EHScope::Catch:
+ size = EHCatchScope::getSizeForNumHandlers(
+ static_cast(get())->getNumHandlers());
+ break;
+
+ case EHScope::Filter:
+ llvm_unreachable("EHScopeStack::iterator Filter");
+ break;
+
+ case EHScope::Cleanup:
+ llvm_unreachable("EHScopeStack::iterator Cleanup");
+ break;
+
+ case EHScope::Terminate:
+ llvm_unreachable("EHScopeStack::iterator Terminate");
+ break;
+ }
+ ptr += llvm::alignTo(size, ScopeStackAlignment);
+ return *this;
+ }
+
+ bool operator==(iterator other) const { return ptr == other.ptr; }
+ bool operator!=(iterator other) const { return ptr != other.ptr; }
};
inline EHScopeStack::iterator EHScopeStack::begin() const {
return iterator(startOfData);
}
+inline EHScopeStack::iterator EHScopeStack::end() const {
+ return iterator(endOfBuffer);
+}
+
inline EHScopeStack::iterator
EHScopeStack::find(stable_iterator savePoint) const {
assert(savePoint.isValid() && "finding invalid savepoint");
@@ -254,7 +313,7 @@ inline void EHScopeStack::popCatch() {
assert(!empty() && "popping exception stack when not empty");
EHCatchScope &scope = llvm::cast(*begin());
- assert(!cir::MissingFeatures::innermostEHScope());
+ innermostEHScope = scope.getEnclosingEHScope();
deallocate(EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers()));
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 5ccb431e626ae..422fa1cf5ad2e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -311,7 +311,8 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
bool isVolatile, QualType ty,
- bool isInit, bool isNontemporal) {
+ LValueBaseInfo baseInfo, bool isInit,
+ bool isNontemporal) {
assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
if (const auto *clangVecTy = ty->getAs()) {
@@ -333,7 +334,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
value = emitToMemory(value, ty);
- assert(!cir::MissingFeatures::opLoadStoreAtomic());
+ assert(!cir::MissingFeatures::opLoadStoreTbaa());
+ LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
+ if (ty->isAtomicType() ||
+ (!isInit && isLValueSuitableForInlineAtomic(atomicLValue))) {
+ emitAtomicStore(RValue::get(value), atomicLValue, isInit);
+ return;
+ }
// Update the alloca with more info on initialization.
assert(addr.getPointer() && "expected pointer to exist");
@@ -550,7 +557,8 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, LValue lvalue,
}
emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
- lvalue.getType(), isInit, /*isNontemporal=*/false);
+ lvalue.getType(), lvalue.getBaseInfo(), isInit,
+ /*isNontemporal=*/false);
}
mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
@@ -1630,7 +1638,7 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot,
bool ignoreResult) {
switch (CIRGenFunction::getEvaluationKind(e->getType())) {
case cir::TEK_Scalar:
- return RValue::get(emitScalarExpr(e));
+ return RValue::get(emitScalarExpr(e, ignoreResult));
case cir::TEK_Complex:
return RValue::getComplex(emitComplexExpr(e));
case cir::TEK_Aggregate: {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 3d3030ca87e2a..201fb73983155 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -343,8 +343,8 @@ class AggExprEmitter : public StmtVisitor {
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitNoInitExpr");
}
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {
- cgf.cgm.errorNYI(dae->getSourceRange(),
- "AggExprEmitter: VisitCXXDefaultArgExpr");
+ CIRGenFunction::CXXDefaultArgExprScope scope(cgf, dae);
+ Visit(dae->getExpr());
}
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *e) {
cgf.cgm.errorNYI(e->getSourceRange(),
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 119314fe27dce..5eba5ba6c3df1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -78,11 +78,15 @@ struct BinOpInfo {
class ScalarExprEmitter : public StmtVisitor {
CIRGenFunction &cgf;
CIRGenBuilderTy &builder;
+ // Unlike classic codegen we set this to false or use std::exchange to read
+ // the value instead of calling TestAndClearIgnoreResultAssign to make it
+ // explicit when the value is used
bool ignoreResultAssign;
public:
- ScalarExprEmitter(CIRGenFunction &cgf, CIRGenBuilderTy &builder)
- : cgf(cgf), builder(builder) {}
+ ScalarExprEmitter(CIRGenFunction &cgf, CIRGenBuilderTy &builder,
+ bool ignoreResultAssign = false)
+ : cgf(cgf), builder(builder), ignoreResultAssign(ignoreResultAssign) {}
//===--------------------------------------------------------------------===//
// Utilities
@@ -221,6 +225,8 @@ class ScalarExprEmitter : public StmtVisitor {
}
mlir::Value VisitArraySubscriptExpr(ArraySubscriptExpr *e) {
+ ignoreResultAssign = false;
+
if (e->getBase()->getType()->isVectorType()) {
assert(!cir::MissingFeatures::scalableVectors());
@@ -839,6 +845,7 @@ class ScalarExprEmitter : public StmtVisitor {
BinOpInfo emitBinOps(const BinaryOperator *e,
QualType promotionType = QualType()) {
+ ignoreResultAssign = false;
BinOpInfo result;
result.lhs = cgf.emitPromotedScalarExpr(e->getLHS(), promotionType);
result.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionType);
@@ -924,6 +931,7 @@ class ScalarExprEmitter : public StmtVisitor {
#undef HANDLEBINOP
mlir::Value emitCmp(const BinaryOperator *e) {
+ ignoreResultAssign = false;
const mlir::Location loc = cgf.getLoc(e->getExprLoc());
mlir::Value result;
QualType lhsTy = e->getLHS()->getType();
@@ -1406,11 +1414,13 @@ CIRGenFunction::emitCompoundAssignmentLValue(const CompoundAssignOperator *e) {
}
/// Emit the computation of the specified expression of scalar type.
-mlir::Value CIRGenFunction::emitScalarExpr(const Expr *e) {
+mlir::Value CIRGenFunction::emitScalarExpr(const Expr *e,
+ bool ignoreResultAssign) {
assert(e && hasScalarEvaluationKind(e->getType()) &&
"Invalid scalar expression to emit");
- return ScalarExprEmitter(*this, builder).Visit(const_cast(e));
+ return ScalarExprEmitter(*this, builder, ignoreResultAssign)
+ .Visit(const_cast(e));
}
mlir::Value CIRGenFunction::emitPromotedScalarExpr(const Expr *e,
@@ -2054,6 +2064,11 @@ mlir::Value ScalarExprEmitter::VisitMemberExpr(MemberExpr *e) {
mlir::Value ScalarExprEmitter::VisitInitListExpr(InitListExpr *e) {
const unsigned numInitElements = e->getNumInits();
+ [[maybe_unused]] const bool ignore = std::exchange(ignoreResultAssign, false);
+ assert((ignore == false ||
+ (numInitElements == 0 && e->getType()->isVoidType())) &&
+ "init list ignored");
+
if (e->hadArrayRangeDesignator()) {
cgf.cgm.errorNYI(e->getSourceRange(), "ArrayRangeDesignator");
return {};
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index e5cecaa573a6e..1c52a78d72e33 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1271,6 +1271,9 @@ class CIRGenFunction : public CIRGenTypeCache {
RValue emitAtomicExpr(AtomicExpr *e);
void emitAtomicInit(Expr *init, LValue dest);
+ void emitAtomicStore(RValue rvalue, LValue dest, bool isInit);
+ void emitAtomicStore(RValue rvalue, LValue dest, cir::MemOrder order,
+ bool isVolatile, bool isInit);
AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d,
mlir::OpBuilder::InsertPoint ip = {});
@@ -1501,7 +1504,8 @@ class CIRGenFunction : public CIRGenTypeCache {
llvm::ArrayRef args = {});
/// Emit the computation of the specified expression of scalar type.
- mlir::Value emitScalarExpr(const clang::Expr *e);
+ mlir::Value emitScalarExpr(const clang::Expr *e,
+ bool ignoreResultAssign = false);
mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
cir::UnaryOpKind kind, bool isPre);
@@ -1679,8 +1683,8 @@ class CIRGenFunction : public CIRGenTypeCache {
bool isInit);
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile,
- clang::QualType ty, bool isInit = false,
- bool isNontemporal = false);
+ clang::QualType ty, LValueBaseInfo baseInfo,
+ bool isInit = false, bool isNontemporal = false);
void emitStoreOfScalar(mlir::Value value, LValue lvalue, bool isInit);
/// Store the specified rvalue into the specified
diff --git a/clang/lib/CIR/CodeGen/EHScopeStack.h b/clang/lib/CIR/CodeGen/EHScopeStack.h
index 4198c23c9cbed..9005b0106b2a4 100644
--- a/clang/lib/CIR/CodeGen/EHScopeStack.h
+++ b/clang/lib/CIR/CodeGen/EHScopeStack.h
@@ -155,6 +155,9 @@ class EHScopeStack {
/// The innermost normal cleanup on the stack.
stable_iterator innermostNormalCleanup = stable_end();
+ /// The innermost EH scope on the stack.
+ stable_iterator innermostEHScope = stable_end();
+
/// The CGF this Stack belong to
CIRGenFunction *cgf = nullptr;
@@ -226,6 +229,8 @@ class EHScopeStack {
}
stable_iterator getInnermostActiveNormalCleanup() const;
+ stable_iterator getInnermostEHScope() const { return innermostEHScope; }
+
/// An unstable reference to a scope-stack depth. Invalidated by
/// pushes but not pops.
class iterator;
@@ -233,6 +238,9 @@ class EHScopeStack {
/// Returns an iterator pointing to the innermost EH scope.
iterator begin() const;
+ /// Returns an iterator pointing to the outermost EH scope.
+ iterator end() const;
+
/// Create a stable reference to the top of the EH stack. The
/// returned reference is valid until that scope is popped off the
/// stack.
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 5a6193fa8d840..ba967a43ce59a 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -194,6 +194,14 @@ mlir::LogicalResult CIRToLLVMCosOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMExpOpLowering::matchAndRewrite(
+ cir::ExpOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Type resTy = typeConverter->convertType(op.getType());
+ rewriter.replaceOpWithNewOp(op, resTy, adaptor.getSrc());
+ return mlir::success();
+}
+
static mlir::Value getLLVMIntCast(mlir::ConversionPatternRewriter &rewriter,
mlir::Value llvmSrc, mlir::Type llvmDstIntTy,
bool isUnsigned, uint64_t cirSrcWidth,
@@ -1336,6 +1344,14 @@ mlir::LogicalResult CIRToLLVMATanOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMCeilOpLowering::matchAndRewrite(
+ cir::CeilOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Type resTy = typeConverter->convertType(op.getType());
+ rewriter.replaceOpWithNewOp(op, resTy, adaptor.getSrc());
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMAllocaOpLowering::matchAndRewrite(
cir::AllocaOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index fbf4a5722caed..b6928ce7d9c44 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -160,6 +160,57 @@ static Value *handleHlslSplitdouble(const CallExpr *E, CodeGenFunction *CGF) {
return LastInst;
}
+static Value *handleElementwiseF16ToF32(CodeGenFunction &CGF,
+ const CallExpr *E) {
+ Value *Op0 = CGF.EmitScalarExpr(E->getArg(0));
+ QualType Op0Ty = E->getArg(0)->getType();
+ llvm::Type *ResType = CGF.FloatTy;
+ uint64_t NumElements = 0;
+ if (Op0->getType()->isVectorTy()) {
+ NumElements =
+ E->getArg(0)->getType()->castAs()->getNumElements();
+ ResType =
+ llvm::VectorType::get(ResType, ElementCount::getFixed(NumElements));
+ }
+ if (!Op0Ty->hasUnsignedIntegerRepresentation())
+ llvm_unreachable(
+ "f16tof32 operand must have an unsigned int representation");
+
+ if (CGF.CGM.getTriple().isDXIL())
+ return CGF.Builder.CreateIntrinsic(ResType, Intrinsic::dx_legacyf16tof32,
+ ArrayRef{Op0}, nullptr,
+ "hlsl.f16tof32");
+
+ if (CGF.CGM.getTriple().isSPIRV()) {
+ // We use the SPIRV UnpackHalf2x16 operation to avoid the need for the
+ // Int16 and Float16 capabilities
+ auto UnpackType =
+ llvm::VectorType::get(CGF.FloatTy, ElementCount::getFixed(2));
+ if (NumElements == 0) {
+ // a scalar input - simply extract the first element of the unpacked
+ // vector
+ Value *Unpack = CGF.Builder.CreateIntrinsic(
+ UnpackType, Intrinsic::spv_unpackhalf2x16, ArrayRef{Op0});
+ return CGF.Builder.CreateExtractElement(Unpack, (uint64_t)0);
+ } else {
+ // a vector input - build a congruent output vector by iterating through
+ // the input vector calling unpackhalf2x16 for each element
+ Value *Result = PoisonValue::get(ResType);
+ for (uint64_t i = 0; i < NumElements; i++) {
+ Value *InVal = CGF.Builder.CreateExtractElement(Op0, i);
+ Value *Unpack = CGF.Builder.CreateIntrinsic(
+ UnpackType, Intrinsic::spv_unpackhalf2x16,
+ ArrayRef{InVal});
+ Value *Res = CGF.Builder.CreateExtractElement(Unpack, (uint64_t)0);
+ Result = CGF.Builder.CreateInsertElement(Result, Res, i);
+ }
+ return Result;
+ }
+ }
+
+ llvm_unreachable("Intrinsic F16ToF32 not supported by target architecture");
+}
+
static Value *emitBufferStride(CodeGenFunction *CGF, const Expr *HandleExpr,
LValue &Stride) {
// Figure out the stride of the buffer elements from the handle type.
@@ -579,6 +630,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
/*ReturnType=*/X->getType(), CGM.getHLSLRuntime().getDegreesIntrinsic(),
ArrayRef{X}, nullptr, "hlsl.degrees");
}
+ case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
+ return handleElementwiseF16ToF32(*this, E);
+ }
case Builtin::BI__builtin_hlsl_elementwise_frac: {
Value *Op0 = EmitScalarExpr(E->getArg(0));
if (!E->getArg(0)->getType()->hasFloatingRepresentation())
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
index 96f3f6221e20f..8ec8aef311656 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -23,6 +23,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/VirtualFileSystem.h"
#include
@@ -378,3 +379,31 @@ clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
HeaderSearchOpts, PreprocessorOpts, CGO, C,
CoverageInfo);
}
+
+namespace clang {
+namespace CodeGen {
+std::optional>
+DemangleTrapReasonInDebugInfo(StringRef FuncName) {
+ static auto TrapRegex =
+ llvm::Regex(llvm::formatv("^{0}\\$(.*)\\$(.*)$", ClangTrapPrefix).str());
+ llvm::SmallVector Matches;
+ std::string *ErrorPtr = nullptr;
+#ifndef NDEBUG
+ std::string Error;
+ ErrorPtr = &Error;
+#endif
+ if (!TrapRegex.match(FuncName, &Matches, ErrorPtr)) {
+ assert(ErrorPtr && ErrorPtr->empty() && "Invalid regex pattern");
+ return {};
+ }
+
+ if (Matches.size() != 3) {
+ assert(0 && "Expected 3 matches from Regex::match");
+ return {};
+ }
+
+ // Returns { Trap Category, Trap Message }
+ return std::make_pair(Matches[1], Matches[2]);
+}
+} // namespace CodeGen
+} // namespace clang
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 51618d17a4180..a0b82cec9a372 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -3857,6 +3857,9 @@ class OffloadingActionBuilder final {
/// Flag set to true if all valid builders allow file bundling/unbundling.
bool CanUseBundler;
+ /// Flag set to false if an argument turns off bundling.
+ bool ShouldUseBundler;
+
public:
OffloadingActionBuilder(Compilation &C, DerivedArgList &Args,
const Driver::InputList &Inputs)
@@ -3891,6 +3894,9 @@ class OffloadingActionBuilder final {
}
CanUseBundler =
ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
+
+ ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
+ options::OPT_no_gpu_bundle_output, true);
}
~OffloadingActionBuilder() {
@@ -4042,11 +4048,11 @@ class OffloadingActionBuilder final {
SB->appendTopLevelActions(OffloadAL);
}
- // If we can use the bundler, replace the host action by the bundling one in
- // the resulting list. Otherwise, just append the device actions. For
- // device only compilation, HostAction is a null pointer, therefore only do
- // this when HostAction is not a null pointer.
- if (CanUseBundler && HostAction &&
+ // If we can and should use the bundler, replace the host action by the
+ // bundling one in the resulting list. Otherwise, just append the device
+ // actions. For device only compilation, HostAction is a null pointer,
+ // therefore only do this when HostAction is not a null pointer.
+ if (CanUseBundler && ShouldUseBundler && HostAction &&
HostAction->getType() != types::TY_Nothing && !OffloadAL.empty()) {
// Add the host action to the list in order to create the bundling action.
OffloadAL.push_back(HostAction);
@@ -6463,9 +6469,16 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
(JA.getOffloadingDeviceKind() == Action::OFK_OpenMP && TC &&
TC->getTriple().isAMDGPU()));
};
- if (!AtTopLevel && JA.getType() == types::TY_LLVM_BC &&
- (C.getArgs().hasArg(options::OPT_emit_llvm) ||
- IsAMDRDCInCompilePhase(JA, C.getArgs())))
+
+ // The linker wrapper may not support the input and output files to be the
+ // same one, and without it -save-temps can fail.
+ bool IsLinkerWrapper =
+ JA.getType() == types::TY_Object && isa(JA);
+ bool IsEmitBitcode = JA.getType() == types::TY_LLVM_BC &&
+ (C.getArgs().hasArg(options::OPT_emit_llvm) ||
+ IsAMDRDCInCompilePhase(JA, C.getArgs()));
+
+ if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
Suffixed += ".tmp";
Suffixed += '.';
Suffixed += Suffix;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d3ab6f1261ad6..30d3e5293a31b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7879,10 +7879,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
!TC.getTriple().isAndroid() && TC.useIntegratedAs()))
CmdArgs.push_back("-faddrsig");
- if ((Triple.isOSBinFormatELF() || Triple.isOSBinFormatMachO()) &&
+ const bool HasDefaultDwarf2CFIASM =
+ (Triple.isOSBinFormatELF() || Triple.isOSBinFormatMachO()) &&
(EH || UnwindTables || AsyncUnwindTables ||
- DebugInfoKind != llvm::codegenoptions::NoDebugInfo))
- CmdArgs.push_back("-D__GCC_HAVE_DWARF2_CFI_ASM=1");
+ DebugInfoKind != llvm::codegenoptions::NoDebugInfo);
+ if (Args.hasFlag(options::OPT_fdwarf2_cfi_asm,
+ options::OPT_fno_dwarf2_cfi_asm, HasDefaultDwarf2CFIASM))
+ CmdArgs.push_back("-fdwarf2-cfi-asm");
if (Arg *A = Args.getLastArg(options::OPT_fsymbol_partition_EQ)) {
std::string Str = A->getAsString(Args);
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index f24b8ab14bdce..406c77cb3ae8f 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -591,7 +591,8 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
CurrentChangeWidthRight = CurrentChange.TokenLength;
const FormatToken *MatchingParenToEncounter = nullptr;
for (unsigned J = I + 1;
- J != E && (Changes[J].NewlinesBefore == 0 || MatchingParenToEncounter);
+ J != E && (Changes[J].NewlinesBefore == 0 ||
+ MatchingParenToEncounter || Changes[J].IsAligned);
++J) {
const auto &Change = Changes[J];
const auto *Tok = Change.Tok;
diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp
index 15fa7de35df97..93e012b163878 100644
--- a/clang/lib/Frontend/DependencyFile.cpp
+++ b/clang/lib/Frontend/DependencyFile.cpp
@@ -75,6 +75,17 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
/*IsMissing*/ false);
}
+ bool EmbedFileNotFound(StringRef FileName) override {
+ DepCollector.maybeAddDependency(
+ llvm::sys::path::remove_leading_dotslash(FileName),
+ /*FromModule=*/false,
+ /*IsSystem=*/false,
+ /*IsModuleFile=*/false,
+ /*IsMissing=*/true);
+ // Return true to silence the file not found diagnostic.
+ return true;
+ }
+
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange,
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index ed3f1f93d25d3..b88d9f89c5f71 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1516,6 +1516,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.PointerAuthIntrinsics)
Builder.defineMacro("__PTRAUTH__");
+ if (CGOpts.Dwarf2CFIAsm)
+ Builder.defineMacro("__GCC_HAVE_DWARF2_CFI_ASM");
+
// Get other target #defines.
TI.getTargetDefines(LangOpts, Builder);
}
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp
index aea3e72d92a84..10032184b5d94 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -349,14 +349,13 @@ struct SourceColumnMap {
/// When the source code line we want to print is too long for
/// the terminal, select the "interesting" region.
-static void selectInterestingSourceRegion(std::string &SourceLine,
- std::string &CaretLine,
- std::string &FixItInsertionLine,
- Columns NonGutterColumns,
- const SourceColumnMap &Map) {
- Columns CaretColumns = Columns(CaretLine.size());
- Columns FixItColumns =
- Columns(llvm::sys::locale::columnWidth(FixItInsertionLine));
+static void selectInterestingSourceRegion(
+ std::string &SourceLine, std::string &CaretLine,
+ std::string &FixItInsertionLine, Columns NonGutterColumns,
+ const SourceColumnMap &Map,
+ SmallVectorImpl &Styles) {
+ Columns CaretColumns = CaretLine.size();
+ Columns FixItColumns = llvm::sys::locale::columnWidth(FixItInsertionLine);
Columns MaxColumns =
std::max({Map.columns().V, CaretColumns.V, FixItColumns.V});
// if the number of columns is less than the desired number we're done
@@ -369,13 +368,11 @@ static void selectInterestingSourceRegion(std::string &SourceLine,
// Find the slice that we need to display the full caret line
// correctly.
Columns CaretStart = 0, CaretEnd = CaretLine.size();
- for (; CaretStart != CaretEnd; CaretStart = CaretStart.next())
- if (!isWhitespace(CaretLine[CaretStart.V]))
- break;
+ while (CaretStart != CaretEnd && isWhitespace(CaretLine[CaretStart.V]))
+ CaretStart = CaretStart.next();
- for (; CaretEnd != CaretStart; CaretEnd = CaretEnd.prev())
- if (!isWhitespace(CaretLine[CaretEnd.V - 1]))
- break;
+ while (CaretEnd != CaretStart && isWhitespace(CaretLine[CaretEnd.V]))
+ CaretEnd = CaretEnd.prev();
// caret has already been inserted into CaretLine so the above whitespace
// check is guaranteed to include the caret
@@ -516,13 +513,45 @@ static void selectInterestingSourceRegion(std::string &SourceLine,
assert(FrontColumnsRemoved + ColumnsKept + BackColumnsRemoved >
NonGutterColumns);
+ // Since we've modified the SourceLine, we also need to adjust the line's
+ // highlighting information. In particular, if we've removed
+ // from the front of the line, we need to move the style ranges to the
+ // left and remove unneeded ranges.
+ // Note in particular that variables like CaretEnd are defined in the
+ // CaretLine, which only contains ASCII, while the style ranges are defined in
+ // the source line, where we have to care for the byte-index != column-index
+ // case.
+ Bytes BytesRemoved =
+ FrontColumnsRemoved > FrontEllipse.size()
+ ? (Map.columnToByte(FrontColumnsRemoved) - Bytes(FrontEllipse.size()))
+ : 0;
+ Bytes CodeEnd =
+ CaretEnd < Map.columns() ? Map.columnToByte(CaretEnd.V) : CaretEnd.V;
+ for (TextDiagnostic::StyleRange &R : Styles) {
+ // Remove style ranges before and after the new truncated snippet.
+ if (R.Start >= static_cast(CodeEnd.V) ||
+ R.End < static_cast(BytesRemoved.V)) {
+ R.Start = R.End = std::numeric_limits::max();
+ continue;
+ }
+ // Move them left. (Note that this can wrap R.Start, but that doesn't
+ // matter).
+ R.Start -= BytesRemoved.V;
+ R.End -= BytesRemoved.V;
+
+ // Don't leak into the ellipse at the end.
+ if (R.Start < static_cast(CodeEnd.V) &&
+ R.End > static_cast(CodeEnd.V))
+ R.End = CodeEnd.V + 1; // R.End is inclusive.
+ }
+
// The line needs some truncation, and we'd prefer to keep the front
// if possible, so remove the back
if (BackColumnsRemoved > Columns(BackEllipse.size()))
SourceLine.replace(SourceEnd.V, std::string::npos, BackEllipse);
// If that's enough then we're done
- if (FrontColumnsRemoved + ColumnsKept <= Columns(NonGutterColumns))
+ if (FrontColumnsRemoved + ColumnsKept <= NonGutterColumns)
return;
// Otherwise remove the front as well
@@ -1391,6 +1420,11 @@ void TextDiagnostic::emitSnippetAndCaret(
OS.indent(MaxLineNoDisplayWidth + 2) << "| ";
};
+ Columns MessageLength = DiagOpts.MessageLength;
+ // If we don't have enough columns available, just abort now.
+ if (MessageLength != 0 && MessageLength <= Columns(MaxLineNoDisplayWidth + 4))
+ return;
+
// Prepare source highlighting information for the lines we're about to
// emit, starting from the first line.
std::unique_ptr[]> SourceStyles =
@@ -1450,10 +1484,14 @@ void TextDiagnostic::emitSnippetAndCaret(
// If the source line is too long for our terminal, select only the
// "interesting" source region within that line.
- Columns MessageLength = DiagOpts.MessageLength;
- if (MessageLength.V != 0)
+ if (MessageLength != 0) {
+ Columns NonGutterColumns = MessageLength;
+ if (MaxLineNoDisplayWidth != 0)
+ NonGutterColumns -= Columns(MaxLineNoDisplayWidth + 4);
selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine,
- MessageLength, SourceColMap);
+ NonGutterColumns, SourceColMap,
+ SourceStyles[LineNo - Lines.first]);
+ }
// If we are in -fdiagnostics-print-source-range-info mode, we are trying
// to produce easily machine parsable output. Add a space before the
@@ -1508,7 +1546,7 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine,
// Print the source line one character at a time.
bool PrintReversed = false;
std::optional CurrentColor;
- size_t I = 0;
+ size_t I = 0; // Bytes.
while (I < SourceLine.size()) {
auto [Str, WasPrintable] =
printableTextForNextCharacter(SourceLine, &I, DiagOpts.TabStop);
diff --git a/clang/lib/Headers/avx10_2_512bf16intrin.h b/clang/lib/Headers/avx10_2_512bf16intrin.h
index 37ebc4f46a826..46ec12a63ef9c 100644
--- a/clang/lib/Headers/avx10_2_512bf16intrin.h
+++ b/clang/lib/Headers/avx10_2_512bf16intrin.h
@@ -24,6 +24,12 @@ typedef __bf16 __m512bh_u __attribute__((__vector_size__(64), __aligned__(1)));
__attribute__((__always_inline__, __nodebug__, __target__("avx10.2"), \
__min_vector_width__(512)))
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define __DEFAULT_FN_ATTRS512_CONSTEXPR __DEFAULT_FN_ATTRS512 constexpr
+#else
+#define __DEFAULT_FN_ATTRS512_CONSTEXPR __DEFAULT_FN_ATTRS512
+#endif
+
static __inline __m512bh __DEFAULT_FN_ATTRS512 _mm512_setzero_pbh(void) {
return __builtin_bit_cast(__m512bh, _mm512_setzero_ps());
}
@@ -167,7 +173,7 @@ _mm512_mask_blend_pbh(__mmask32 __U, __m512bh __A, __m512bh __W) {
(__v32bf)__A);
}
-static __inline__ __m512bh __DEFAULT_FN_ATTRS512
+static __inline__ __m512bh __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_permutex2var_pbh(__m512bh __A, __m512i __I, __m512bh __B) {
return (__m512bh)__builtin_ia32_vpermi2varhi512((__v32hi)__A, (__v32hi)__I,
(__v32hi)__B);
@@ -555,6 +561,7 @@ static __inline__ __m512bh __DEFAULT_FN_ATTRS512 _mm512_maskz_fnmsub_pbh(
(__v32bf)_mm512_setzero_pbh());
}
+#undef __DEFAULT_FN_ATTRS512_CONSTEXPR
#undef __DEFAULT_FN_ATTRS512
#endif
diff --git a/clang/lib/Headers/avx10_2bf16intrin.h b/clang/lib/Headers/avx10_2bf16intrin.h
index 765cd682986b4..8fb8cd7cd0865 100644
--- a/clang/lib/Headers/avx10_2bf16intrin.h
+++ b/clang/lib/Headers/avx10_2bf16intrin.h
@@ -27,6 +27,14 @@ typedef __bf16 __m256bh_u __attribute__((__vector_size__(32), __aligned__(1)));
__attribute__((__always_inline__, __nodebug__, __target__("avx10.2"), \
__min_vector_width__(128)))
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define __DEFAULT_FN_ATTRS128_CONSTEXPR __DEFAULT_FN_ATTRS128 constexpr
+#define __DEFAULT_FN_ATTRS256_CONSTEXPR __DEFAULT_FN_ATTRS256 constexpr
+#else
+#define __DEFAULT_FN_ATTRS128_CONSTEXPR __DEFAULT_FN_ATTRS128
+#define __DEFAULT_FN_ATTRS256_CONSTEXPR __DEFAULT_FN_ATTRS256
+#endif
+
static __inline __m256bh __DEFAULT_FN_ATTRS256 _mm256_setzero_pbh(void) {
return __builtin_bit_cast(__m256bh, _mm256_setzero_ps());
}
@@ -287,13 +295,13 @@ _mm256_mask_blend_pbh(__mmask16 __U, __m256bh __A, __m256bh __W) {
(__v16bf)__A);
}
-static __inline__ __m128bh __DEFAULT_FN_ATTRS128
+static __inline__ __m128bh __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_permutex2var_pbh(__m128bh __A, __m128i __I, __m128bh __B) {
return (__m128bh)__builtin_ia32_vpermi2varhi128((__v8hi)__A, (__v8hi)__I,
(__v8hi)__B);
}
-static __inline__ __m256bh __DEFAULT_FN_ATTRS256
+static __inline__ __m256bh __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_permutex2var_pbh(__m256bh __A, __m256i __I, __m256bh __B) {
return (__m256bh)__builtin_ia32_vpermi2varhi256((__v16hi)__A, (__v16hi)__I,
(__v16hi)__B);
@@ -1080,6 +1088,7 @@ _mm_maskz_fnmsub_pbh(__mmask8 __U, __m128bh __A, __m128bh __B, __m128bh __C) {
#undef __DEFAULT_FN_ATTRS128
#undef __DEFAULT_FN_ATTRS256
-
+#undef __DEFAULT_FN_ATTRS128_CONSTEXPR
+#undef __DEFAULT_FN_ATTRS256_CONSTEXPR
#endif
#endif
diff --git a/clang/lib/Headers/avx512bwintrin.h b/clang/lib/Headers/avx512bwintrin.h
index ac75b6ccde735..aab1f2b61ab8a 100644
--- a/clang/lib/Headers/avx512bwintrin.h
+++ b/clang/lib/Headers/avx512bwintrin.h
@@ -969,35 +969,31 @@ _mm512_maskz_subs_epu16 (__mmask32 __U, __m512i __A, __m512i __B)
(__v32hi)_mm512_setzero_si512());
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
-_mm512_permutex2var_epi16(__m512i __A, __m512i __I, __m512i __B)
-{
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_permutex2var_epi16(__m512i __A, __m512i __I, __m512i __B) {
return (__m512i)__builtin_ia32_vpermi2varhi512((__v32hi)__A, (__v32hi)__I,
(__v32hi)__B);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_mask_permutex2var_epi16(__m512i __A, __mmask32 __U, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectw_512(__U,
(__v32hi)_mm512_permutex2var_epi16(__A, __I, __B),
(__v32hi)__A);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_mask2_permutex2var_epi16(__m512i __A, __m512i __I, __mmask32 __U,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectw_512(__U,
(__v32hi)_mm512_permutex2var_epi16(__A, __I, __B),
(__v32hi)__I);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_maskz_permutex2var_epi16(__mmask32 __U, __m512i __A, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectw_512(__U,
(__v32hi)_mm512_permutex2var_epi16(__A, __I, __B),
(__v32hi)_mm512_setzero_si512());
diff --git a/clang/lib/Headers/avx512fintrin.h b/clang/lib/Headers/avx512fintrin.h
index 18c4a44a4c76e..5fc0afa49ce4c 100644
--- a/clang/lib/Headers/avx512fintrin.h
+++ b/clang/lib/Headers/avx512fintrin.h
@@ -3059,69 +3059,61 @@ _mm512_mask3_fmsubadd_ps(__m512 __A, __m512 __B, __m512 __C, __mmask16 __U)
/* Vector permutations */
-static __inline __m512i __DEFAULT_FN_ATTRS512
-_mm512_permutex2var_epi32(__m512i __A, __m512i __I, __m512i __B)
-{
+static __inline __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_permutex2var_epi32(__m512i __A, __m512i __I, __m512i __B) {
return (__m512i)__builtin_ia32_vpermi2vard512((__v16si)__A, (__v16si) __I,
(__v16si) __B);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_mask_permutex2var_epi32(__m512i __A, __mmask16 __U, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(__U,
(__v16si)_mm512_permutex2var_epi32(__A, __I, __B),
(__v16si)__A);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_mask2_permutex2var_epi32(__m512i __A, __m512i __I, __mmask16 __U,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(__U,
(__v16si)_mm512_permutex2var_epi32(__A, __I, __B),
(__v16si)__I);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_maskz_permutex2var_epi32(__mmask16 __U, __m512i __A, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(__U,
(__v16si)_mm512_permutex2var_epi32(__A, __I, __B),
(__v16si)_mm512_setzero_si512());
}
-static __inline __m512i __DEFAULT_FN_ATTRS512
-_mm512_permutex2var_epi64(__m512i __A, __m512i __I, __m512i __B)
-{
+static __inline __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_permutex2var_epi64(__m512i __A, __m512i __I, __m512i __B) {
return (__m512i)__builtin_ia32_vpermi2varq512((__v8di)__A, (__v8di) __I,
(__v8di) __B);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_mask_permutex2var_epi64(__m512i __A, __mmask8 __U, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectq_512(__U,
(__v8di)_mm512_permutex2var_epi64(__A, __I, __B),
(__v8di)__A);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_mask2_permutex2var_epi64(__m512i __A, __m512i __I, __mmask8 __U,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectq_512(__U,
(__v8di)_mm512_permutex2var_epi64(__A, __I, __B),
(__v8di)__I);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS512
+static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_maskz_permutex2var_epi64(__mmask8 __U, __m512i __A, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectq_512(__U,
(__v8di)_mm512_permutex2var_epi64(__A, __I, __B),
(__v8di)_mm512_setzero_si512());
@@ -5949,71 +5941,66 @@ _mm512_maskz_permutevar_ps(__mmask16 __U, __m512 __A, __m512i __C)
(__v16sf)_mm512_setzero_ps());
}
-static __inline __m512d __DEFAULT_FN_ATTRS512
-_mm512_permutex2var_pd(__m512d __A, __m512i __I, __m512d __B)
-{
+static __inline __m512d __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_permutex2var_pd(__m512d __A, __m512i __I, __m512d __B) {
return (__m512d)__builtin_ia32_vpermi2varpd512((__v8df)__A, (__v8di)__I,
(__v8df)__B);
}
-static __inline__ __m512d __DEFAULT_FN_ATTRS512
-_mm512_mask_permutex2var_pd(__m512d __A, __mmask8 __U, __m512i __I, __m512d __B)
-{
+static __inline__ __m512d __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_mask_permutex2var_pd(__m512d __A, __mmask8 __U, __m512i __I,
+ __m512d __B) {
return (__m512d)__builtin_ia32_selectpd_512(__U,
(__v8df)_mm512_permutex2var_pd(__A, __I, __B),
(__v8df)__A);
}
-static __inline__ __m512d __DEFAULT_FN_ATTRS512
+static __inline__ __m512d __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_mask2_permutex2var_pd(__m512d __A, __m512i __I, __mmask8 __U,
- __m512d __B)
-{
+ __m512d __B) {
return (__m512d)__builtin_ia32_selectpd_512(__U,
(__v8df)_mm512_permutex2var_pd(__A, __I, __B),
(__v8df)(__m512d)__I);
}
-static __inline__ __m512d __DEFAULT_FN_ATTRS512
+static __inline__ __m512d __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_maskz_permutex2var_pd(__mmask8 __U, __m512d __A, __m512i __I,
- __m512d __B)
-{
+ __m512d __B) {
return (__m512d)__builtin_ia32_selectpd_512(__U,
(__v8df)_mm512_permutex2var_pd(__A, __I, __B),
(__v8df)_mm512_setzero_pd());
}
-static __inline __m512 __DEFAULT_FN_ATTRS512
-_mm512_permutex2var_ps(__m512 __A, __m512i __I, __m512 __B)
-{
+static __inline __m512 __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_permutex2var_ps(__m512 __A, __m512i __I, __m512 __B) {
return (__m512)__builtin_ia32_vpermi2varps512((__v16sf)__A, (__v16si)__I,
(__v16sf) __B);
}
-static __inline__ __m512 __DEFAULT_FN_ATTRS512
-_mm512_mask_permutex2var_ps(__m512 __A, __mmask16 __U, __m512i __I, __m512 __B)
-{
+static __inline__ __m512 __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_mask_permutex2var_ps(__m512 __A, __mmask16 __U, __m512i __I,
+ __m512 __B) {
return (__m512)__builtin_ia32_selectps_512(__U,
(__v16sf)_mm512_permutex2var_ps(__A, __I, __B),
(__v16sf)__A);
}
-static __inline__ __m512 __DEFAULT_FN_ATTRS512
-_mm512_mask2_permutex2var_ps(__m512 __A, __m512i __I, __mmask16 __U, __m512 __B)
-{
+static __inline__ __m512 __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_mask2_permutex2var_ps(__m512 __A, __m512i __I, __mmask16 __U,
+ __m512 __B) {
return (__m512)__builtin_ia32_selectps_512(__U,
(__v16sf)_mm512_permutex2var_ps(__A, __I, __B),
(__v16sf)(__m512)__I);
}
-static __inline__ __m512 __DEFAULT_FN_ATTRS512
-_mm512_maskz_permutex2var_ps(__mmask16 __U, __m512 __A, __m512i __I, __m512 __B)
-{
+static __inline__ __m512 __DEFAULT_FN_ATTRS512_CONSTEXPR
+_mm512_maskz_permutex2var_ps(__mmask16 __U, __m512 __A, __m512i __I,
+ __m512 __B) {
return (__m512)__builtin_ia32_selectps_512(__U,
(__v16sf)_mm512_permutex2var_ps(__A, __I, __B),
(__v16sf)_mm512_setzero_ps());
}
-
#define _mm512_cvtt_roundpd_epu32(A, R) \
((__m256i)__builtin_ia32_cvttpd2udq512_mask((__v8df)(__m512d)(A), \
(__v8si)_mm256_undefined_si256(), \
diff --git a/clang/lib/Headers/avx512fp16intrin.h b/clang/lib/Headers/avx512fp16intrin.h
index 142cc079c2c4b..25051228f3e0a 100644
--- a/clang/lib/Headers/avx512fp16intrin.h
+++ b/clang/lib/Headers/avx512fp16intrin.h
@@ -3316,13 +3316,13 @@ _mm512_mask_blend_ph(__mmask32 __U, __m512h __A, __m512h __W) {
(__v32hf)__A);
}
-static __inline__ __m512h __DEFAULT_FN_ATTRS512
+static __inline__ __m512h __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_permutex2var_ph(__m512h __A, __m512i __I, __m512h __B) {
return (__m512h)__builtin_ia32_vpermi2varhi512((__v32hi)__A, (__v32hi)__I,
(__v32hi)__B);
}
-static __inline__ __m512h __DEFAULT_FN_ATTRS512
+static __inline__ __m512h __DEFAULT_FN_ATTRS512_CONSTEXPR
_mm512_permutexvar_ph(__m512i __A, __m512h __B) {
return (__m512h)__builtin_ia32_permvarhi512((__v32hi)__B, (__v32hi)__A);
}
diff --git a/clang/lib/Headers/avx512ifmaintrin.h b/clang/lib/Headers/avx512ifmaintrin.h
index 625a8ff66dc60..f73b607df797f 100644
--- a/clang/lib/Headers/avx512ifmaintrin.h
+++ b/clang/lib/Headers/avx512ifmaintrin.h
@@ -17,9 +17,8 @@
/* Define the default attributes for the functions in this file. */
#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __DEFAULT_FN_ATTRS \
- constexpr \
- __attribute__((__always_inline__, __nodebug__, __target__("avx512ifma"), \
- __min_vector_width__(512)))
+ __attribute__((__always_inline__, __nodebug__, __target__("avx512ifma"), \
+ __min_vector_width__(512))) constexpr
#else
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, __target__("avx512ifma"), \
diff --git a/clang/lib/Headers/avx512ifmavlintrin.h b/clang/lib/Headers/avx512ifmavlintrin.h
index b377c17166ffb..51d5210e5aa5d 100644
--- a/clang/lib/Headers/avx512ifmavlintrin.h
+++ b/clang/lib/Headers/avx512ifmavlintrin.h
@@ -18,13 +18,13 @@
/* Define the default attributes for the functions in this file. */
#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __DEFAULT_FN_ATTRS128 \
- constexpr __attribute__((__always_inline__, __nodebug__, \
- __target__("avx512ifma,avx512vl"), \
- __min_vector_width__(128)))
+ __attribute__((__always_inline__, __nodebug__, \
+ __target__("avx512ifma,avx512vl"), \
+ __min_vector_width__(128))) constexpr
#define __DEFAULT_FN_ATTRS256 \
- constexpr __attribute__((__always_inline__, __nodebug__, \
- __target__("avx512ifma,avx512vl"), \
- __min_vector_width__(256)))
+ __attribute__((__always_inline__, __nodebug__, \
+ __target__("avx512ifma,avx512vl"), \
+ __min_vector_width__(256))) constexpr
#else
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
@@ -34,7 +34,6 @@
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512ifma,avx512vl"), \
__min_vector_width__(256)))
-
#endif
#if !(defined(__AVXIFMA__) || defined(__AVX512IFMA__))
diff --git a/clang/lib/Headers/avx512vbmiintrin.h b/clang/lib/Headers/avx512vbmiintrin.h
index 964535c4c4900..84fda5c5849e8 100644
--- a/clang/lib/Headers/avx512vbmiintrin.h
+++ b/clang/lib/Headers/avx512vbmiintrin.h
@@ -19,59 +19,57 @@
__attribute__((__always_inline__, __nodebug__, __target__("avx512vbmi"), \
__min_vector_width__(512)))
-static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_permutex2var_epi8(__m512i __A, __m512i __I, __m512i __B)
-{
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
+#else
+#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
+#endif
+
+static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm512_permutex2var_epi8(__m512i __A, __m512i __I, __m512i __B) {
return (__m512i)__builtin_ia32_vpermi2varqi512((__v64qi)__A, (__v64qi)__I,
(__v64qi) __B);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS
+static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
_mm512_mask_permutex2var_epi8(__m512i __A, __mmask64 __U, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectb_512(__U,
(__v64qi)_mm512_permutex2var_epi8(__A, __I, __B),
(__v64qi)__A);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS
+static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
_mm512_mask2_permutex2var_epi8(__m512i __A, __m512i __I, __mmask64 __U,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectb_512(__U,
(__v64qi)_mm512_permutex2var_epi8(__A, __I, __B),
(__v64qi)__I);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS
+static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
_mm512_maskz_permutex2var_epi8(__mmask64 __U, __m512i __A, __m512i __I,
- __m512i __B)
-{
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectb_512(__U,
(__v64qi)_mm512_permutex2var_epi8(__A, __I, __B),
(__v64qi)_mm512_setzero_si512());
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_permutexvar_epi8 (__m512i __A, __m512i __B)
-{
+static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm512_permutexvar_epi8(__m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_permvarqi512((__v64qi) __B, (__v64qi) __A);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_permutexvar_epi8 (__mmask64 __M, __m512i __A,
- __m512i __B)
-{
+static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm512_maskz_permutexvar_epi8(__mmask64 __M, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectb_512((__mmask64)__M,
(__v64qi)_mm512_permutexvar_epi8(__A, __B),
(__v64qi)_mm512_setzero_si512());
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_permutexvar_epi8 (__m512i __W, __mmask64 __M, __m512i __A,
- __m512i __B)
-{
+static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm512_mask_permutexvar_epi8(__m512i __W, __mmask64 __M, __m512i __A,
+ __m512i __B) {
return (__m512i)__builtin_ia32_selectb_512((__mmask64)__M,
(__v64qi)_mm512_permutexvar_epi8(__A, __B),
(__v64qi)__W);
@@ -99,8 +97,6 @@ _mm512_maskz_multishift_epi64_epi8(__mmask64 __M, __m512i __X, __m512i __Y)
(__v64qi)_mm512_multishift_epi64_epi8(__X, __Y),
(__v64qi)_mm512_setzero_si512());
}
-
-
+#undef __DEFAULT_FN_ATTRS_CONSTEXPR
#undef __DEFAULT_FN_ATTRS
-
#endif
diff --git a/clang/lib/Headers/avx512vbmivlintrin.h b/clang/lib/Headers/avx512vbmivlintrin.h
index 4c50be7d9e7e5..58a48dadff863 100644
--- a/clang/lib/Headers/avx512vbmivlintrin.h
+++ b/clang/lib/Headers/avx512vbmivlintrin.h
@@ -24,117 +24,110 @@
__target__("avx512vbmi,avx512vl"), \
__min_vector_width__(256)))
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_permutex2var_epi8(__m128i __A, __m128i __I, __m128i __B)
-{
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define __DEFAULT_FN_ATTRS128_CONSTEXPR __DEFAULT_FN_ATTRS128 constexpr
+#define __DEFAULT_FN_ATTRS256_CONSTEXPR __DEFAULT_FN_ATTRS256 constexpr
+#else
+#define __DEFAULT_FN_ATTRS128_CONSTEXPR __DEFAULT_FN_ATTRS128
+#define __DEFAULT_FN_ATTRS256_CONSTEXPR __DEFAULT_FN_ATTRS256
+#endif
+
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+_mm_permutex2var_epi8(__m128i __A, __m128i __I, __m128i __B) {
return (__m128i)__builtin_ia32_vpermi2varqi128((__v16qi)__A,
(__v16qi)__I,
(__v16qi)__B);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask_permutex2var_epi8(__m128i __A, __mmask16 __U, __m128i __I,
- __m128i __B)
-{
+ __m128i __B) {
return (__m128i)__builtin_ia32_selectb_128(__U,
(__v16qi)_mm_permutex2var_epi8(__A, __I, __B),
(__v16qi)__A);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask2_permutex2var_epi8(__m128i __A, __m128i __I, __mmask16 __U,
- __m128i __B)
-{
+ __m128i __B) {
return (__m128i)__builtin_ia32_selectb_128(__U,
(__v16qi)_mm_permutex2var_epi8(__A, __I, __B),
(__v16qi)__I);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_maskz_permutex2var_epi8(__mmask16 __U, __m128i __A, __m128i __I,
- __m128i __B)
-{
+ __m128i __B) {
return (__m128i)__builtin_ia32_selectb_128(__U,
(__v16qi)_mm_permutex2var_epi8(__A, __I, __B),
(__v16qi)_mm_setzero_si128());
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_permutex2var_epi8(__m256i __A, __m256i __I, __m256i __B)
-{
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_permutex2var_epi8(__m256i __A, __m256i __I, __m256i __B) {
return (__m256i)__builtin_ia32_vpermi2varqi256((__v32qi)__A, (__v32qi)__I,
(__v32qi)__B);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask_permutex2var_epi8(__m256i __A, __mmask32 __U, __m256i __I,
- __m256i __B)
-{
+ __m256i __B) {
return (__m256i)__builtin_ia32_selectb_256(__U,
(__v32qi)_mm256_permutex2var_epi8(__A, __I, __B),
(__v32qi)__A);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask2_permutex2var_epi8(__m256i __A, __m256i __I, __mmask32 __U,
- __m256i __B)
-{
+ __m256i __B) {
return (__m256i)__builtin_ia32_selectb_256(__U,
(__v32qi)_mm256_permutex2var_epi8(__A, __I, __B),
(__v32qi)__I);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_maskz_permutex2var_epi8(__mmask32 __U, __m256i __A, __m256i __I,
- __m256i __B)
-{
+ __m256i __B) {
return (__m256i)__builtin_ia32_selectb_256(__U,
(__v32qi)_mm256_permutex2var_epi8(__A, __I, __B),
(__v32qi)_mm256_setzero_si256());
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_permutexvar_epi8 (__m128i __A, __m128i __B)
-{
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+_mm_permutexvar_epi8(__m128i __A, __m128i __B) {
return (__m128i)__builtin_ia32_permvarqi128((__v16qi)__B, (__v16qi)__A);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_permutexvar_epi8 (__mmask16 __M, __m128i __A, __m128i __B)
-{
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+_mm_maskz_permutexvar_epi8(__mmask16 __M, __m128i __A, __m128i __B) {
return (__m128i)__builtin_ia32_selectb_128((__mmask16)__M,
(__v16qi)_mm_permutexvar_epi8(__A, __B),
(__v16qi)_mm_setzero_si128());
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_permutexvar_epi8 (__m128i __W, __mmask16 __M, __m128i __A,
- __m128i __B)
-{
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+_mm_mask_permutexvar_epi8(__m128i __W, __mmask16 __M, __m128i __A,
+ __m128i __B) {
return (__m128i)__builtin_ia32_selectb_128((__mmask16)__M,
(__v16qi)_mm_permutexvar_epi8(__A, __B),
(__v16qi)__W);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_permutexvar_epi8 (__m256i __A, __m256i __B)
-{
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_permutexvar_epi8(__m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_permvarqi256((__v32qi) __B, (__v32qi) __A);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_permutexvar_epi8 (__mmask32 __M, __m256i __A,
- __m256i __B)
-{
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_maskz_permutexvar_epi8(__mmask32 __M, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_selectb_256((__mmask32)__M,
(__v32qi)_mm256_permutexvar_epi8(__A, __B),
(__v32qi)_mm256_setzero_si256());
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_permutexvar_epi8 (__m256i __W, __mmask32 __M, __m256i __A,
- __m256i __B)
-{
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_mask_permutexvar_epi8(__m256i __W, __mmask32 __M, __m256i __A,
+ __m256i __B) {
return (__m256i)__builtin_ia32_selectb_256((__mmask32)__M,
(__v32qi)_mm256_permutexvar_epi8(__A, __B),
(__v32qi)__W);
@@ -186,7 +179,8 @@ _mm256_maskz_multishift_epi64_epi8(__mmask32 __M, __m256i __X, __m256i __Y)
(__v32qi)_mm256_setzero_si256());
}
-
+#undef __DEFAULT_FN_ATTRS128_CONSTEXPR
+#undef __DEFAULT_FN_ATTRS256_CONSTEXPR
#undef __DEFAULT_FN_ATTRS128
#undef __DEFAULT_FN_ATTRS256
diff --git a/clang/lib/Headers/avx512vlbwintrin.h b/clang/lib/Headers/avx512vlbwintrin.h
index 263a1079b26d5..575c0c8962662 100644
--- a/clang/lib/Headers/avx512vlbwintrin.h
+++ b/clang/lib/Headers/avx512vlbwintrin.h
@@ -1223,69 +1223,61 @@ _mm256_maskz_subs_epu16(__mmask16 __U, __m256i __A, __m256i __B)
(__v16hi)_mm256_setzero_si256());
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_permutex2var_epi16(__m128i __A, __m128i __I, __m128i __B)
-{
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+_mm_permutex2var_epi16(__m128i __A, __m128i __I, __m128i __B) {
return (__m128i)__builtin_ia32_vpermi2varhi128((__v8hi)__A, (__v8hi)__I,
(__v8hi) __B);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask_permutex2var_epi16(__m128i __A, __mmask8 __U, __m128i __I,
- __m128i __B)
-{
+ __m128i __B) {
return (__m128i)__builtin_ia32_selectw_128(__U,
(__v8hi)_mm_permutex2var_epi16(__A, __I, __B),
(__v8hi)__A);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask2_permutex2var_epi16(__m128i __A, __m128i __I, __mmask8 __U,
- __m128i __B)
-{
+ __m128i __B) {
return (__m128i)__builtin_ia32_selectw_128(__U,
(__v8hi)_mm_permutex2var_epi16(__A, __I, __B),
(__v8hi)__I);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_permutex2var_epi16 (__mmask8 __U, __m128i __A, __m128i __I,
- __m128i __B)
-{
+static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+_mm_maskz_permutex2var_epi16(__mmask8 __U, __m128i __A, __m128i __I,
+ __m128i __B) {
return (__m128i)__builtin_ia32_selectw_128(__U,
(__v8hi)_mm_permutex2var_epi16(__A, __I, __B),
(__v8hi)_mm_setzero_si128());
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_permutex2var_epi16(__m256i __A, __m256i __I, __m256i __B)
-{
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_permutex2var_epi16(__m256i __A, __m256i __I, __m256i __B) {
return (__m256i)__builtin_ia32_vpermi2varhi256((__v16hi)__A, (__v16hi)__I,
(__v16hi)__B);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask_permutex2var_epi16(__m256i __A, __mmask16 __U, __m256i __I,
- __m256i __B)
-{
+ __m256i __B) {
return (__m256i)__builtin_ia32_selectw_256(__U,
(__v16hi)_mm256_permutex2var_epi16(__A, __I, __B),
(__v16hi)__A);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask2_permutex2var_epi16(__m256i __A, __m256i __I, __mmask16 __U,
- __m256i __B)
-{
+ __m256i __B) {
return (__m256i)__builtin_ia32_selectw_256(__U,
(__v16hi)_mm256_permutex2var_epi16(__A, __I, __B),
(__v16hi)__I);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_permutex2var_epi16 (__mmask16 __U, __m256i __A, __m256i __I,
- __m256i __B)
-{
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_maskz_permutex2var_epi16(__mmask16 __U, __m256i __A, __m256i __I,
+ __m256i __B) {
return (__m256i)__builtin_ia32_selectw_256(__U,
(__v16hi)_mm256_permutex2var_epi16(__A, __I, __B),
(__v16hi)_mm256_setzero_si256());
diff --git a/clang/lib/Headers/avx512vlfp16intrin.h b/clang/lib/Headers/avx512vlfp16intrin.h
index 5b2b3f0d0bbd4..885231b030b23 100644
--- a/clang/lib/Headers/avx512vlfp16intrin.h
+++ b/clang/lib/Headers/avx512vlfp16intrin.h
@@ -2010,24 +2010,24 @@ _mm256_mask_blend_ph(__mmask16 __U, __m256h __A, __m256h __W) {
(__v16hf)__A);
}
-static __inline__ __m128h __DEFAULT_FN_ATTRS128
+static __inline__ __m128h __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_permutex2var_ph(__m128h __A, __m128i __I, __m128h __B) {
return (__m128h)__builtin_ia32_vpermi2varhi128((__v8hi)__A, (__v8hi)__I,
(__v8hi)__B);
}
-static __inline__ __m256h __DEFAULT_FN_ATTRS256
+static __inline__ __m256h __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_permutex2var_ph(__m256h __A, __m256i __I, __m256h __B) {
return (__m256h)__builtin_ia32_vpermi2varhi256((__v16hi)__A, (__v16hi)__I,
(__v16hi)__B);
}
-static __inline__ __m128h __DEFAULT_FN_ATTRS128
+static __inline__ __m128h __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_permutexvar_ph(__m128i __A, __m128h __B) {
return (__m128h)__builtin_ia32_permvarhi128((__v8hi)__B, (__v8hi)__A);
}
-static __inline__ __m256h __DEFAULT_FN_ATTRS256
+static __inline__ __m256h __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_permutexvar_ph(__m256i __A, __m256h __B) {
return (__m256h)__builtin_ia32_permvarhi256((__v16hi)__B, (__v16hi)__A);
}
diff --git a/clang/lib/Headers/avx512vlintrin.h b/clang/lib/Headers/avx512vlintrin.h
index 92bb444aeb5b8..e5249926b934e 100644
--- a/clang/lib/Headers/avx512vlintrin.h
+++ b/clang/lib/Headers/avx512vlintrin.h
@@ -3556,13 +3556,13 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v8sf)_mm256_setzero_ps());
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_permutex2var_epi32(__m128i __A, __m128i __I, __m128i __B) {
return (__m128i)__builtin_ia32_vpermi2vard128((__v4si) __A, (__v4si)__I,
(__v4si)__B);
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask_permutex2var_epi32(__m128i __A, __mmask8 __U, __m128i __I,
__m128i __B) {
return (__m128i)__builtin_ia32_selectd_128(__U,
@@ -3570,7 +3570,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4si)__A);
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask2_permutex2var_epi32(__m128i __A, __m128i __I, __mmask8 __U,
__m128i __B) {
return (__m128i)__builtin_ia32_selectd_128(__U,
@@ -3578,7 +3578,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4si)__I);
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_maskz_permutex2var_epi32(__mmask8 __U, __m128i __A, __m128i __I,
__m128i __B) {
return (__m128i)__builtin_ia32_selectd_128(__U,
@@ -3586,13 +3586,13 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4si)_mm_setzero_si128());
}
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_permutex2var_epi32(__m256i __A, __m256i __I, __m256i __B) {
return (__m256i)__builtin_ia32_vpermi2vard256((__v8si)__A, (__v8si) __I,
(__v8si) __B);
}
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask_permutex2var_epi32(__m256i __A, __mmask8 __U, __m256i __I,
__m256i __B) {
return (__m256i)__builtin_ia32_selectd_256(__U,
@@ -3600,7 +3600,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v8si)__A);
}
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask2_permutex2var_epi32(__m256i __A, __m256i __I, __mmask8 __U,
__m256i __B) {
return (__m256i)__builtin_ia32_selectd_256(__U,
@@ -3608,7 +3608,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v8si)__I);
}
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_maskz_permutex2var_epi32(__mmask8 __U, __m256i __A, __m256i __I,
__m256i __B) {
return (__m256i)__builtin_ia32_selectd_256(__U,
@@ -3616,40 +3616,43 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v8si)_mm256_setzero_si256());
}
- static __inline__ __m128d __DEFAULT_FN_ATTRS128
+ static __inline__ __m128d __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_permutex2var_pd(__m128d __A, __m128i __I, __m128d __B) {
return (__m128d)__builtin_ia32_vpermi2varpd128((__v2df)__A, (__v2di)__I,
(__v2df)__B);
}
- static __inline__ __m128d __DEFAULT_FN_ATTRS128
- _mm_mask_permutex2var_pd(__m128d __A, __mmask8 __U, __m128i __I, __m128d __B) {
+ static __inline__ __m128d __DEFAULT_FN_ATTRS128_CONSTEXPR
+ _mm_mask_permutex2var_pd(__m128d __A, __mmask8 __U, __m128i __I,
+ __m128d __B) {
return (__m128d)__builtin_ia32_selectpd_128(__U,
(__v2df)_mm_permutex2var_pd(__A, __I, __B),
(__v2df)__A);
}
- static __inline__ __m128d __DEFAULT_FN_ATTRS128
- _mm_mask2_permutex2var_pd(__m128d __A, __m128i __I, __mmask8 __U, __m128d __B) {
+ static __inline__ __m128d __DEFAULT_FN_ATTRS128_CONSTEXPR
+ _mm_mask2_permutex2var_pd(__m128d __A, __m128i __I, __mmask8 __U,
+ __m128d __B) {
return (__m128d)__builtin_ia32_selectpd_128(__U,
(__v2df)_mm_permutex2var_pd(__A, __I, __B),
(__v2df)(__m128d)__I);
}
- static __inline__ __m128d __DEFAULT_FN_ATTRS128
- _mm_maskz_permutex2var_pd(__mmask8 __U, __m128d __A, __m128i __I, __m128d __B) {
+ static __inline__ __m128d __DEFAULT_FN_ATTRS128_CONSTEXPR
+ _mm_maskz_permutex2var_pd(__mmask8 __U, __m128d __A, __m128i __I,
+ __m128d __B) {
return (__m128d)__builtin_ia32_selectpd_128(__U,
(__v2df)_mm_permutex2var_pd(__A, __I, __B),
(__v2df)_mm_setzero_pd());
}
- static __inline__ __m256d __DEFAULT_FN_ATTRS256
+ static __inline__ __m256d __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_permutex2var_pd(__m256d __A, __m256i __I, __m256d __B) {
return (__m256d)__builtin_ia32_vpermi2varpd256((__v4df)__A, (__v4di)__I,
(__v4df)__B);
}
- static __inline__ __m256d __DEFAULT_FN_ATTRS256
+ static __inline__ __m256d __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask_permutex2var_pd(__m256d __A, __mmask8 __U, __m256i __I,
__m256d __B) {
return (__m256d)__builtin_ia32_selectpd_256(__U,
@@ -3657,7 +3660,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4df)__A);
}
- static __inline__ __m256d __DEFAULT_FN_ATTRS256
+ static __inline__ __m256d __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask2_permutex2var_pd(__m256d __A, __m256i __I, __mmask8 __U,
__m256d __B) {
return (__m256d)__builtin_ia32_selectpd_256(__U,
@@ -3665,7 +3668,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4df)(__m256d)__I);
}
- static __inline__ __m256d __DEFAULT_FN_ATTRS256
+ static __inline__ __m256d __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_maskz_permutex2var_pd(__mmask8 __U, __m256d __A, __m256i __I,
__m256d __B) {
return (__m256d)__builtin_ia32_selectpd_256(__U,
@@ -3673,47 +3676,48 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4df)_mm256_setzero_pd());
}
- static __inline__ __m128 __DEFAULT_FN_ATTRS128
+ static __inline__ __m128 __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_permutex2var_ps(__m128 __A, __m128i __I, __m128 __B) {
return (__m128)__builtin_ia32_vpermi2varps128((__v4sf)__A, (__v4si)__I,
(__v4sf)__B);
}
- static __inline__ __m128 __DEFAULT_FN_ATTRS128
+ static __inline__ __m128 __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask_permutex2var_ps(__m128 __A, __mmask8 __U, __m128i __I, __m128 __B) {
return (__m128)__builtin_ia32_selectps_128(__U,
(__v4sf)_mm_permutex2var_ps(__A, __I, __B),
(__v4sf)__A);
}
- static __inline__ __m128 __DEFAULT_FN_ATTRS128
+ static __inline__ __m128 __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask2_permutex2var_ps(__m128 __A, __m128i __I, __mmask8 __U, __m128 __B) {
return (__m128)__builtin_ia32_selectps_128(__U,
(__v4sf)_mm_permutex2var_ps(__A, __I, __B),
(__v4sf)(__m128)__I);
}
- static __inline__ __m128 __DEFAULT_FN_ATTRS128
+ static __inline__ __m128 __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_maskz_permutex2var_ps(__mmask8 __U, __m128 __A, __m128i __I, __m128 __B) {
return (__m128)__builtin_ia32_selectps_128(__U,
(__v4sf)_mm_permutex2var_ps(__A, __I, __B),
(__v4sf)_mm_setzero_ps());
}
- static __inline__ __m256 __DEFAULT_FN_ATTRS256
+ static __inline__ __m256 __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_permutex2var_ps(__m256 __A, __m256i __I, __m256 __B) {
return (__m256)__builtin_ia32_vpermi2varps256((__v8sf)__A, (__v8si)__I,
(__v8sf) __B);
}
- static __inline__ __m256 __DEFAULT_FN_ATTRS256
- _mm256_mask_permutex2var_ps(__m256 __A, __mmask8 __U, __m256i __I, __m256 __B) {
+ static __inline__ __m256 __DEFAULT_FN_ATTRS256_CONSTEXPR
+ _mm256_mask_permutex2var_ps(__m256 __A, __mmask8 __U, __m256i __I,
+ __m256 __B) {
return (__m256)__builtin_ia32_selectps_256(__U,
(__v8sf)_mm256_permutex2var_ps(__A, __I, __B),
(__v8sf)__A);
}
- static __inline__ __m256 __DEFAULT_FN_ATTRS256
+ static __inline__ __m256 __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask2_permutex2var_ps(__m256 __A, __m256i __I, __mmask8 __U,
__m256 __B) {
return (__m256)__builtin_ia32_selectps_256(__U,
@@ -3721,7 +3725,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v8sf)(__m256)__I);
}
- static __inline__ __m256 __DEFAULT_FN_ATTRS256
+ static __inline__ __m256 __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_maskz_permutex2var_ps(__mmask8 __U, __m256 __A, __m256i __I,
__m256 __B) {
return (__m256)__builtin_ia32_selectps_256(__U,
@@ -3729,13 +3733,13 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v8sf)_mm256_setzero_ps());
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_permutex2var_epi64(__m128i __A, __m128i __I, __m128i __B) {
return (__m128i)__builtin_ia32_vpermi2varq128((__v2di)__A, (__v2di)__I,
(__v2di)__B);
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask_permutex2var_epi64(__m128i __A, __mmask8 __U, __m128i __I,
__m128i __B) {
return (__m128i)__builtin_ia32_selectq_128(__U,
@@ -3743,7 +3747,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v2di)__A);
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_mask2_permutex2var_epi64(__m128i __A, __m128i __I, __mmask8 __U,
__m128i __B) {
return (__m128i)__builtin_ia32_selectq_128(__U,
@@ -3751,7 +3755,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v2di)__I);
}
- static __inline__ __m128i __DEFAULT_FN_ATTRS128
+ static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
_mm_maskz_permutex2var_epi64(__mmask8 __U, __m128i __A, __m128i __I,
__m128i __B) {
return (__m128i)__builtin_ia32_selectq_128(__U,
@@ -3759,14 +3763,13 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v2di)_mm_setzero_si128());
}
-
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_permutex2var_epi64(__m256i __A, __m256i __I, __m256i __B) {
return (__m256i)__builtin_ia32_vpermi2varq256((__v4di)__A, (__v4di) __I,
(__v4di) __B);
}
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask_permutex2var_epi64(__m256i __A, __mmask8 __U, __m256i __I,
__m256i __B) {
return (__m256i)__builtin_ia32_selectq_256(__U,
@@ -3774,7 +3777,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4di)__A);
}
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_mask2_permutex2var_epi64(__m256i __A, __m256i __I, __mmask8 __U,
__m256i __B) {
return (__m256i)__builtin_ia32_selectq_256(__U,
@@ -3782,7 +3785,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) {
(__v4di)__I);
}
- static __inline__ __m256i __DEFAULT_FN_ATTRS256
+ static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
_mm256_maskz_permutex2var_epi64(__mmask8 __U, __m256i __A, __m256i __I,
__m256i __B) {
return (__m256i)__builtin_ia32_selectq_256(__U,
diff --git a/clang/lib/Headers/avxifmaintrin.h b/clang/lib/Headers/avxifmaintrin.h
index e452d5f0920e9..30df01caed6cf 100644
--- a/clang/lib/Headers/avxifmaintrin.h
+++ b/clang/lib/Headers/avxifmaintrin.h
@@ -17,11 +17,11 @@
/* Define the default attributes for the functions in this file. */
#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __DEFAULT_FN_ATTRS128 \
- constexpr __attribute__((__always_inline__, __nodebug__, \
- __target__("avxifma"), __min_vector_width__(128)))
+ __attribute__((__always_inline__, __nodebug__, __target__("avxifma"), \
+ __min_vector_width__(128))) constexpr
#define __DEFAULT_FN_ATTRS256 \
- constexpr __attribute__((__always_inline__, __nodebug__, \
- __target__("avxifma"), __min_vector_width__(256)))
+ __attribute__((__always_inline__, __nodebug__, __target__("avxifma"), \
+ __min_vector_width__(256))) constexpr
#else
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, __target__("avxifma"), \
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index a918af39e4074..208776eb7840e 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -1052,6 +1052,27 @@ float3 exp2(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_exp2)
float4 exp2(float4);
+//===----------------------------------------------------------------------===//
+// f16tof32 builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn float f16tof32(uint x)
+/// \brief Returns the half value stored in the low 16 bits of the uint arg
+/// converted to a float.
+/// \param x The uint containing two half values.
+///
+/// The float value of the half value found in the low 16 bits of the \a xi
+/// parameter.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_f16tof32)
+float f16tof32(uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_f16tof32)
+float2 f16tof32(uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_f16tof32)
+float3 f16tof32(uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_f16tof32)
+float4 f16tof32(uint4);
+
//===----------------------------------------------------------------------===//
// firstbithigh builtins
//===----------------------------------------------------------------------===//
@@ -2090,9 +2111,17 @@ T select(bool, T, T);
/// \param FalseVals The vector values are chosen from when conditions are
/// false.
-template
+template
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector select(vector, vector, vector);
+vector select(vector, vector, vector);
+
+template
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+vector select(vector, vector, vector);
+
+template
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+vector select(vector, vector, vector);
/// \fn vector select(vector Conds, T TrueVal,
/// vector FalseVals)
@@ -2102,9 +2131,17 @@ vector select(vector, vector, vector);
/// \param FalseVals The vector values are chosen from when conditions are
/// false.
-template
+template
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+vector select(vector, T, vector);
+
+template
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
+vector select(vector, T, vector);
+
+template
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector select(vector, T, vector);
+vector select(vector