473 changes: 313 additions & 160 deletions .github/workflows/release-binaries.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .github/workflows/release-sources.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
steps:
- id: inputs
run: |
ref=${{ inputs.release-version || github.sha }}
ref=${{ (inputs.release-version && format('llvmorg-{0}', inputs.release-version)) || github.sha }}
if [ -n "${{ inputs.release-version }}" ]; then
export_args="-release ${{ inputs.release-version }} -final"
else
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/release-tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,20 @@ jobs:
needs:
- validate-tag
- release-create
strategy:
fail-fast: false
matrix:
runs-on:
- ubuntu-22.04
- windows-2022
- macos-13
- macos-14

uses: ./.github/workflows/release-binaries.yml
with:
release-version: ${{ needs.validate-tag.outputs.release-version }}
upload: true
runs-on: ${{ matrix.runs-on }}

release-sources:
name: Package Release Sources
Expand Down
5 changes: 4 additions & 1 deletion bolt/include/bolt/Core/DebugData.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,8 @@ class DebugStrOffsetsWriter {
}

/// Update Str offset in .debug_str in .debug_str_offsets.
void updateAddressMap(uint32_t Index, uint32_t Address);
void updateAddressMap(uint32_t Index, uint32_t Address,
const DWARFUnit &Unit);

/// Get offset for given index in original .debug_str_offsets section.
uint64_t getOffset(uint32_t Index) const { return StrOffsets[Index]; }
Expand Down Expand Up @@ -507,6 +508,8 @@ class DebugStrOffsetsWriter {
std::unique_ptr<DebugStrOffsetsBufferVector> StrOffsetsBuffer;
std::unique_ptr<raw_svector_ostream> StrOffsetsStream;
std::map<uint32_t, uint32_t> IndexToAddressMap;
[[maybe_unused]]
DenseSet<uint64_t> DebugStrOffsetFinalized;
SmallVector<uint32_t, 5> StrOffsets;
std::unordered_map<uint64_t, uint64_t> ProcessedBaseOffsets;
bool StrOffsetSectionWasModified = false;
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Core/DIEBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static void addStringHelper(DebugStrOffsetsWriter &StrOffstsWriter,
uint32_t NewOffset = StrWriter.addString(Str);
if (Unit.getVersion() >= 5) {
StrOffstsWriter.updateAddressMap(DIEAttrInfo.getDIEInteger().getValue(),
NewOffset);
NewOffset, Unit);
return;
}
DIEBldr.replaceValue(&Die, DIEAttrInfo.getAttribute(), DIEAttrInfo.getForm(),
Expand Down
8 changes: 7 additions & 1 deletion bolt/lib/Core/DebugData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,11 @@ void DebugStrOffsetsWriter::initialize(DWARFUnit &Unit) {
StrOffsetsSection.Data.data() + Contr->Base + Offset));
}

void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) {
void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address,
const DWARFUnit &Unit) {
assert(DebugStrOffsetFinalized.count(Unit.getOffset()) == 0 &&
"Cannot update address map since debug_str_offsets was already "
"finalized for this CU.");
IndexToAddressMap[Index] = Address;
StrOffsetSectionWasModified = true;
}
Expand Down Expand Up @@ -906,6 +910,8 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit,
}

StrOffsetSectionWasModified = false;
assert(DebugStrOffsetFinalized.insert(Unit.getOffset()).second &&
"debug_str_offsets was already finalized for this CU.");
clear();
}

Expand Down
8 changes: 7 additions & 1 deletion bolt/lib/Rewrite/DWARFRewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
Expand All @@ -56,6 +57,8 @@
#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"

static mc::RegisterMCTargetOptionsFlags MOF;

static void printDie(const DWARFDie &DIE) {
DIDumpOptions DumpOpts;
DumpOpts.ShowForm = true;
Expand Down Expand Up @@ -711,7 +714,8 @@ void DWARFRewriter::updateDebugInfo() {
RangesBase = RangesSectionWriter.getSectionOffset() +
getDWARF5RngListLocListHeaderSize();
RangesSectionWriter.initSection(Unit);
StrOffstsWriter->finalizeSection(Unit, DIEBlder);
if (!SplitCU)
StrOffstsWriter->finalizeSection(Unit, DIEBlder);
} else if (SplitCU) {
RangesBase = LegacyRangesSectionWriter.get()->getSectionOffset();
}
Expand Down Expand Up @@ -757,6 +761,8 @@ void DWARFRewriter::updateDebugInfo() {
: std::optional<std::string>(opts::DwarfOutputPath.c_str());
std::string DWOName = DIEBlder.updateDWONameCompDir(
*StrOffstsWriter, *StrWriter, *CU, DwarfOutputPath, std::nullopt);
if (CU->getVersion() >= 5)
StrOffstsWriter->finalizeSection(*CU, DIEBlder);
processSplitCU(*CU, **SplitCU, DIEBlder, *TempRangesSectionWriter,
AddressWriter, DWOName, DwarfOutputPath);
}
Expand Down
4 changes: 3 additions & 1 deletion bolt/test/AArch64/dummy-return.s
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# REQUIRES: system-linux,target=aarch64{{.*}}
# This test checks instrumentation of static binary on AArch64.

# REQUIRES: system-linux,bolt-runtime,target=aarch64{{.*}}

# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -static
Expand Down
28 changes: 28 additions & 0 deletions bolt/test/X86/dwarf5-df-larger-batch-size.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; RUN: rm -rf %t
; RUN: mkdir %t
; RUN: cd %t
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-main.s \
; RUN: -split-dwarf-file=main.dwo -o main.o
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-other.s \
; RUN: -split-dwarf-file=mainOther.dwo -o other.o
; RUN: %clang %cflags main.o other.o -o main.exe
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --cu-processing-batch-size=1
; RUN: llvm-bolt main.exe -o main-batch.exe.bolt --update-debug-sections --cu-processing-batch-size=2
; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo.txt
; RUN: cat %t/foo.txt | FileCheck -check-prefix=BOLT %s
; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo-batch.txt
; RUN: cat %t/foo-batch.txt | FileCheck -check-prefix=BOLT-BATCH %s

;; Tests that BOLT correctly handles DWO name strings with larger batch sizes.

; BOLT: DW_TAG_skeleton_unit
; BOLT: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "main.dwo.dwo")

; BOLT: DW_TAG_skeleton_unit
; BOLT: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "mainOther.dwo.dwo")

; BOLT-BATCH: DW_TAG_skeleton_unit
; BOLT-BATCH: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "main.dwo.dwo")

; BOLT-BATCH: DW_TAG_skeleton_unit
; BOLT-BATCH: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "mainOther.dwo.dwo")
155 changes: 134 additions & 21 deletions clang-tools-extra/clang-tidy/add_new_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@

import argparse
import io
import itertools
import os
import re
import sys
import textwrap


# Adapts the module's CMakelist file. Returns 'True' if it could add a new
# entry and 'False' if the entry already existed.
Expand Down Expand Up @@ -53,7 +56,29 @@ def adapt_cmake(module_path, check_name_camel):


# Adds a header for the new check.
def write_header(module_path, module, namespace, check_name, check_name_camel):
def write_header(
module_path,
module,
namespace,
check_name,
check_name_camel,
description,
lang_restrict,
):
wrapped_desc = "\n".join(
textwrap.wrap(
description, width=80, initial_indent="/// ", subsequent_indent="/// "
)
)
if lang_restrict:
override_supported = """
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return %s;
}""" % (
lang_restrict % {"lang": "LangOpts"}
)
else:
override_supported = ""
filename = os.path.join(module_path, check_name_camel) + ".h"
print("Creating %s..." % filename)
with io.open(filename, "w", encoding="utf8", newline="\n") as f:
Expand Down Expand Up @@ -85,7 +110,7 @@ def write_header(module_path, module, namespace, check_name, check_name_camel):
namespace clang::tidy::%(namespace)s {
/// FIXME: Write a short description.
%(description)s
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/%(module)s/%(check_name)s.html
Expand All @@ -94,7 +119,7 @@ class %(check_name_camel)s : public ClangTidyCheck {
%(check_name_camel)s(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;%(override_supported)s
};
} // namespace clang::tidy::%(namespace)s
Expand All @@ -107,6 +132,8 @@ class %(check_name_camel)s : public ClangTidyCheck {
"check_name": check_name,
"module": module,
"namespace": namespace,
"description": wrapped_desc,
"override_supported": override_supported,
}
)

Expand Down Expand Up @@ -235,7 +262,12 @@ def adapt_module(module_path, module, check_name, check_name_camel):


# Adds a release notes entry.
def add_release_notes(module_path, module, check_name):
def add_release_notes(module_path, module, check_name, description):
wrapped_desc = "\n".join(
textwrap.wrap(
description, width=80, initial_indent=" ", subsequent_indent=" "
)
)
check_name_dashes = module + "-" + check_name
filename = os.path.normpath(
os.path.join(module_path, "../../docs/ReleaseNotes.rst")
Expand Down Expand Up @@ -281,18 +313,20 @@ def add_release_notes(module_path, module, check_name):
"""- New :doc:`%s
<clang-tidy/checks/%s/%s>` check.
FIXME: add release notes.
%s
"""
% (check_name_dashes, module, check_name)
% (check_name_dashes, module, check_name, wrapped_desc)
)
note_added = True

f.write(line)


# Adds a test for the check.
def write_test(module_path, module, check_name, test_extension):
def write_test(module_path, module, check_name, test_extension, test_standard):
if test_standard:
test_standard = f"-std={test_standard}-or-later "
check_name_dashes = module + "-" + check_name
filename = os.path.normpath(
os.path.join(
Expand All @@ -309,7 +343,7 @@ def write_test(module_path, module, check_name, test_extension):
print("Creating %s..." % filename)
with io.open(filename, "w", encoding="utf8", newline="\n") as f:
f.write(
"""// RUN: %%check_clang_tidy %%s %(check_name_dashes)s %%t
"""// RUN: %%check_clang_tidy %(standard)s%%s %(check_name_dashes)s %%t
// FIXME: Add something that triggers the check here.
void f();
Expand All @@ -324,7 +358,7 @@ def write_test(module_path, module, check_name, test_extension):
// FIXME: Add something that doesn't trigger the check here.
void awesome_f2();
"""
% {"check_name_dashes": check_name_dashes}
% {"check_name_dashes": check_name_dashes, "standard": test_standard}
)


Expand Down Expand Up @@ -497,7 +531,10 @@ def format_link_alias(doc_file):
if (match or (check_name.startswith("clang-analyzer-"))) and check_name:
module = doc_file[0]
check_file = doc_file[1].replace(".rst", "")
if not match or match.group(1) == "https://clang.llvm.org/docs/analyzer/checkers":
if (
not match
or match.group(1) == "https://clang.llvm.org/docs/analyzer/checkers"
):
title = "Clang Static Analyzer " + check_file
# Preserve the anchor in checkers.html from group 2.
target = "" if not match else match.group(1) + ".html" + match.group(2)
Expand All @@ -515,29 +552,31 @@ def format_link_alias(doc_file):
if target:
# The checker is just a redirect.
return (
" :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(ref_begin)s`%(title)s <%(target)s>`%(ref_end)s,%(autofix)s\n"
" :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(ref_begin)s`%(title)s <%(target)s>`%(ref_end)s,%(autofix)s\n"
% {
"check_name": check_name,
"module": module,
"check_file": check_file,
"target": target,
"title": title,
"autofix": autofix,
"ref_begin" : ref_begin,
"ref_end" : ref_end
})
"ref_begin": ref_begin,
"ref_end": ref_end,
}
)
else:
# The checker is just a alias without redirect.
return (
" :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(title)s,%(autofix)s\n"
" :doc:`%(check_name)s <%(module)s/%(check_file)s>`, %(title)s,%(autofix)s\n"
% {
"check_name": check_name,
"module": module,
"check_file": check_file,
"target": target,
"title": title,
"autofix": autofix,
})
}
)
return ""

checks = map(format_link, doc_files)
Expand Down Expand Up @@ -599,6 +638,22 @@ def main():
"objc": "m",
"objc++": "mm",
}
cpp_language_to_requirements = {
"c++98": "CPlusPlus",
"c++11": "CPlusPlus11",
"c++14": "CPlusPlus14",
"c++17": "CPlusPlus17",
"c++20": "CPlusPlus20",
"c++23": "CPlusPlus23",
"c++26": "CPlusPlus26",
}
c_language_to_requirements = {
"c99": None,
"c11": "C11",
"c17": "C17",
"c23": "C23",
"c27": "C2Y",
}
parser = argparse.ArgumentParser()
parser.add_argument(
"--update-docs",
Expand All @@ -609,9 +664,26 @@ def main():
"--language",
help="language to use for new check (defaults to c++)",
choices=language_to_extension.keys(),
default="c++",
default=None,
metavar="LANG",
)
parser.add_argument(
"--description",
"-d",
help="short description of what the check does",
default="FIXME: Write a short description",
type=str,
)
parser.add_argument(
"--standard",
help="Specify a specific version of the language",
choices=list(
itertools.chain(
cpp_language_to_requirements.keys(), c_language_to_requirements.keys()
)
),
default=None,
)
parser.add_argument(
"module",
nargs="?",
Expand Down Expand Up @@ -652,12 +724,53 @@ def main():
else:
namespace = module

write_header(module_path, module, namespace, check_name, check_name_camel)
description = args.description
if not description.endswith("."):
description += "."

language = args.language

if args.standard:
if args.standard in cpp_language_to_requirements:
if language and language != "c++":
raise ValueError("C++ standard chosen when language is not C++")
language = "c++"
elif args.standard in c_language_to_requirements:
if language and language != "c":
raise ValueError("C standard chosen when language is not C")
language = "c"

if not language:
language = "c++"

language_restrict = None

if language == "c":
language_restrict = "!%(lang)s.CPlusPlus"
extra = c_language_to_requirements.get(args.standard, None)
if extra:
language_restrict += f" && %(lang)s.{extra}"
elif language == "c++":
language_restrict = (
f"%(lang)s.{cpp_language_to_requirements.get(args.standard, 'CPlusPlus')}"
)
elif language in ["objc", "objc++"]:
language_restrict = "%(lang)s.ObjC"

write_header(
module_path,
module,
namespace,
check_name,
check_name_camel,
description,
language_restrict,
)
write_implementation(module_path, module, namespace, check_name_camel)
adapt_module(module_path, module, check_name, check_name_camel)
add_release_notes(module_path, module, check_name)
test_extension = language_to_extension.get(args.language)
write_test(module_path, module, check_name, test_extension)
add_release_notes(module_path, module, check_name, description)
test_extension = language_to_extension.get(language)
write_test(module_path, module, check_name, test_extension, args.standard)
write_docs(module_path, module, check_name)
update_checks_list(clang_tidy_path)
print("Done. Now it's your turn!")
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/test/clang-doc/basic-project.test
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// See https://github.com/llvm/llvm-project/issues/97507.
// UNSUPPORTED: target={{.*}}

// RUN: rm -rf %t && mkdir -p %t/docs %t/build
// RUN: sed 's|$test_dir|%/S|g' %S/Inputs/basic-project/database_template.json > %t/build/compile_commands.json
// RUN: clang-doc --format=html --output=%t/docs --executor=all-TUs %t/build/compile_commands.json
Expand Down
50 changes: 35 additions & 15 deletions clang-tools-extra/test/clang-tidy/check_clang_tidy.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,11 @@ def run_clang_tidy(self):
self.temp_file_name,
]
+ [
"-fix"
if self.export_fixes is None
else "--export-fixes=" + self.export_fixes
(
"-fix"
if self.export_fixes is None
else "--export-fixes=" + self.export_fixes
)
]
+ [
"--checks=-*," + self.check_name,
Expand Down Expand Up @@ -299,19 +301,37 @@ def run(self):
self.check_notes(clang_tidy_output)


CPP_STANDARDS = [
"c++98",
"c++11",
("c++14", "c++1y"),
("c++17", "c++1z"),
("c++20", "c++2a"),
("c++23", "c++2b"),
("c++26", "c++2c"),
]
C_STANDARDS = ["c99", ("c11", "c1x"), "c17", ("c23", "c2x"), "c2y"]


def expand_std(std):
if std == "c++98-or-later":
return ["c++98", "c++11", "c++14", "c++17", "c++20", "c++23", "c++2c"]
if std == "c++11-or-later":
return ["c++11", "c++14", "c++17", "c++20", "c++23", "c++2c"]
if std == "c++14-or-later":
return ["c++14", "c++17", "c++20", "c++23", "c++2c"]
if std == "c++17-or-later":
return ["c++17", "c++20", "c++23", "c++2c"]
if std == "c++20-or-later":
return ["c++20", "c++23", "c++2c"]
if std == "c++23-or-later":
return ["c++23", "c++2c"]
split_std, or_later, _ = std.partition("-or-later")

if not or_later:
return [split_std]

for standard_list in (CPP_STANDARDS, C_STANDARDS):
item = next(
(
i
for i, v in enumerate(standard_list)
if (split_std in v if isinstance(v, (list, tuple)) else split_std == v)
),
None,
)
if item is not None:
return [split_std] + [
x if isinstance(x, str) else x[0] for x in standard_list[item + 1 :]
]
return [std]


Expand Down
6 changes: 5 additions & 1 deletion clang/cmake/caches/Release.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ endfunction()
# cache file to CMake via -C. e.g.
#
# cmake -D LLVM_RELEASE_ENABLE_PGO=ON -C Release.cmake
set (DEFAULT_RUNTIMES "compiler-rt;libcxx")
if (NOT WIN32)
list(APPEND DEFAULT_RUNTIMES "libcxxabi" "libunwind")
endif()
set(LLVM_RELEASE_ENABLE_LTO THIN CACHE STRING "")
set(LLVM_RELEASE_ENABLE_PGO ON CACHE BOOL "")
set(LLVM_RELEASE_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "")
set(LLVM_RELEASE_ENABLE_RUNTIMES ${DEFAULT_RUNTIMES} CACHE STRING "")
set(LLVM_RELEASE_ENABLE_PROJECTS "clang;lld;lldb;clang-tools-extra;bolt;polly;mlir;flang" CACHE STRING "")
# Note we don't need to add install here, since it is one of the pre-defined
# steps.
Expand Down
1 change: 1 addition & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,7 @@ The following type trait primitives are supported by Clang. Those traits marked
* ``__array_extent(type, dim)`` (Embarcadero):
The ``dim``'th array bound in the type ``type``, or ``0`` if
``dim >= __array_rank(type)``.
* ``__builtin_is_virtual_base_of`` (C++, GNU, Microsoft)
* ``__can_pass_in_regs`` (C++)
Returns whether a class can be passed in registers under the current
ABI. This type can only be applied to unqualified class types.
Expand Down
11 changes: 11 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ C++23 Feature Support
C++2c Feature Support
^^^^^^^^^^^^^^^^^^^^^

- Add ``__builtin_is_virtual_base_of`` intrinsic, which supports
`P2985R0 A type trait for detecting virtual base classes <https://wg21.link/p2985r0>`_

Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -113,6 +116,9 @@ Attribute Changes in Clang

- Introduced a new format attribute ``__attribute__((format(syslog, 1, 2)))`` from OpenBSD.

- The ``hybrid_patchable`` attribute is now supported on ARM64EC targets. It can be used to specify
that a function requires an additional x86-64 thunk, which may be patched at runtime.

Improvements to Clang's diagnostics
-----------------------------------

Expand All @@ -130,6 +136,8 @@ Improvements to Clang's diagnostics

- Clang now diagnoses undefined behavior in constant expressions more consistently. This includes invalid shifts, and signed overflow in arithmetic.

- -Wdangling-assignment-gsl is enabled by default.

Improvements to Clang's time-trace
----------------------------------

Expand Down Expand Up @@ -163,6 +171,9 @@ Miscellaneous Bug Fixes
Miscellaneous Clang Crashes Fixed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Fixed a crash in C due to incorrect lookup that members in nested anonymous struct/union
can be found as ordinary identifiers in struct/union definition. (#GH31295)

OpenACC Specific Changes
------------------------

Expand Down
11 changes: 5 additions & 6 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -4698,26 +4698,25 @@ class FunctionEffect {
};

private:
LLVM_PREFERRED_TYPE(Kind)
unsigned FKind : 3;
Kind FKind;

// Expansion: for hypothetical TCB+types, there could be one Kind for TCB,
// then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would
// be considered for uniqueness.

public:
FunctionEffect() : FKind(unsigned(Kind::None)) {}
FunctionEffect() : FKind(Kind::None) {}

explicit FunctionEffect(Kind K) : FKind(unsigned(K)) {}
explicit FunctionEffect(Kind K) : FKind(K) {}

/// The kind of the effect.
Kind kind() const { return Kind(FKind); }
Kind kind() const { return FKind; }

/// Return the opposite kind, for effects which have opposites.
Kind oppositeKind() const;

/// For serialization.
uint32_t toOpaqueInt32() const { return FKind; }
uint32_t toOpaqueInt32() const { return uint32_t(FKind); }
static FunctionEffect fromOpaqueInt32(uint32_t Value) {
return FunctionEffect(Kind(Value));
}
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,9 @@ def TargetELF : TargetSpec {
def TargetELFOrMachO : TargetSpec {
let ObjectFormats = ["ELF", "MachO"];
}
def TargetWindowsArm64EC : TargetSpec {
let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }];
}

def TargetSupportsInitPriority : TargetSpec {
let CustomCode = [{ !Target.getTriple().isOSzOS() }];
Expand Down Expand Up @@ -4027,6 +4030,12 @@ def SelectAny : InheritableAttr {
let SimpleHandler = 1;
}

def HybridPatchable : InheritableAttr, TargetSpecificAttr<TargetWindowsArm64EC> {
let Spellings = [Declspec<"hybrid_patchable">, Clang<"hybrid_patchable">];
let Subjects = SubjectList<[Function]>;
let Documentation = [HybridPatchableDocs];
}

def Thread : Attr {
let Spellings = [Declspec<"thread">];
let LangOpts = [MicrosoftExt];
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -5985,6 +5985,16 @@ For more information see
or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
}]; }

def HybridPatchableDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``hybrid_patchable`` attribute declares an ARM64EC function with an additional
x86-64 thunk, which may be patched at runtime.

For more information see
`ARM64EC ABI documentation <https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi>`_.
}]; }

def WebAssemblyExportNameDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Expand Down
7 changes: 4 additions & 3 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3681,6 +3681,9 @@ def err_attribute_weak_static : Error<
"weak declaration cannot have internal linkage">;
def err_attribute_selectany_non_extern_data : Error<
"'selectany' can only be applied to data items with external linkage">;
def warn_attribute_hybrid_patchable_non_extern : Warning<
"'hybrid_patchable' is ignored on functions without external linkage">,
InGroup<IgnoredAttributes>;
def err_declspec_thread_on_thread_variable : Error<
"'__declspec(thread)' applied to variable that already has a "
"thread-local storage specifier">;
Expand Down Expand Up @@ -3812,8 +3815,6 @@ def warn_sme_locally_streaming_has_vl_args_returns : Warning<
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
def err_sme_streaming_cannot_be_multiversioned : Error<
"streaming function cannot be multi-versioned">;
def err_unknown_arm_state : Error<
"unknown state '%0'">;
def err_missing_arm_state : Error<
Expand Down Expand Up @@ -10133,7 +10134,7 @@ def warn_dangling_lifetime_pointer : Warning<
InGroup<DanglingGsl>;
def warn_dangling_lifetime_pointer_assignment : Warning<"object backing the "
"pointer %0 will be destroyed at the end of the full-expression">,
InGroup<DanglingAssignmentGsl>, DefaultIgnore;
InGroup<DanglingAssignmentGsl>;
def warn_new_dangling_initializer_list : Warning<
"array backing "
"%select{initializer list subobject of the allocated object|"
Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ COMPATIBLE_LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro")
COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math")
COMPATIBLE_LANGOPT(ProtectParens , 1, 0, "optimizer honors parentheses "
"when floating-point expressions are evaluated")
Expand Down Expand Up @@ -340,7 +339,6 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating poi
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
BENIGN_LANGOPT(CLNoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
COMPATIBLE_LANGOPT(CLUnsafeMath , 1, 0, "Unsafe Floating Point Math")
COMPATIBLE_LANGOPT(CLFiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
/// FP_CONTRACT mode (on/off/fast).
BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point")
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX)
TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)

// GNU and MS Type Traits
TYPE_TRAIT_2(__builtin_is_virtual_base_of, IsVirtualBaseOf, KEYCXX)
TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX)
TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX)
TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX)
Expand Down
14 changes: 6 additions & 8 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,7 @@ def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">,
MarshallingInfoFlag<LangOpts<"SinglePrecisionConstants">>;
def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, Group<opencl_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">,
MarshallingInfoFlag<LangOpts<"CLFiniteMathOnly">>;
HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">;
def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Group<opencl_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Generate kernel argument metadata.">,
Expand Down Expand Up @@ -2609,13 +2608,12 @@ defm approx_func : BoolFOption<"approx-func", LangOpts<"ApproxFunc">, DefaultFal
"with an approximately equivalent calculation",
[funsafe_math_optimizations.KeyPath]>,
NegFlag<SetFalse, [], [ClangOption, CC1Option, FC1Option, FlangOption]>>;
defm finite_math_only : BoolFOption<"finite-math-only",
LangOpts<"FiniteMathOnly">, DefaultFalse,
defm finite_math_only : BoolOptionWithoutMarshalling<"f", "finite-math-only",
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Allow floating-point optimizations that "
"assume arguments and results are not NaNs or +-inf. This defines "
"the \\_\\_FINITE\\_MATH\\_ONLY\\_\\_ preprocessor macro.",
[cl_finite_math_only.KeyPath, ffast_math.KeyPath]>,
[ffast_math.KeyPath]>,
NegFlag<SetFalse>>;
defm signed_zeros : BoolFOption<"signed-zeros",
LangOpts<"NoSignedZero">, DefaultFalse,
Expand Down Expand Up @@ -7815,10 +7813,10 @@ def mreassociate : Flag<["-"], "mreassociate">,
MarshallingInfoFlag<LangOpts<"AllowFPReassoc">>, ImpliedByAnyOf<[funsafe_math_optimizations.KeyPath]>;
def menable_no_nans : Flag<["-"], "menable-no-nans">,
HelpText<"Allow optimization to assume there are no NaNs.">,
MarshallingInfoFlag<LangOpts<"NoHonorNaNs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
def menable_no_infinities : Flag<["-"], "menable-no-infs">,
MarshallingInfoFlag<LangOpts<"NoHonorNaNs">>, ImpliedByAnyOf<[ffast_math.KeyPath]>;
def menable_no_infs : Flag<["-"], "menable-no-infs">,
HelpText<"Allow optimization to assume there are no infinities.">,
MarshallingInfoFlag<LangOpts<"NoHonorInfs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
MarshallingInfoFlag<LangOpts<"NoHonorInfs">>, ImpliedByAnyOf<[ffast_math.KeyPath]>;

def pic_level : Separate<["-"], "pic-level">,
HelpText<"Value for __PIC__">,
Expand Down
12 changes: 0 additions & 12 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -1045,18 +1045,6 @@ def MallocOverflowSecurityChecker : Checker<"MallocOverflow">,

def MmapWriteExecChecker : Checker<"MmapWriteExec">,
HelpText<"Warn on mmap() calls that are both writable and executable">,
CheckerOptions<[
CmdLineOption<Integer,
"MmapProtExec",
"Specifies the value of PROT_EXEC",
"0x04",
Released>,
CmdLineOption<Integer,
"MmapProtRead",
"Specifies the value of PROT_READ",
"0x01",
Released>
]>,
Documentation<HasDocumentation>;

def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,8 +879,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
return IDNS_Ordinary;
case Label:
return IDNS_Label;
case IndirectField:
return IDNS_Ordinary | IDNS_Member;

case Binding:
case NonTypeTemplateParm:
Expand Down Expand Up @@ -918,6 +916,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
return IDNS_ObjCProtocol;

case Field:
case IndirectField:
case ObjCAtDefsField:
case ObjCIvar:
return IDNS_Member;
Expand Down
11 changes: 8 additions & 3 deletions clang/lib/AST/Interp/Disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,15 @@ LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS,
OS << "\n";
OS.indent(Spaces) << "This: " << getThis() << "\n";
OS.indent(Spaces) << "RVO: " << getRVOPtr() << "\n";

while (const InterpFrame *F = this->Caller) {
OS.indent(Spaces) << "Depth: " << Depth << "\n";
OS.indent(Spaces) << "ArgSize: " << ArgSize << "\n";
OS.indent(Spaces) << "Args: " << (void *)Args << "\n";
OS.indent(Spaces) << "FrameOffset: " << FrameOffset << "\n";
OS.indent(Spaces) << "FrameSize: " << (Func ? Func->getFrameSize() : 0)
<< "\n";

for (const InterpFrame *F = this->Caller; F; F = F->Caller) {
F->dump(OS, Indent + 1);
F = F->Caller;
}
}

Expand Down
37 changes: 20 additions & 17 deletions clang/lib/AST/Interp/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1170,27 +1170,30 @@ static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC,
Stk.clear();
}

const APValue &LV = Res.toAPValue();
if (!Res.isInvalid() && LV.isLValue()) {
APValue::LValueBase Base = LV.getLValueBase();
if (Base.isNull()) {
// A null base is acceptable.
return returnInt(true);
} else if (const auto *E = Base.dyn_cast<const Expr *>()) {
if (!isa<StringLiteral>(E))
if (!Res.isInvalid() && !Res.empty()) {
const APValue &LV = Res.toAPValue();
if (LV.isLValue()) {
APValue::LValueBase Base = LV.getLValueBase();
if (Base.isNull()) {
// A null base is acceptable.
return returnInt(true);
} else if (const auto *E = Base.dyn_cast<const Expr *>()) {
if (!isa<StringLiteral>(E))
return returnInt(false);
return returnInt(LV.getLValueOffset().isZero());
} else if (Base.is<TypeInfoLValue>()) {
// Surprisingly, GCC considers __builtin_constant_p(&typeid(int)) to
// evaluate to true.
return returnInt(true);
} else {
// Any other base is not constant enough for GCC.
return returnInt(false);
return returnInt(LV.getLValueOffset().isZero());
} else if (Base.is<TypeInfoLValue>()) {
// Surprisingly, GCC considers __builtin_constant_p(&typeid(int)) to
// evaluate to true.
return returnInt(true);
} else {
// Any other base is not constant enough for GCC.
return returnInt(false);
}
}
}

return returnInt(!Res.isInvalid() && !Res.empty());
// Otherwise, any constant value is good enough.
return returnInt(true);
}

return returnInt(false);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
// below them can initialize the same object (or part of it).
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
isa<CXXDefaultArgExpr>(E) || isa<CXXStdInitializerListExpr>(E) ||
isa<AtomicExpr>(E) ||
isa<AtomicExpr>(E) || isa<CXXInheritedCtorInitExpr>(E) ||
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
// it may not even be casting from a record type -- and even if it is,
// the two objects are in general of unrelated type.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ void LangOptions::resetNonModularOptions() {
// invocations that cannot be round-tripped to arguments.
// FIXME: we should derive this automatically from ImpliedBy in tablegen.
AllowFPReassoc = UnsafeFPMath;
NoHonorNaNs = FiniteMathOnly;
NoHonorInfs = FiniteMathOnly;
NoHonorInfs = FastMath;
NoHonorNaNs = FastMath;

// These options do not affect AST generation.
NoSanitizeFiles.clear();
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Basic/Targets/OSTargets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
// "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical
// transformation unless the transformation is guaranteed to produce a bitwise
// identical result."
const bool any_imprecise_flags =
Opts.FastMath || Opts.FiniteMathOnly || Opts.UnsafeFPMath ||
Opts.AllowFPReassoc || Opts.NoHonorNaNs || Opts.NoHonorInfs ||
Opts.NoSignedZero || Opts.AllowRecip || Opts.ApproxFunc;
const bool any_imprecise_flags = Opts.FastMath || Opts.UnsafeFPMath ||
Opts.AllowFPReassoc || Opts.NoHonorNaNs ||
Opts.NoHonorInfs || Opts.NoSignedZero ||
Opts.AllowRecip || Opts.ApproxFunc;

// "Under both /fp:precise and /fp:fast, the compiler generates code intended
// to run in the default floating-point environment."
Expand Down
13 changes: 12 additions & 1 deletion clang/lib/CodeGen/CGAtomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,

llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1);
llvm::AtomicRMWInst *RMWI =
CGF.Builder.CreateAtomicRMW(Op, Ptr, LoadVal1, Order, Scope);
CGF.emitAtomicRMWInst(Op, Ptr, LoadVal1, Order, Scope);
RMWI->setVolatile(E->isVolatile());

// For __atomic_*_fetch operations, perform the operation again to
Expand Down Expand Up @@ -2034,6 +2034,17 @@ std::pair<RValue, llvm::Value *> CodeGenFunction::EmitAtomicCompareExchange(
IsWeak);
}

llvm::AtomicRMWInst *
CodeGenFunction::emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr,
llvm::Value *Val, llvm::AtomicOrdering Order,
llvm::SyncScope::ID SSID) {

llvm::AtomicRMWInst *RMW =
Builder.CreateAtomicRMW(Op, Addr, Val, Order, SSID);
getTargetHooks().setTargetAtomicMetadata(*this, *RMW);
return RMW;
}

void CodeGenFunction::EmitAtomicUpdate(
LValue LVal, llvm::AtomicOrdering AO,
const llvm::function_ref<RValue(RValue)> &UpdateOp, bool IsVolatile) {
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5986,8 +5986,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
getTarget().getTriple().isAMDGCN() ||
(getTarget().getTriple().isSPIRV() &&
getTarget().getTriple().getVendor() == Triple::VendorType::AMD)) {
if (getLangOpts().OpenMPIsTargetDevice)
return EmitOpenMPDevicePrintfCallExpr(E);
if (getTarget().getTriple().isNVPTX())
return EmitNVPTXDevicePrintfCallExpr(E);
if ((getTarget().getTriple().isAMDGCN() ||
Expand Down
13 changes: 7 additions & 6 deletions clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2841,9 +2841,10 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
llvm::Value *amt = llvm::ConstantFP::get(
VMContext, llvm::APFloat(static_cast<float>(1.0)));
llvm::Value *old =
Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
llvm::AtomicOrdering::SequentiallyConsistent);
llvm::AtomicRMWInst *old =
CGF.emitAtomicRMWInst(aop, LV.getAddress(), amt,
llvm::AtomicOrdering::SequentiallyConsistent);

return isPre ? Builder.CreateBinOp(op, old, amt) : old;
}
value = EmitLoadOfLValue(LV, E->getExprLoc());
Expand Down Expand Up @@ -3583,9 +3584,9 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy,
E->getExprLoc()),
LHSTy);
Value *OldVal = Builder.CreateAtomicRMW(
AtomicOp, LHSLV.getAddress(), Amt,
llvm::AtomicOrdering::SequentiallyConsistent);

llvm::AtomicRMWInst *OldVal =
CGF.emitAtomicRMWInst(AtomicOp, LHSLV.getAddress(), Amt);

// Since operation is atomic, the result type is guaranteed to be the
// same as the input in LLVM terms.
Expand Down
29 changes: 0 additions & 29 deletions clang/lib/CodeGen/CGGPUBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,28 +42,6 @@ llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, "vprintf", &M);
}

llvm::Function *GetOpenMPVprintfDeclaration(CodeGenModule &CGM) {
const char *Name = "__llvm_omp_vprintf";
llvm::Module &M = CGM.getModule();
llvm::Type *ArgTypes[] = {llvm::PointerType::getUnqual(M.getContext()),
llvm::PointerType::getUnqual(M.getContext()),
llvm::Type::getInt32Ty(M.getContext())};
llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false);

if (auto *F = M.getFunction(Name)) {
if (F->getFunctionType() != VprintfFuncType) {
CGM.Error(SourceLocation(),
"Invalid type declaration for __llvm_omp_vprintf");
return nullptr;
}
return F;
}

return llvm::Function::Create(
VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, Name, &M);
}

// Transforms a call to printf into a call to the NVPTX vprintf syscall (which
// isn't particularly special; it's invoked just like a regular function).
// vprintf takes two args: A format string, and a pointer to a buffer containing
Expand Down Expand Up @@ -213,10 +191,3 @@ RValue CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E) {
Builder.SetInsertPoint(IRB.GetInsertBlock(), IRB.GetInsertPoint());
return RValue::get(Printf);
}

RValue CodeGenFunction::EmitOpenMPDevicePrintfCallExpr(const CallExpr *E) {
assert(getTarget().getTriple().isNVPTX() ||
getTarget().getTriple().isAMDGCN());
return EmitDevicePrintfCallExpr(E, this, GetOpenMPVprintfDeclaration(CGM),
true);
}
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGStmtOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6326,8 +6326,8 @@ static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
UpdateVal = CGF.Builder.CreateCast(llvm::Instruction::CastOps::UIToFP, IC,
X.getAddress().getElementType());
}
llvm::Value *Res =
CGF.Builder.CreateAtomicRMW(RMWOp, X.getAddress(), UpdateVal, AO);
llvm::AtomicRMWInst *Res =
CGF.emitAtomicRMWInst(RMWOp, X.getAddress(), UpdateVal, AO);
return std::make_pair(true, RValue::get(Res));
}

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (D && D->hasAttr<NoProfileFunctionAttr>())
Fn->addFnAttr(llvm::Attribute::NoProfile);

if (D && D->hasAttr<HybridPatchableAttr>())
Fn->addFnAttr(llvm::Attribute::HybridPatchable);

if (D) {
// Function attributes take precedence over command line flags.
if (auto *A = D->getAttr<FunctionReturnThunksAttr>()) {
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4160,6 +4160,13 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::AtomicOrdering::SequentiallyConsistent,
bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored());

/// Emit an atomicrmw instruction, and applying relevant metadata when
/// applicable.
llvm::AtomicRMWInst *emitAtomicRMWInst(
llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val,
llvm::AtomicOrdering Order = llvm::AtomicOrdering::SequentiallyConsistent,
llvm::SyncScope::ID SSID = llvm::SyncScope::System);

void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO,
const llvm::function_ref<RValue(RValue)> &UpdateOp,
bool IsVolatile);
Expand Down Expand Up @@ -4529,7 +4536,6 @@ class CodeGenFunction : public CodeGenTypeCache {

RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E);
RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E);
RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E);

RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const CallExpr *E, ReturnValueSlot ReturnValue);
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ class TargetCodeGenInfo {
llvm::AtomicOrdering Ordering,
llvm::LLVMContext &Ctx) const;

/// Allow the target to apply other metadata to an atomic instruction
virtual void setTargetAtomicMetadata(CodeGenFunction &CGF,
llvm::AtomicRMWInst &RMW) const {}

/// Interface class for filling custom fields of a block literal for OpenCL.
class TargetOpenCLBlockHelper {
public:
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/CodeGen/Targets/AMDGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo {
SyncScope Scope,
llvm::AtomicOrdering Ordering,
llvm::LLVMContext &Ctx) const override;
void setTargetAtomicMetadata(CodeGenFunction &CGF,
llvm::AtomicRMWInst &RMW) const override;
llvm::Value *createEnqueuedBlockKernel(CodeGenFunction &CGF,
llvm::Function *BlockInvokeFunc,
llvm::Type *BlockTy) const override;
Expand Down Expand Up @@ -546,6 +548,23 @@ AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts,
return Ctx.getOrInsertSyncScopeID(Name);
}

void AMDGPUTargetCodeGenInfo::setTargetAtomicMetadata(
CodeGenFunction &CGF, llvm::AtomicRMWInst &RMW) const {
if (!CGF.getTarget().allowAMDGPUUnsafeFPAtomics())
return;

// TODO: Introduce new, more controlled options that also work for integers,
// and deprecate allowAMDGPUUnsafeFPAtomics.
llvm::AtomicRMWInst::BinOp RMWOp = RMW.getOperation();
if (llvm::AtomicRMWInst::isFPOperation(RMWOp)) {
llvm::MDNode *Empty = llvm::MDNode::get(CGF.getLLVMContext(), {});
RMW.setMetadata("amdgpu.no.fine.grained.memory", Empty);

if (RMWOp == llvm::AtomicRMWInst::FAdd && RMW.getType()->isFloatTy())
RMW.setMetadata("amdgpu.ignore.denormal.mode", Empty);
}
}

bool AMDGPUTargetCodeGenInfo::shouldEmitStaticExternCAliases() const {
return false;
}
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Driver/ToolChains/AMDGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,10 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const char *LinkingOutput) const {
std::string Linker = getToolChain().GetLinkerPath();
ArgStringList CmdArgs;
CmdArgs.push_back("--no-undefined");
CmdArgs.push_back("-shared");
if (!Args.hasArg(options::OPT_r)) {
CmdArgs.push_back("--no-undefined");
CmdArgs.push_back("-shared");
}

addLinkerCompressDebugSectionsOption(getToolChain(), Args, CmdArgs);
Args.AddAllArgs(CmdArgs, options::OPT_L);
Expand Down
28 changes: 26 additions & 2 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3384,9 +3384,28 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
CmdArgs.push_back("-ffast-math");

// Handle __FINITE_MATH_ONLY__ similarly.
if (!HonorINFs && !HonorNaNs)
// The -ffinite-math-only is added to CmdArgs when !HonorINFs && !HonorNaNs.
// Otherwise process the Xclang arguments to determine if -menable-no-infs and
// -menable-no-nans are set by the user.
bool shouldAddFiniteMathOnly = false;
if (!HonorINFs && !HonorNaNs) {
shouldAddFiniteMathOnly = true;
} else {
bool InfValues = true;
bool NanValues = true;
for (const auto *Arg : Args.filtered(options::OPT_Xclang)) {
StringRef ArgValue = Arg->getValue();
if (ArgValue == "-menable-no-nans")
NanValues = false;
else if (ArgValue == "-menable-no-infs")
InfValues = false;
}
if (!NanValues && !InfValues)
shouldAddFiniteMathOnly = true;
}
if (shouldAddFiniteMathOnly) {
CmdArgs.push_back("-ffinite-math-only");

}
if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
CmdArgs.push_back("-mfpmath");
CmdArgs.push_back(A->getValue());
Expand Down Expand Up @@ -3755,6 +3774,11 @@ static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
CmdArgs.push_back(Args.MakeArgString(CLExtStr));
}

if (Args.hasArg(options::OPT_cl_finite_math_only)) {
CmdArgs.push_back("-menable-no-infs");
CmdArgs.push_back("-menable-no-nans");
}

for (const auto &Arg : ForwardedArguments)
if (const auto *A = Args.getLastArg(Arg))
CmdArgs.push_back(Args.MakeArgString(A->getOption().getPrefixedName()));
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Driver/ToolChains/PS4CPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (UseJMC)
AddLTOFlag("-enable-jmc-instrument");

if (Args.hasFlag(options::OPT_fstack_size_section,
options::OPT_fno_stack_size_section, false))
AddLTOFlag("-stack-size-section");

if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir))
AddLTOFlag(Twine("-crash-diagnostics-dir=") + A->getValue());

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (!LangOpts.MathErrno)
Builder.defineMacro("__NO_MATH_ERRNO__");

if (LangOpts.FastMath || LangOpts.FiniteMathOnly)
if (LangOpts.FastMath || (LangOpts.NoHonorInfs && LangOpts.NoHonorNaNs))
Builder.defineMacro("__FINITE_MATH_ONLY__", "1");
else
Builder.defineMacro("__FINITE_MATH_ONLY__", "0");
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Frontend/PrintPreprocessedOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,6 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
*Callbacks->OS << static_cast<unsigned>(*Iter);
PrintComma = true;
}
IsStartOfLine = true;
} else if (Tok.isAnnotation()) {
// Ignore annotation tokens created by pragmas - the pragmas themselves
// will be reproduced in the preprocessed output.
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Lex/PPMacroExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,16 @@ static bool isTargetVariantEnvironment(const TargetInfo &TI,
return false;
}

#if defined(__sun__) && defined(__svr4__)
// GCC mangles std::tm as tm for binary compatibility on Solaris (Issue
// #33114). We need to match this to allow the std::put_time calls to link
// (PR #99075).
asm("_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
"RSt8ios_basecPKSt2tmPKcSB_ = "
"_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
"RSt8ios_basecPK2tmPKcSB_");
#endif

/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
/// as a builtin macro, handle it and return the next token as 'Tok'.
void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,18 @@ static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall,
return false;
}

// In OpenCL, __builtin_alloca_* should return a pointer to address space
// that corresponds to the stack address space i.e private address space.
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall) {
QualType RT = TheCall->getType();
assert((RT->isPointerType() && !(RT->getPointeeType().hasAddressSpace())) &&
"__builtin_alloca has invalid address space");

RT = RT->getPointeeType();
RT = S.Context.getAddrSpaceQualType(RT, LangAS::opencl_private);
TheCall->setType(S.Context.getPointerType(RT));
}

namespace {
enum PointerAuthOpKind {
PAO_Strip,
Expand Down Expand Up @@ -2214,6 +2226,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI__builtin_alloca_uninitialized:
Diag(TheCall->getBeginLoc(), diag::warn_alloca)
<< TheCall->getDirectCallee();
if (getLangOpts().OpenCL) {
builtinAllocaAddrSpace(*this, TheCall);
}
break;
case Builtin::BI__arithmetic_fence:
if (BuiltinArithmeticFence(TheCall))
Expand Down
29 changes: 25 additions & 4 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6890,6 +6890,11 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
}
}

if (HybridPatchableAttr *Attr = ND.getAttr<HybridPatchableAttr>()) {
if (!ND.isExternallyVisible())
S.Diag(Attr->getLocation(),
diag::warn_attribute_hybrid_patchable_non_extern);
}
if (const InheritableAttr *Attr = getDLLAttr(&ND)) {
auto *VD = dyn_cast<VarDecl>(&ND);
bool IsAnonymousNS = false;
Expand Down Expand Up @@ -11009,6 +11014,9 @@ static bool AttrCompatibleWithMultiVersion(attr::Kind Kind,
switch (Kind) {
default:
return false;
case attr::ArmLocallyStreaming:
return MVKind == MultiVersionKind::TargetVersion ||
MVKind == MultiVersionKind::TargetClones;
case attr::Used:
return MVKind == MultiVersionKind::Target;
case attr::NonNull:
Expand Down Expand Up @@ -11145,7 +11153,21 @@ bool Sema::areMultiversionVariantFunctionsCompatible(
FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo();
FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo();

if (OldTypeInfo.getCC() != NewTypeInfo.getCC())
const auto *OldFPT = OldFD->getType()->getAs<FunctionProtoType>();
const auto *NewFPT = NewFD->getType()->getAs<FunctionProtoType>();

bool ArmStreamingCCMismatched = false;
if (OldFPT && NewFPT) {
unsigned Diff =
OldFPT->getAArch64SMEAttributes() ^ NewFPT->getAArch64SMEAttributes();
// Arm-streaming, arm-streaming-compatible and non-streaming versions
// cannot be mixed.
if (Diff & (FunctionType::SME_PStateSMEnabledMask |
FunctionType::SME_PStateSMCompatibleMask))
ArmStreamingCCMismatched = true;
}

if (OldTypeInfo.getCC() != NewTypeInfo.getCC() || ArmStreamingCCMismatched)
return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << CallingConv;

QualType OldReturnType = OldType->getReturnType();
Expand All @@ -11165,9 +11187,8 @@ bool Sema::areMultiversionVariantFunctionsCompatible(
if (!CLinkageMayDiffer && OldFD->isExternC() != NewFD->isExternC())
return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << LanguageLinkage;

if (CheckEquivalentExceptionSpec(
OldFD->getType()->getAs<FunctionProtoType>(), OldFD->getLocation(),
NewFD->getType()->getAs<FunctionProtoType>(), NewFD->getLocation()))
if (CheckEquivalentExceptionSpec(OldFPT, OldFD->getLocation(), NewFPT,
NewFD->getLocation()))
return true;
}
return false;
Expand Down
10 changes: 3 additions & 7 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3034,9 +3034,6 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << CurFeature << TargetVersion;
}
if (IsArmStreamingFunction(cast<FunctionDecl>(D),
/*IncludeLocallyStreaming=*/false))
return Diag(LiteralLoc, diag::err_sme_streaming_cannot_be_multiversioned);
return false;
}

Expand Down Expand Up @@ -3133,10 +3130,6 @@ bool Sema::checkTargetClonesAttrString(
HasNotDefault = true;
}
}
if (IsArmStreamingFunction(cast<FunctionDecl>(D),
/*IncludeLocallyStreaming=*/false))
return Diag(LiteralLoc,
diag::err_sme_streaming_cannot_be_multiversioned);
} else {
// Other targets ( currently X86 )
if (Cur.starts_with("arch=")) {
Expand Down Expand Up @@ -6878,6 +6871,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_MSConstexpr:
handleMSConstexprAttr(S, D, AL);
break;
case ParsedAttr::AT_HybridPatchable:
handleSimpleAttribute<HybridPatchableAttr>(S, D, AL);
break;

// HLSL attributes:
case ParsedAttr::AT_HLSLNumThreads:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10385,7 +10385,7 @@ void Sema::checkIncorrectVTablePointerAuthenticationAttribute(
while (1) {
assert(PrimaryBase);
const CXXRecordDecl *Base = nullptr;
for (auto BasePtr : PrimaryBase->bases()) {
for (const CXXBaseSpecifier &BasePtr : PrimaryBase->bases()) {
if (!BasePtr.getType()->getAsCXXRecordDecl()->isDynamicClass())
continue;
Base = BasePtr.getType()->getAsCXXRecordDecl();
Expand Down
26 changes: 26 additions & 0 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6030,6 +6030,32 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI
return cast<CXXRecordDecl>(rhsRecord->getDecl())
->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
}
case BTT_IsVirtualBaseOf: {
const RecordType *BaseRecord = LhsT->getAs<RecordType>();
const RecordType *DerivedRecord = RhsT->getAs<RecordType>();

if (!BaseRecord || !DerivedRecord) {
DiagnoseVLAInCXXTypeTrait(Self, Lhs,
tok::kw___builtin_is_virtual_base_of);
DiagnoseVLAInCXXTypeTrait(Self, Rhs,
tok::kw___builtin_is_virtual_base_of);
return false;
}

if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
return false;

if (!BaseRecord->isStructureOrClassType() ||
!DerivedRecord->isStructureOrClassType())
return false;

if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
diag::err_incomplete_type))
return false;

return cast<CXXRecordDecl>(DerivedRecord->getDecl())
->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));
}
case BTT_IsSame:
return Self.Context.hasSameType(LhsT, RhsT);
case BTT_TypeCompatible: {
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Sema/SemaPPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
unsigned BuiltinID,
CallExpr *TheCall) {
ASTContext &Context = getASTContext();
unsigned i = 0, l = 0, u = 0;
bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64;
llvm::APSInt Result;

Expand Down Expand Up @@ -248,7 +247,7 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
return BuiltinPPCMMACall(TheCall, BuiltinID, Types);
#include "clang/Basic/BuiltinsPPC.def"
}
return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u);
llvm_unreachable("must return from switch");
}

// Check if the given type is a non-pointer PPC MMA type. This function is used
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,9 +951,11 @@ class PackDeductionScope {

// Skip over the pack elements that were expanded into separate arguments.
// If we partially expanded, this is the number of partial arguments.
// FIXME: `&& FixedNumExpansions` is a workaround for UB described in
// https://github.com/llvm/llvm-project/issues/100095
if (IsPartiallyExpanded)
PackElements += NumPartialPackArgs;
else if (IsExpanded)
else if (IsExpanded && FixedNumExpansions)
PackElements += *FixedNumExpansions;

for (auto &Pack : Packs) {
Expand Down
58 changes: 29 additions & 29 deletions clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,49 +21,56 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"

using namespace clang;
using namespace ento;

namespace {
class MmapWriteExecChecker : public Checker<check::PreCall> {
class MmapWriteExecChecker
: public Checker<check::ASTDecl<TranslationUnitDecl>, check::PreCall> {
CallDescription MmapFn{CDM::CLibrary, {"mmap"}, 6};
CallDescription MprotectFn{CDM::CLibrary, {"mprotect"}, 3};
static int ProtWrite;
static int ProtExec;
static int ProtRead;
const BugType BT{this, "W^X check fails, Write Exec prot flags set",
"Security"};

// Default values are used if definition of the flags is not found.
mutable int ProtRead = 0x01;
mutable int ProtWrite = 0x02;
mutable int ProtExec = 0x04;

public:
void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager &Mgr,
BugReporter &BR) const;
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
int ProtExecOv;
int ProtReadOv;
};
}

int MmapWriteExecChecker::ProtWrite = 0x02;
int MmapWriteExecChecker::ProtExec = 0x04;
int MmapWriteExecChecker::ProtRead = 0x01;
void MmapWriteExecChecker::checkASTDecl(const TranslationUnitDecl *TU,
AnalysisManager &Mgr,
BugReporter &BR) const {
Preprocessor &PP = Mgr.getPreprocessor();
const std::optional<int> FoundProtRead = tryExpandAsInteger("PROT_READ", PP);
const std::optional<int> FoundProtWrite =
tryExpandAsInteger("PROT_WRITE", PP);
const std::optional<int> FoundProtExec = tryExpandAsInteger("PROT_EXEC", PP);
if (FoundProtRead && FoundProtWrite && FoundProtExec) {
ProtRead = *FoundProtRead;
ProtWrite = *FoundProtWrite;
ProtExec = *FoundProtExec;
}
}

void MmapWriteExecChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
CheckerContext &C) const {
if (matchesAny(Call, MmapFn, MprotectFn)) {
SVal ProtVal = Call.getArgSVal(2);
auto ProtLoc = ProtVal.getAs<nonloc::ConcreteInt>();
if (!ProtLoc)
return;
int64_t Prot = ProtLoc->getValue().getSExtValue();
if (ProtExecOv != ProtExec)
ProtExec = ProtExecOv;
if (ProtReadOv != ProtRead)
ProtRead = ProtReadOv;

// Wrong settings
if (ProtRead == ProtExec)
return;

if ((Prot & (ProtWrite | ProtExec)) == (ProtWrite | ProtExec)) {
if ((Prot & ProtWrite) && (Prot & ProtExec)) {
ExplodedNode *N = C.generateNonFatalErrorNode();
if (!N)
return;
Expand All @@ -80,17 +87,10 @@ void MmapWriteExecChecker::checkPreCall(const CallEvent &Call,
}
}

void ento::registerMmapWriteExecChecker(CheckerManager &mgr) {
MmapWriteExecChecker *Mwec =
mgr.registerChecker<MmapWriteExecChecker>();
Mwec->ProtExecOv =
mgr.getAnalyzerOptions()
.getCheckerIntegerOption(Mwec, "MmapProtExec");
Mwec->ProtReadOv =
mgr.getAnalyzerOptions()
.getCheckerIntegerOption(Mwec, "MmapProtRead");
void ento::registerMmapWriteExecChecker(CheckerManager &Mgr) {
Mgr.registerChecker<MmapWriteExecChecker>();
}

bool ento::shouldRegisterMmapWriteExecChecker(const CheckerManager &mgr) {
bool ento::shouldRegisterMmapWriteExecChecker(const CheckerManager &) {
return true;
}
5 changes: 5 additions & 0 deletions clang/test/AST/Interp/builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ constexpr bool assume() {
return true;
}
static_assert(assume(), "");

void test_builtin_os_log(void *buf, int i, const char *data) {
constexpr int len = __builtin_os_log_format_buffer_size("%d %{public}s %{private}.16P", i, data, data);
static_assert(len > 0, "Expect len > 0");
}
2 changes: 0 additions & 2 deletions clang/test/Analysis/analyzer-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
// CHECK-NEXT: alpha.clone.CloneChecker:ReportNormalClones = true
// CHECK-NEXT: alpha.cplusplus.STLAlgorithmModeling:AggressiveStdFindModeling = false
// CHECK-NEXT: alpha.osx.cocoa.DirectIvarAssignment:AnnotatedFunctions = false
// CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtExec = 0x04
// CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtRead = 0x01
// CHECK-NEXT: alpha.security.taint.TaintPropagation:Config = ""
// CHECK-NEXT: apply-fixits = false
// CHECK-NEXT: assume-controlled-environment = false
Expand Down
11 changes: 6 additions & 5 deletions clang/test/Analysis/mmap-writeexec.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=alpha.security.MmapWriteExec -analyzer-config alpha.security.MmapWriteExec:MmapProtExec=1 -analyzer-config alpha.security.MmapWriteExec:MmapProtRead=4 -DUSE_ALTERNATIVE_PROT_EXEC_DEFINITION -verify %s
// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=alpha.security.MmapWriteExec -DUSE_ALTERNATIVE_PROT_EXEC_DEFINITION -verify %s
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-apple-darwin10 -analyzer-checker=alpha.security.MmapWriteExec -verify %s

#define PROT_WRITE 0x02
#ifndef USE_ALTERNATIVE_PROT_EXEC_DEFINITION
#define PROT_EXEC 0x04
#define PROT_READ 0x01
#else
#define PROT_EXEC 0x01
#define PROT_WRITE 0x02
#define PROT_READ 0x04
#else
#define PROT_EXEC 0x08
#define PROT_WRITE 0x04
#define PROT_READ 0x02
#endif
#define MAP_PRIVATE 0x0002
#define MAP_ANON 0x1000
Expand Down
316 changes: 316 additions & 0 deletions clang/test/CodeGen/AMDGPU/amdgpu-atomic-float.c

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions clang/test/CodeGen/aarch64-fmv-streaming.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -emit-llvm -o - %s | FileCheck %s


// CHECK-LABEL: define {{[^@]+}}@n_callee._Msve
// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
//
// CHECK-LABEL: define {{[^@]+}}@n_callee._Msimd
// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
//
__arm_locally_streaming __attribute__((target_clones("sve", "simd"))) void n_callee(void) {}
// CHECK-LABEL: define {{[^@]+}}@n_callee._Msme2
// CHECK-SAME: () #[[ATTR2:[0-9]+]] {
//
__attribute__((target_version("sme2"))) void n_callee(void) {}
// CHECK-LABEL: define {{[^@]+}}@n_callee.default
// CHECK-SAME: () #[[ATTR3:[0-9]+]] {
//
__attribute__((target_version("default"))) void n_callee(void) {}


// CHECK-LABEL: define {{[^@]+}}@s_callee._Msve
// CHECK-SAME: () #[[ATTR4:[0-9]+]] {
//
// CHECK-LABEL: define {{[^@]+}}@s_callee._Msimd
// CHECK-SAME: () #[[ATTR5:[0-9]+]] {
//
__attribute__((target_clones("sve", "simd"))) void s_callee(void) __arm_streaming {}
// CHECK-LABEL: define {{[^@]+}}@s_callee._Msme2
// CHECK-SAME: () #[[ATTR6:[0-9]+]] {
//
__arm_locally_streaming __attribute__((target_version("sme2"))) void s_callee(void) __arm_streaming {}
// CHECK-LABEL: define {{[^@]+}}@s_callee.default
// CHECK-SAME: () #[[ATTR7:[0-9]+]] {
//
__attribute__((target_version("default"))) void s_callee(void) __arm_streaming {}


// CHECK-LABEL: define {{[^@]+}}@sc_callee._Msve
// CHECK-SAME: () #[[ATTR8:[0-9]+]] {
//
// CHECK-LABEL: define {{[^@]+}}@sc_callee._Msimd
// CHECK-SAME: () #[[ATTR9:[0-9]+]] {
//
__attribute__((target_clones("sve", "simd"))) void sc_callee(void) __arm_streaming_compatible {}
// CHECK-LABEL: define {{[^@]+}}@sc_callee._Msme2
// CHECK-SAME: () #[[ATTR10:[0-9]+]] {
//
__arm_locally_streaming __attribute__((target_version("sme2"))) void sc_callee(void) __arm_streaming_compatible {}
// CHECK-LABEL: define {{[^@]+}}@sc_callee.default
// CHECK-SAME: () #[[ATTR11:[0-9]+]] {
//
__attribute__((target_version("default"))) void sc_callee(void) __arm_streaming_compatible {}


// CHECK-LABEL: define {{[^@]+}}@n_caller
// CHECK-SAME: () #[[ATTR3:[0-9]+]] {
// CHECK: call void @n_callee()
// CHECK: call void @s_callee() #[[ATTR12:[0-9]+]]
// CHECK: call void @sc_callee() #[[ATTR13:[0-9]+]]
//
void n_caller(void) {
n_callee();
s_callee();
sc_callee();
}


// CHECK-LABEL: define {{[^@]+}}@s_caller
// CHECK-SAME: () #[[ATTR7:[0-9]+]] {
// CHECK: call void @n_callee()
// CHECK: call void @s_callee() #[[ATTR12]]
// CHECK: call void @sc_callee() #[[ATTR13]]
//
void s_caller(void) __arm_streaming {
n_callee();
s_callee();
sc_callee();
}


// CHECK-LABEL: define {{[^@]+}}@sc_caller
// CHECK-SAME: () #[[ATTR11:[0-9]+]] {
// CHECK: call void @n_callee()
// CHECK: call void @s_callee() #[[ATTR12]]
// CHECK: call void @sc_callee() #[[ATTR13]]
//
void sc_caller(void) __arm_streaming_compatible {
n_callee();
s_callee();
sc_callee();
}


// CHECK: attributes #[[ATTR0:[0-9]+]] = {{.*}} "aarch64_pstate_sm_body"
// CHECK: attributes #[[ATTR1:[0-9]+]] = {{.*}} "aarch64_pstate_sm_body"
// CHECK: attributes #[[ATTR2:[0-9]+]] = {{.*}}
// CHECK: attributes #[[ATTR3]] = {{.*}}
// CHECK: attributes #[[ATTR4:[0-9]+]] = {{.*}} "aarch64_pstate_sm_enabled"
// CHECK: attributes #[[ATTR5:[0-9]+]] = {{.*}} "aarch64_pstate_sm_enabled"
// CHECK: attributes #[[ATTR6:[0-9]+]] = {{.*}} "aarch64_pstate_sm_body" "aarch64_pstate_sm_enabled"
// CHECK: attributes #[[ATTR7]] = {{.*}} "aarch64_pstate_sm_enabled"
// CHECK: attributes #[[ATTR8:[0-9]+]] = {{.*}} "aarch64_pstate_sm_compatible"
// CHECK: attributes #[[ATTR9:[0-9]+]] = {{.*}} "aarch64_pstate_sm_compatible"
// CHECK: attributes #[[ATTR10]] = {{.*}} "aarch64_pstate_sm_body" "aarch64_pstate_sm_compatible"
// CHECK: attributes #[[ATTR11]] = {{.*}} "aarch64_pstate_sm_compatible"
// CHECK: attributes #[[ATTR12]] = {{.*}} "aarch64_pstate_sm_enabled"
// CHECK: attributes #[[ATTR13]] = {{.*}} "aarch64_pstate_sm_compatible"
34 changes: 34 additions & 0 deletions clang/test/CodeGen/arm64ec-hybrid-patchable.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// REQUIRES: aarch64-registered-target
// RUN: %clang_cc1 -triple arm64ec-pc-windows -fms-extensions -emit-llvm -o - %s -verify | FileCheck %s

// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone
// CHECK-NEXT: define dso_local i32 @func() #0 {
int __attribute__((hybrid_patchable)) func(void) { return 1; }

// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone
// CHECK-NEXT: define dso_local i32 @func2() #0 {
int __declspec(hybrid_patchable) func2(void) { return 2; }

// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone
// CHECK-NEXT: define dso_local i32 @func3() #0 {
int __declspec(hybrid_patchable) func3(void);
int func3(void) { return 3; }

// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone
// CHECK-NEXT: define dso_local i32 @func4() #0 {
[[clang::hybrid_patchable]] int func4(void);
int func4(void) { return 3; }

// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone
// CHECK-NEXT: define internal void @static_func() #0 {
// expected-warning@+1 {{'hybrid_patchable' is ignored on functions without external linkage}}
static void __declspec(hybrid_patchable) static_func(void) {}

// CHECK: ; Function Attrs: hybrid_patchable noinline nounwind optnone
// CHECK-NEXT: define linkonce_odr dso_local i32 @func5() #0 comdat {
int inline __declspec(hybrid_patchable) func5(void) { return 4; }

void caller(void) {
static_func();
func5();
}
2 changes: 1 addition & 1 deletion clang/test/CodeGen/finite-math.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -ffinite-math-only -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FINITE
// RUN: %clang_cc1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FINITE
// RUN: %clang_cc1 -fno-signed-zeros -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=NSZ
// RUN: %clang_cc1 -freciprocal-math -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=RECIP
// RUN: %clang_cc1 -mreassociate -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=REASSOC
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGen/fp-floatcontrol-stack.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DEBSTRICT=1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEBSTRICT %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -DFAST=1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -ffinite-math-only -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s

#define FUN(n) \
(float z) { return n * z + n; }
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGen/fp-options-to-fast-math-flags.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix CHECK-PRECISE %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefix CHECK-NO-NANS %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -menable-no-infs -emit-llvm -o - %s | FileCheck -check-prefix CHECK-NO-INFS %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ffinite-math-only -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FINITE %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FINITE %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fno-signed-zeros -emit-llvm -o - %s | FileCheck -check-prefix CHECK-NO-SIGNED-ZEROS %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -mreassociate -emit-llvm -o - %s | FileCheck -check-prefix CHECK-REASSOC %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -freciprocal-math -emit-llvm -o - %s | FileCheck -check-prefix CHECK-RECIP %s
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/nofpclass.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 2
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -ffinite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CFINITEONLY %s
// RUN: %clang_cc1 -x cl -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -cl-finite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CLFINITEONLY %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefixes=CFINITEONLY %s
// RUN: %clang_cc1 -x cl -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-nans -menable-no-infs -emit-llvm -o - %s | FileCheck -check-prefixes=CLFINITEONLY %s

// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefixes=NONANS %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-infs -emit-llvm -o - %s | FileCheck -check-prefixes=NOINFS %s
Expand Down
102 changes: 79 additions & 23 deletions clang/test/CodeGenCUDA/amdgpu-atomic-ops.cu
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// RUN: %clang_cc1 -x hip %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa \
// RUN: -fcuda-is-device -target-cpu gfx906 -fnative-half-type \
// RUN: -fnative-half-arguments-and-returns | FileCheck %s
// RUN: -fnative-half-arguments-and-returns | FileCheck -check-prefixes=CHECK,SAFEIR %s

// RUN: %clang_cc1 -x hip %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa \
// RUN: -fcuda-is-device -target-cpu gfx906 -fnative-half-type \
// RUN: -fnative-half-arguments-and-returns -munsafe-fp-atomics | FileCheck -check-prefixes=CHECK,UNSAFEIR %s

// RUN: %clang_cc1 -x hip %s -O3 -S -o - -triple=amdgcn-amd-amdhsa \
// RUN: -fcuda-is-device -target-cpu gfx1100 -fnative-half-type \
Expand All @@ -18,24 +22,38 @@

__global__ void ffp1(float *p) {
// CHECK-LABEL: @_Z4ffp1Pf
// CHECK: atomicrmw fadd ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} monotonic
// CHECK: atomicrmw fmin ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic
// CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic
// SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 4{{$}}
// SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 4{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 4{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 4{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 4{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 4{{$}}

// UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+}}, !amdgpu.ignore.denormal.mode !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}

// SAFE: _Z4ffp1Pf
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap

// UNSAFE: _Z4ffp1Pf
// UNSAFE: global_atomic_add_f32
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap

__atomic_fetch_add(p, 1.0f, memory_order_relaxed);
__atomic_fetch_sub(p, 1.0f, memory_order_relaxed);
__atomic_fetch_max(p, 1.0f, memory_order_relaxed);
__atomic_fetch_min(p, 1.0f, memory_order_relaxed);
__hip_atomic_fetch_max(p, 1.0f, memory_order_relaxed, __HIP_MEMORY_SCOPE_AGENT);
Expand All @@ -44,23 +62,36 @@ __global__ void ffp1(float *p) {

__global__ void ffp2(double *p) {
// CHECK-LABEL: @_Z4ffp2Pd
// CHECK: atomicrmw fsub ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} monotonic
// CHECK: atomicrmw fmin ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic
// CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic
// SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8{{$}}

// UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}

// SAFE-LABEL: @_Z4ffp2Pd
// SAFE: global_atomic_cmpswap_b64
// SAFE: global_atomic_cmpswap_b64
// SAFE: global_atomic_cmpswap_b64
// SAFE: global_atomic_cmpswap_b64
// SAFE: global_atomic_cmpswap_b64
// SAFE: global_atomic_cmpswap_b64

// UNSAFE-LABEL: @_Z4ffp2Pd
// UNSAFE: global_atomic_add_f64
// UNSAFE: global_atomic_cmpswap_x2
// UNSAFE: global_atomic_cmpswap_x2
// UNSAFE: global_atomic_cmpswap_x2
// UNSAFE: global_atomic_max_f64
// UNSAFE: global_atomic_min_f64
__atomic_fetch_add(p, 1.0, memory_order_relaxed);
__atomic_fetch_sub(p, 1.0, memory_order_relaxed);
__atomic_fetch_max(p, 1.0, memory_order_relaxed);
__atomic_fetch_min(p, 1.0, memory_order_relaxed);
Expand All @@ -71,11 +102,20 @@ __global__ void ffp2(double *p) {
// long double is the same as double for amdgcn.
__global__ void ffp3(long double *p) {
// CHECK-LABEL: @_Z4ffp3Pe
// CHECK: atomicrmw fsub ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} monotonic
// CHECK: atomicrmw fmin ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic
// CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic
// SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8{{$}}

// UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}

// SAFE-LABEL: @_Z4ffp3Pe
// SAFE: global_atomic_cmpswap_b64
// SAFE: global_atomic_cmpswap_b64
Expand All @@ -88,6 +128,7 @@ __global__ void ffp3(long double *p) {
// UNSAFE: global_atomic_cmpswap_x2
// UNSAFE: global_atomic_max_f64
// UNSAFE: global_atomic_min_f64
__atomic_fetch_add(p, 1.0L, memory_order_relaxed);
__atomic_fetch_sub(p, 1.0L, memory_order_relaxed);
__atomic_fetch_max(p, 1.0L, memory_order_relaxed);
__atomic_fetch_min(p, 1.0L, memory_order_relaxed);
Expand All @@ -98,37 +139,52 @@ __global__ void ffp3(long double *p) {
__device__ double ffp4(double *p, float f) {
// CHECK-LABEL: @_Z4ffp4Pdf
// CHECK: fpext float {{.*}} to double
// CHECK: atomicrmw fsub ptr {{.*}} monotonic
// SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}}
// UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
return __atomic_fetch_sub(p, f, memory_order_relaxed);
}

__device__ double ffp5(double *p, int i) {
// CHECK-LABEL: @_Z4ffp5Pdi
// CHECK: sitofp i32 {{.*}} to double
// CHECK: atomicrmw fsub ptr {{.*}} monotonic
// SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8{{$}}
// UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
return __atomic_fetch_sub(p, i, memory_order_relaxed);
}

__global__ void ffp6(_Float16 *p) {
// CHECK-LABEL: @_Z4ffp6PDF16
// CHECK: atomicrmw fadd ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} monotonic
// CHECK: atomicrmw fmin ptr {{.*}} monotonic
// CHECK: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic
// CHECK: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic
// SAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 2{{$}}
// SAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 2{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 2{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 2{{$}}
// SAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 2{{$}}
// SAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 2{{$}}

// UNSAFEIR: atomicrmw fadd ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fsub ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmax ptr {{.*}} syncscope("agent-one-as") monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// UNSAFEIR: atomicrmw fmin ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 2, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}

// SAFE: _Z4ffp6PDF16
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap
// SAFE: global_atomic_cmpswap

// UNSAFE: _Z4ffp6PDF16
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
// UNSAFE: global_atomic_cmpswap
__atomic_fetch_add(p, 1.0, memory_order_relaxed);
__atomic_fetch_sub(p, 1.0, memory_order_relaxed);
__atomic_fetch_max(p, 1.0, memory_order_relaxed);
__atomic_fetch_min(p, 1.0, memory_order_relaxed);
__hip_atomic_fetch_max(p, 1.0f, memory_order_relaxed, __HIP_MEMORY_SCOPE_AGENT);
Expand Down
141 changes: 141 additions & 0 deletions clang/test/CodeGenOpenCL/builtins-alloca.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL1.2 \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL2.0 \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=OPENCL %s

// OPENCL-LABEL: define dso_local void @test1_builtin_alloca(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0:[0-9]+]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 8, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR]], align 4
// OPENCL-NEXT: ret void
//
void test1_builtin_alloca(unsigned n) {
__private float* alloc_ptr = (__private float*)__builtin_alloca(n*sizeof(int));
}

// OPENCL-LABEL: define dso_local void @test1_builtin_alloca_uninitialized(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 8, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_UNINITIALIZED]], align 4
// OPENCL-NEXT: ret void
//
void test1_builtin_alloca_uninitialized(unsigned n) {
__private float* alloc_ptr_uninitialized = (__private float*)__builtin_alloca_uninitialized(n*sizeof(int));
}

// OPENCL-LABEL: define dso_local void @test1_builtin_alloca_with_align(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR_ALIGN:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 1, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN]], align 4
// OPENCL-NEXT: ret void
//
void test1_builtin_alloca_with_align(unsigned n) {
__private float* alloc_ptr_align = (__private float*)__builtin_alloca_with_align((n*sizeof(int)), 8);
}

// OPENCL-LABEL: define dso_local void @test1_builtin_alloca_with_align_uninitialized(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR_ALIGN_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[MUL:%.*]] = mul i64 [[CONV]], 4
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[MUL]], align 1, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN_UNINITIALIZED]], align 4
// OPENCL-NEXT: ret void
//
void test1_builtin_alloca_with_align_uninitialized(unsigned n) {
__private float* alloc_ptr_align_uninitialized = (__private float*)__builtin_alloca_with_align_uninitialized((n*sizeof(int)), 8);
}

// OPENCL-LABEL: define dso_local void @test2_builtin_alloca(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 8, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR]], align 4
// OPENCL-NEXT: ret void
//
void test2_builtin_alloca(unsigned n) {
__private void *alloc_ptr = __builtin_alloca(n);
}

// OPENCL-LABEL: define dso_local void @test2_builtin_alloca_uninitialized(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 8, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_UNINITIALIZED]], align 4
// OPENCL-NEXT: ret void
//
void test2_builtin_alloca_uninitialized(unsigned n) {
__private void *alloc_ptr_uninitialized = __builtin_alloca_uninitialized(n);
}

// OPENCL-LABEL: define dso_local void @test2_builtin_alloca_with_align(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR_ALIGN:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 1, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN]], align 4
// OPENCL-NEXT: ret void
//
void test2_builtin_alloca_with_align(unsigned n) {
__private void *alloc_ptr_align = __builtin_alloca_with_align(n, 8);
}

// OPENCL-LABEL: define dso_local void @test2_builtin_alloca_with_align_uninitialized(
// OPENCL-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
// OPENCL-NEXT: [[ENTRY:.*:]]
// OPENCL-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
// OPENCL-NEXT: [[ALLOC_PTR_ALIGN_UNINITIALIZED:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// OPENCL-NEXT: store i32 [[N]], ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[N_ADDR]], align 4
// OPENCL-NEXT: [[CONV:%.*]] = zext i32 [[TMP0]] to i64
// OPENCL-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[CONV]], align 1, addrspace(5)
// OPENCL-NEXT: store ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[ALLOC_PTR_ALIGN_UNINITIALIZED]], align 4
// OPENCL-NEXT: ret void
//
void test2_builtin_alloca_with_align_uninitialized(unsigned n) {
__private void *alloc_ptr_align_uninitialized = __builtin_alloca_with_align_uninitialized(n, 8);
}
4 changes: 2 additions & 2 deletions clang/test/CodeGenOpenCL/relaxed-fpmath.cl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL
// RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST
// RUN: %clang_cc1 %s -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE
// RUN: %clang_cc1 %s -emit-llvm -menable-no-infs -menable-no-nans -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE
// RUN: %clang_cc1 %s -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE
// RUN: %clang_cc1 %s -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD
// RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED
Expand All @@ -9,7 +9,7 @@
// RUN: %clang_cc1 %s -DGEN_PCH=1 -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch
// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL
// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST
// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE
// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -menable-no-infs -menable-no-nans -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE
// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE
// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD
// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Driver/amdgpu-toolchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@
// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \
// RUN: -fuse-ld=ld %s 2>&1 | FileCheck -check-prefixes=LD %s
// LD: ld.lld

// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \
// RUN: -r %s 2>&1 | FileCheck -check-prefixes=RELO %s
// RELO-NOT: -shared
2 changes: 1 addition & 1 deletion clang/test/Driver/opencl.cl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
// CHECK-OPT-DISABLE: "-cc1" {{.*}} "-cl-opt-disable"
// CHECK-STRICT-ALIASING: "-cc1" {{.*}} "-cl-strict-aliasing"
// CHECK-SINGLE-PRECISION-CONST: "-cc1" {{.*}} "-cl-single-precision-constant"
// CHECK-FINITE-MATH-ONLY: "-cc1" {{.*}} "-cl-finite-math-only"
// CHECK-FINITE-MATH-ONLY: "-cc1" {{.*}} "-menable-no-infs" "-menable-no-nans" "-cl-finite-math-only"
// CHECK-KERNEL-ARG-INFO: "-cc1" {{.*}} "-cl-kernel-arg-info"
// CHECK-UNSAFE-MATH-OPT: "-cc1" {{.*}} "-cl-unsafe-math-optimizations"
// CHECK-FAST-RELAXED-MATH: "-cc1" {{.*}} "-cl-fast-relaxed-math"
Expand Down
1 change: 1 addition & 0 deletions clang/test/Driver/stack-size-section.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

// RUN: %clang -### --target=x86_64-linux-gnu -flto -fstack-size-section %s 2>&1 | FileCheck %s --check-prefix=LTO
// RUN: %clang -### --target=x86_64-linux-gnu -flto -fstack-size-section -fno-stack-size-section %s 2>&1 | FileCheck %s --check-prefix=LTO-NO
// RUN: %clang -### --target=x86_64-sie-ps5 -fstack-size-section %s 2>&1 | FileCheck %s --check-prefix=LTO

// LTO: "-plugin-opt=-stack-size-section"
// LTO-NO-NOT: "-plugin-opt=-stack-size-section"
Expand Down
3 changes: 2 additions & 1 deletion clang/test/Headers/__clang_hip_cmath.hip
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
// RUN: -internal-isystem %S/../../lib/Headers/cuda_wrappers \
// RUN: -internal-isystem %S/Inputs/include \
// RUN: -triple amdgcn-amd-amdhsa -aux-triple x86_64-unknown-unknown \
// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -ffinite-math-only -o - \
// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -menable-no-infs \
// RUN: -menable-no-nans -o - \
// RUN: -D__HIPCC_RTC__ | FileCheck -check-prefix=FINITEONLY %s

// DEFAULT-LABEL: @test_fma_f16(
Expand Down
3 changes: 2 additions & 1 deletion clang/test/Headers/__clang_hip_math.hip
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
// RUN: -internal-isystem %S/../../lib/Headers/cuda_wrappers \
// RUN: -internal-isystem %S/Inputs/include \
// RUN: -triple amdgcn-amd-amdhsa -aux-triple x86_64-unknown-unknown \
// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -ffinite-math-only -o - \
// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -O1 -menable-no-infs \
// RUN: -menable-no-nans -o - \
// RUN: -D__HIPCC_RTC__ | FileCheck -check-prefixes=CHECK,FINITEONLY %s

// Check that we end up with -fapprox-func set on intrinsic calls
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Headers/float.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -ffreestanding %s
// RUN: %clang_cc1 -fsyntax-only -verify=finite -std=c23 -ffreestanding -ffinite-math-only %s
// RUN: %clang_cc1 -fsyntax-only -verify=finite -std=c23 -ffreestanding -menable-no-nans -menable-no-infs %s
// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++11 -ffreestanding %s
// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++14 -ffreestanding %s
// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++17 -ffreestanding %s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
// CHECK-NEXT: HIPManaged (SubjectMatchRule_variable)
// CHECK-NEXT: HLSLResourceClass (SubjectMatchRule_record_not_is_union)
// CHECK-NEXT: Hot (SubjectMatchRule_function)
// CHECK-NEXT: HybridPatchable (SubjectMatchRule_function)
// CHECK-NEXT: IBAction (SubjectMatchRule_objc_method_is_instance)
// CHECK-NEXT: IFunc (SubjectMatchRule_function)
// CHECK-NEXT: InitPriority (SubjectMatchRule_variable)
Expand Down
59 changes: 59 additions & 0 deletions clang/test/OpenMP/amdgpu-unsafe-fp-atomics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -o - | FileCheck -check-prefix=DEFAULT %s
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -munsafe-fp-atomics -emit-llvm %s -fopenmp-is-target-device -o - | FileCheck -check-prefix=UNSAFE-FP-ATOMICS %s

#pragma omp declare target

float fv, fx;
double dv, dx;

// DEFAULT-LABEL: define hidden void @_Z15atomic_fadd_f32v(
// DEFAULT-SAME: ) #[[ATTR0:[0-9]+]] {
// DEFAULT-NEXT: [[ENTRY:.*:]]
// DEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4
// DEFAULT-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @fx to ptr), float [[TMP0]] monotonic, align 4
// DEFAULT-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP0]]
// DEFAULT-NEXT: store float [[ADD]], ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4
// DEFAULT-NEXT: ret void
//
// UNSAFE-FP-ATOMICS-LABEL: define hidden void @_Z15atomic_fadd_f32v(
// UNSAFE-FP-ATOMICS-SAME: ) #[[ATTR0:[0-9]+]] {
// UNSAFE-FP-ATOMICS-NEXT: [[ENTRY:.*:]]
// UNSAFE-FP-ATOMICS-NEXT: [[TMP0:%.*]] = load float, ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4
// UNSAFE-FP-ATOMICS-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @fx to ptr), float [[TMP0]] monotonic, align 4, !amdgpu.no.fine.grained.memory [[META5:![0-9]+]], !amdgpu.ignore.denormal.mode [[META5]]
// UNSAFE-FP-ATOMICS-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP0]]
// UNSAFE-FP-ATOMICS-NEXT: store float [[ADD]], ptr addrspacecast (ptr addrspace(1) @fv to ptr), align 4
// UNSAFE-FP-ATOMICS-NEXT: ret void
//
void atomic_fadd_f32() {
#pragma omp atomic capture
fv = fx = fx + fv;
}

// DEFAULT-LABEL: define hidden void @_Z15atomic_fadd_f64v(
// DEFAULT-SAME: ) #[[ATTR0]] {
// DEFAULT-NEXT: [[ENTRY:.*:]]
// DEFAULT-NEXT: [[TMP0:%.*]] = load double, ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8
// DEFAULT-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @dx to ptr), double [[TMP0]] monotonic, align 8
// DEFAULT-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[TMP0]]
// DEFAULT-NEXT: store double [[ADD]], ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8
// DEFAULT-NEXT: ret void
//
// UNSAFE-FP-ATOMICS-LABEL: define hidden void @_Z15atomic_fadd_f64v(
// UNSAFE-FP-ATOMICS-SAME: ) #[[ATTR0]] {
// UNSAFE-FP-ATOMICS-NEXT: [[ENTRY:.*:]]
// UNSAFE-FP-ATOMICS-NEXT: [[TMP0:%.*]] = load double, ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8
// UNSAFE-FP-ATOMICS-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @dx to ptr), double [[TMP0]] monotonic, align 8, !amdgpu.no.fine.grained.memory [[META5]]
// UNSAFE-FP-ATOMICS-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[TMP0]]
// UNSAFE-FP-ATOMICS-NEXT: store double [[ADD]], ptr addrspacecast (ptr addrspace(1) @dv to ptr), align 8
// UNSAFE-FP-ATOMICS-NEXT: ret void
//
void atomic_fadd_f64() {
#pragma omp atomic capture
dv = dx = dx + dv;
}

#pragma omp end declare target
//.
// UNSAFE-FP-ATOMICS: [[META5]] = !{}
//.
Loading