28 changes: 10 additions & 18 deletions clang/bindings/python/tests/cindex/test_translation_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from contextlib import contextmanager
import gc
import os
import sys
import tempfile
import unittest
from pathlib import Path

from clang.cindex import CursorKind
from clang.cindex import Cursor
Expand All @@ -22,8 +22,6 @@
from clang.cindex import TranslationUnit
from .util import get_cursor
from .util import get_tu
from .util import skip_if_no_fspath
from .util import str_to_path


kInputsDir = os.path.join(os.path.dirname(__file__), "INPUTS")
Expand All @@ -47,7 +45,7 @@ def save_tu_pathlike(tu):
Returns the filename it was saved to.
"""
with tempfile.NamedTemporaryFile() as t:
tu.save(str_to_path(t.name))
tu.save(Path(t.name))
yield t.name


Expand Down Expand Up @@ -105,32 +103,29 @@ def test_unsaved_files(self):
self.assertEqual(spellings[-1], "y")

def test_unsaved_files_2(self):
if sys.version_info.major >= 3:
from io import StringIO
else:
from io import BytesIO as StringIO
from io import StringIO

tu = TranslationUnit.from_source(
"fake.c", unsaved_files=[("fake.c", StringIO("int x;"))]
)
spellings = [c.spelling for c in tu.cursor.get_children()]
self.assertEqual(spellings[-1], "x")

@skip_if_no_fspath
def test_from_source_accepts_pathlike(self):
tu = TranslationUnit.from_source(
str_to_path("fake.c"),
Path("fake.c"),
["-Iincludes"],
unsaved_files=[
(
str_to_path("fake.c"),
Path("fake.c"),
"""
#include "fake.h"
int x;
int SOME_DEFINE;
""",
),
(
str_to_path("includes/fake.h"),
Path("includes/fake.h"),
"""
#define SOME_DEFINE y
""",
Expand Down Expand Up @@ -192,7 +187,6 @@ def test_save(self):
self.assertTrue(os.path.exists(path))
self.assertGreater(os.path.getsize(path), 0)

@skip_if_no_fspath
def test_save_pathlike(self):
"""Ensure TranslationUnit.save() works with PathLike filename."""

Expand Down Expand Up @@ -234,14 +228,13 @@ def test_load(self):
# Just in case there is an open file descriptor somewhere.
del tu2

@skip_if_no_fspath
def test_load_pathlike(self):
"""Ensure TranslationUnits can be constructed from saved files -
PathLike variant."""
tu = get_tu("int foo();")
self.assertEqual(len(tu.diagnostics), 0)
with save_tu(tu) as path:
tu2 = TranslationUnit.from_ast_file(filename=str_to_path(path))
tu2 = TranslationUnit.from_ast_file(filename=Path(path))
self.assertEqual(len(tu2.diagnostics), 0)

foo = get_cursor(tu2, "foo")
Expand All @@ -268,18 +261,17 @@ def test_get_file(self):
with self.assertRaises(Exception):
f = tu.get_file("foobar.cpp")

@skip_if_no_fspath
def test_get_file_pathlike(self):
"""Ensure tu.get_file() works appropriately with PathLike filenames."""

tu = get_tu("int foo();")

f = tu.get_file(str_to_path("t.c"))
f = tu.get_file(Path("t.c"))
self.assertIsInstance(f, File)
self.assertEqual(f.name, "t.c")

with self.assertRaises(Exception):
f = tu.get_file(str_to_path("foobar.cpp"))
f = tu.get_file(Path("foobar.cpp"))

def test_get_source_location(self):
"""Ensure tu.get_source_location() works."""
Expand Down
6 changes: 3 additions & 3 deletions clang/bindings/python/tests/cindex/test_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def test_references(self):
self.assertIsInstance(t.translation_unit, TranslationUnit)

# If the TU was destroyed, this should cause a segfault.
decl = t.get_declaration()
t.get_declaration()

def testConstantArray(self):
tu = get_tu(constarrayInput)
Expand Down Expand Up @@ -459,8 +459,8 @@ def test_offset(self):
(["-target", "i386-pc-win32"], (8, 16, 0, 32, 64, 96)),
(["-target", "msp430-none-none"], (2, 14, 0, 32, 64, 96)),
]
for flags, values in tries:
align, total, f1, bariton, foo, bar = values
for _, values in tries:
_, _, f1, bariton, foo, bar = values
tu = get_tu(source)
teststruct = get_cursor(tu, "Test")
children = list(teststruct.get_children())
Expand Down
17 changes: 0 additions & 17 deletions clang/bindings/python/tests/cindex/util.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
# This file provides common utility functions for the test suite.

import os

HAS_FSPATH = hasattr(os, "fspath")

if HAS_FSPATH:
from pathlib import Path as str_to_path
else:
str_to_path = None

import unittest

from clang.cindex import Cursor
from clang.cindex import TranslationUnit

Expand Down Expand Up @@ -81,14 +70,8 @@ def get_cursors(source, spelling):
return cursors


skip_if_no_fspath = unittest.skipUnless(
HAS_FSPATH, "Requires file system path protocol / Python 3.6+"
)

__all__ = [
"get_cursor",
"get_cursors",
"get_tu",
"skip_if_no_fspath",
"str_to_path",
]
5 changes: 0 additions & 5 deletions clang/docs/ClangFormat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,3 @@ those as well).

These commands use the file paths shown in the diff output
so they will only work from the root of the repository.

Current State of Clang Format for LLVM
======================================

The following table :doc:`ClangFormattedStatus` shows the current status of clang-formatting for the entire LLVM source tree.
3 changes: 0 additions & 3 deletions clang/docs/ClangLinkerWrapper.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ only for the linker wrapper will be forwarded to the wrapped linker job.
USAGE: clang-linker-wrapper [options] -- <options to passed to the linker>
OPTIONS:
--bitcode-library=<kind>-<triple>-<arch>=<path>
Extra bitcode library to link
--cuda-path=<dir> Set the system CUDA path
--device-debug Use debugging
--device-linker=<value> or <triple>=<value>
Arguments to pass to the device linker invocation
--dry-run Print program arguments without running
--embed-bitcode Embed linked bitcode in the module
--help-hidden Display all available options
--help Display available options (--help-hidden for more)
--host-triple=<triple> Triple to use for the host compilation
Expand Down
82 changes: 82 additions & 0 deletions clang/docs/ClangSYCLLinker.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
=======================
Clang SYCL Linker
=======================

.. contents::
:local:

.. _clang-sycl-linker:

Introduction
============

This tool works as a wrapper around the SYCL device code linking process.
The purpose of this tool is to provide an interface to link SYCL device bitcode
in LLVM IR format, SYCL device bitcode in SPIR-V IR format, and native binary
objects, and then use the SPIR-V LLVM Translator tool on fully linked device
objects to produce the final output.
After the linking stage, the fully linked device code in LLVM IR format may
undergo several SYCL-specific finalization steps before the SPIR-V code
generation step.
The tool will also support the Ahead-Of-Time (AOT) compilation flow. AOT
compilation is the process of invoking the back-end at compile time to produce
the final binary, as opposed to just-in-time (JIT) compilation when final code
generation is deferred until application runtime.

Device code linking for SYCL offloading has several known quirks that
make it difficult to use in a unified offloading setting. Two of the primary
issues are:
1. Several finalization steps are required to be run on the fully linked LLVM
IR bitcode to guarantee conformance to SYCL standards. This step is unique to
the SYCL offloading compilation flow.
2. The SPIR-V LLVM Translator tool is an external tool and hence SPIR-V IR code
generation cannot be done as part of LTO. This limitation can be lifted once
the SPIR-V backend is available as a viable LLVM backend.

This tool has been proposed to work around these issues.

Usage
=====

This tool can be used with the following options. Several of these options will
be passed down to downstream tools like 'llvm-link', 'llvm-spirv', etc.

.. code-block:: console
OVERVIEW: A utility that wraps around the SYCL device code linking process.
This enables linking and code generation for SPIR-V JIT targets and AOT
targets.
USAGE: clang-sycl-linker [options]
OPTIONS:
--arch <value> Specify the name of the target architecture.
--dry-run Print generated commands without running.
-g Specify that this was a debug compile.
-help-hidden Display all available options
-help Display available options (--help-hidden for more)
--library-path=<dir> Set the library path for SYCL device libraries
--device-libs=<value> A comma separated list of device libraries that are linked during the device link
-o <path> Path to file to write output
--save-temps Save intermediate results
--triple <value> Specify the target triple.
--version Display the version number and exit
-v Print verbose information
-spirv-dump-device-code=<dir> Directory to dump SPIR-V IR code into
-is-windows-msvc-env Specify if we are compiling under windows environment
-llvm-spirv-options=<value> Pass options to llvm-spirv tool
--llvm-spirv-path=<dir> Set the system llvm-spirv path
Example
=======

This tool is intended to be invoked when targeting any of the target offloading
toolchains. When the --sycl-link option is passed to the clang driver, the
driver will invoke the linking job of the target offloading toolchain, which in
turn will invoke this tool. This tool can be used to create one or more fully
linked device images that are ready to be wrapped and linked with host code to
generate the final executable.

.. code-block:: console
clang-sycl-linker --triple spirv64 --arch native input.bc
4 changes: 2 additions & 2 deletions clang/docs/RealtimeSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ projects. RTSan can be used to detect real-time violations, i.e. calls to method
that are not safe for use in functions with deterministic run time requirements.
RTSan considers any function marked with the ``[[clang::nonblocking]]`` attribute
to be a real-time function. At run-time, if RTSan detects a call to ``malloc``,
``free``, ``pthread_mutex_lock``, or anything else that could have a
``free``, ``pthread_mutex_lock``, or anything else known to have a
non-deterministic execution time in a function marked ``[[clang::nonblocking]]``
RTSan raises an error.
it raises an error.

RTSan performs its analysis at run-time but shares the ``[[clang::nonblocking]]``
attribute with the :doc:`FunctionEffectAnalysis` system, which operates at
Expand Down
14 changes: 14 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,19 @@ Removed Compiler Flags
Attribute Changes in Clang
--------------------------

- The ``swift_attr`` can now be applied to types. To make it possible to use imported APIs
in Swift safely there has to be a way to annotate individual parameters and result types
with relevant attributes that indicate that e.g. a block is called on a particular actor
or it accepts a Sendable or global-actor (i.e. ``@MainActor``) isolated parameter.

For example:

.. code-block:: objc
@interface MyService
-(void) handle: (void (^ __attribute__((swift_attr("@Sendable"))))(id)) handler;
@end
- Clang now disallows more than one ``__attribute__((ownership_returns(class, idx)))`` with
different class names attached to one function.

Expand Down Expand Up @@ -661,6 +674,7 @@ X86 Support

- Supported intrinsics for ``MOVRS AND AVX10.2``.
* Supported intrinsics of ``_mm(256|512)_(mask(z))_loadrs_epi(8|16|32|64)``.
- Support ISA of ``AMX-FP8``.

Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
1 change: 1 addition & 0 deletions clang/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ Using Clang Tools
ClangOffloadBundler
ClangOffloadPackager
ClangRepl
ClangSYCLLinker

Design Documents
================
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1719,8 +1719,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;

QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
QualType equivalentType,
const Attr *attr = nullptr) const;

QualType getAttributedType(const Attr *attr, QualType modifiedType,
QualType equivalentType) const;

QualType getAttributedType(NullabilityKind nullability, QualType modifiedType,
QualType equivalentType);

QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
QualType Wrapped) const;

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/PropertiesBase.td
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def APValue : PropertyType { let PassByReference = 1; }
def APValueKind : EnumPropertyType<"APValue::ValueKind">;
def ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">;
def AttrKind : EnumPropertyType<"attr::Kind">;
def Attr : PropertyType<"const Attr *">;
def AutoTypeKeyword : EnumPropertyType;
def Bool : PropertyType<"bool">;
def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
Expand Down
42 changes: 17 additions & 25 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class ValueDecl;
class TagDecl;
class TemplateParameterList;
class Type;
class Attr;

enum {
TypeAlignmentInBits = 4,
Expand Down Expand Up @@ -6130,21 +6131,29 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
private:
friend class ASTContext; // ASTContext creates these

const Attr *Attribute;

QualType ModifiedType;
QualType EquivalentType;

AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
QualType equivalent)
: Type(Attributed, canon, equivalent->getDependence()),
ModifiedType(modified), EquivalentType(equivalent) {
AttributedTypeBits.AttrKind = attrKind;
}
: AttributedType(canon, attrKind, nullptr, modified, equivalent) {}

AttributedType(QualType canon, const Attr *attr, QualType modified,
QualType equivalent);

private:
AttributedType(QualType canon, attr::Kind attrKind, const Attr *attr,
QualType modified, QualType equivalent);

public:
Kind getAttrKind() const {
return static_cast<Kind>(AttributedTypeBits.AttrKind);
}

const Attr *getAttr() const { return Attribute; }

QualType getModifiedType() const { return ModifiedType; }
QualType getEquivalentType() const { return EquivalentType; }

Expand Down Expand Up @@ -6176,25 +6185,6 @@ class AttributedType : public Type, public llvm::FoldingSetNode {

std::optional<NullabilityKind> getImmediateNullability() const;

/// Retrieve the attribute kind corresponding to the given
/// nullability kind.
static Kind getNullabilityAttrKind(NullabilityKind kind) {
switch (kind) {
case NullabilityKind::NonNull:
return attr::TypeNonNull;

case NullabilityKind::Nullable:
return attr::TypeNullable;

case NullabilityKind::NullableResult:
return attr::TypeNullableResult;

case NullabilityKind::Unspecified:
return attr::TypeNullUnspecified;
}
llvm_unreachable("Unknown nullability kind.");
}

/// Strip off the top-level nullability annotation on the given
/// type, if it's there.
///
Expand All @@ -6207,14 +6197,16 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
static std::optional<NullabilityKind> stripOuterNullability(QualType &T);

void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
Profile(ID, getAttrKind(), ModifiedType, EquivalentType, Attribute);
}

static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
QualType modified, QualType equivalent) {
QualType modified, QualType equivalent,
const Attr *attr) {
ID.AddInteger(attrKind);
ID.AddPointer(modified.getAsOpaquePtr());
ID.AddPointer(equivalent.getAsOpaquePtr());
ID.AddPointer(attr);
}

static bool classof(const Type *T) {
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -668,12 +668,16 @@ let Class = AttributedType in {
def : Property<"equivalentType", QualType> {
let Read = [{ node->getEquivalentType() }];
}
def : Property<"attribute", AttrKind> {
def : Property<"attrKind", AttrKind> {
let Read = [{ node->getAttrKind() }];
}
def : Property<"attribute", Attr> {
let Read = [{ node->getAttr() }];
}

def : Creator<[{
return ctx.getAttributedType(attribute, modifiedType, equivalentType);
return ctx.getAttributedType(attrKind, modifiedType,
equivalentType, attribute);
}]>;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -2838,7 +2838,7 @@ def SwiftAsyncName : InheritableAttr {
let Documentation = [SwiftAsyncNameDocs];
}

def SwiftAttr : InheritableAttr {
def SwiftAttr : DeclOrTypeAttr {
let Spellings = [GNU<"swift_attr">];
let Args = [StringArgument<"Attribute">];
let Documentation = [SwiftAttrDocs];
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -4507,8 +4507,8 @@ def SwiftAttrDocs : Documentation {
let Heading = "swift_attr";
let Content = [{
The ``swift_attr`` provides a Swift-specific annotation for the declaration
to which the attribute appertains to. It can be used on any declaration
in Clang. This kind of annotation is ignored by Clang as it doesn't have any
or type to which the attribute appertains to. It can be used on any declaration
or type in Clang. This kind of annotation is ignored by Clang as it doesn't have any
semantic meaning in languages supported by Clang. The Swift compiler can
interpret these annotations according to its own rules when importing C or
Objective-C declarations.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/BuiltinsAMDGPU.def
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_bf8, "fUiUif", "nc", "dot11-insts")
//===----------------------------------------------------------------------===//
TARGET_BUILTIN(__builtin_amdgcn_permlane16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_permlanex16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp8, "UiUiIUi", "nc", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp8, "UiUiIUi", "nct", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_ttracedata_imm, "vIs", "n", "gfx10-insts")

//===----------------------------------------------------------------------===//
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/BuiltinsX86_64.def
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ TARGET_BUILTIN(__builtin_ia32_cmpccxadd64, "SLLiv*SLLiSLLiIi", "n", "cmpccxadd")
// AMX_FP16 FP16
TARGET_BUILTIN(__builtin_ia32_tdpfp16ps, "vIUcIUcIUc", "n", "amx-fp16")

// AMX FP8
TARGET_BUILTIN(__builtin_ia32_tdpbf8ps, "vIUcUIcUIc", "n", "amx-fp8")
TARGET_BUILTIN(__builtin_ia32_tdpbhf8ps, "vIUcUIcUIc", "n", "amx-fp8")
TARGET_BUILTIN(__builtin_ia32_tdphbf8ps, "vIUcUIcUIc", "n", "amx-fp8")
TARGET_BUILTIN(__builtin_ia32_tdphf8ps, "vIUcUIcUIc", "n", "amx-fp8")

// RAO-INT
TARGET_BUILTIN(__builtin_ia32_aadd64, "vv*SOi", "n", "raoint")
TARGET_BUILTIN(__builtin_ia32_aand64, "vv*SOi", "n", "raoint")
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")

LANGOPT(XLPragmaPack, 1, 0, "IBM XL #pragma pack handling")

LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
COMPATIBLE_LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")

LANGOPT(APINotes, 1, 0, "use external API notes")
LANGOPT(APINotesModules, 1, 0, "use module-based external API notes")
Expand Down
13 changes: 6 additions & 7 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1786,12 +1786,6 @@ defm debug_info_for_profiling : BoolFOption<"debug-info-for-profiling",
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Emit extra debug info to make sample profile more accurate">,
NegFlag<SetFalse>>;
def fprofile_generate_cold_function_coverage : Flag<["-"], "fprofile-generate-cold-function-coverage">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect coverage info for cold functions into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def fprofile_generate_cold_function_coverage_EQ : Joined<["-"], "fprofile-generate-cold-function-coverage=">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>, MetaVarName<"<directory>">,
HelpText<"Generate instrumented code to collect coverage info for cold functions into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
Expand Down Expand Up @@ -6300,6 +6294,8 @@ def mamx_fp16 : Flag<["-"], "mamx-fp16">, Group<m_x86_Features_Group>;
def mno_amx_fp16 : Flag<["-"], "mno-amx-fp16">, Group<m_x86_Features_Group>;
def mamx_int8 : Flag<["-"], "mamx-int8">, Group<m_x86_Features_Group>;
def mno_amx_int8 : Flag<["-"], "mno-amx-int8">, Group<m_x86_Features_Group>;
def mamx_fp8 : Flag<["-"], "mamx-fp8">, Group<m_x86_Features_Group>;
def mno_amx_fp8 : Flag<["-"], "mno-amx-fp8">, Group<m_x86_Features_Group>;
def mamx_tile : Flag<["-"], "mamx-tile">, Group<m_x86_Features_Group>;
def mno_amx_tile : Flag<["-"], "mno-amx-tile">, Group<m_x86_Features_Group>;
def mcmpccxadd : Flag<["-"], "mcmpccxadd">, Group<m_x86_Features_Group>;
Expand Down Expand Up @@ -6779,7 +6775,10 @@ def fsycl : Flag<["-"], "fsycl">,
def fno_sycl : Flag<["-"], "fno-sycl">,
Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Disables SYCL kernels compilation for device">;

def sycl_link : Flag<["--"], "sycl-link">, Flags<[HelpHidden]>,
Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Perform link through clang-sycl-linker via the target "
"offloading toolchain.">;
// OS-specific options
let Flags = [TargetSpecific] in {
defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/SemaAMDGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class SemaAMDGPU : public SemaBase {

bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);

bool checkMovDPPFunctionCall(CallExpr *TheCall, unsigned NumArgs,
unsigned NumDataArgs);

/// Create an AMDGPUWavesPerEUAttr attribute.
AMDGPUFlatWorkGroupSizeAttr *
CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min,
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Sema/SemaObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,10 @@ class SemaObjC : public SemaBase {
ParsedAttributesView ArgAttrs;
};

ParmVarDecl *ActOnMethodParmDeclaration(Scope *S, ObjCArgInfo &ArgInfo,
int ParamIndex,
bool MethodDefinition);

Decl *ActOnMethodDeclaration(
Scope *S,
SourceLocation BeginLoc, // location of the + or -.
Expand All @@ -359,7 +363,7 @@ class SemaObjC : public SemaBase {
ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
unsigned CNumArgs, // c-style args
const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind,
bool isVariadic, bool MethodDefinition);
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class ASTRecordWriter
AddStmt(const_cast<Stmt*>(S));
}

void writeAttr(const Attr *A) { AddAttr(A); }

/// Write an BTFTypeTagAttr object.
void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }

Expand Down
48 changes: 40 additions & 8 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3552,7 +3552,8 @@ ASTContext::adjustType(QualType Orig,
const auto *AT = dyn_cast<AttributedType>(Orig);
return getAttributedType(AT->getAttrKind(),
adjustType(AT->getModifiedType(), Adjust),
adjustType(AT->getEquivalentType(), Adjust));
adjustType(AT->getEquivalentType(), Adjust),
AT->getAttr());
}

case Type::BTFTagAttributed: {
Expand Down Expand Up @@ -5197,24 +5198,54 @@ QualType ASTContext::getUnresolvedUsingType(

QualType ASTContext::getAttributedType(attr::Kind attrKind,
QualType modifiedType,
QualType equivalentType) const {
QualType equivalentType,
const Attr *attr) const {
llvm::FoldingSetNodeID id;
AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
AttributedType::Profile(id, attrKind, modifiedType, equivalentType, attr);

void *insertPos = nullptr;
AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
if (type) return QualType(type, 0);

assert(!attr || attr->getKind() == attrKind);

QualType canon = getCanonicalType(equivalentType);
type = new (*this, alignof(AttributedType))
AttributedType(canon, attrKind, modifiedType, equivalentType);
type = new (*this, alignof(AttributedType))
AttributedType(canon, attrKind, attr, modifiedType, equivalentType);

Types.push_back(type);
AttributedTypes.InsertNode(type, insertPos);

return QualType(type, 0);
}

QualType ASTContext::getAttributedType(const Attr *attr, QualType modifiedType,
QualType equivalentType) const {
return getAttributedType(attr->getKind(), modifiedType, equivalentType, attr);
}

QualType ASTContext::getAttributedType(NullabilityKind nullability,
QualType modifiedType,
QualType equivalentType) {
switch (nullability) {
case NullabilityKind::NonNull:
return getAttributedType(attr::TypeNonNull, modifiedType, equivalentType);

case NullabilityKind::Nullable:
return getAttributedType(attr::TypeNullable, modifiedType, equivalentType);

case NullabilityKind::NullableResult:
return getAttributedType(attr::TypeNullableResult, modifiedType,
equivalentType);

case NullabilityKind::Unspecified:
return getAttributedType(attr::TypeNullUnspecified, modifiedType,
equivalentType);
}

llvm_unreachable("Unknown nullability kind");
}

QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
QualType Wrapped) const {
llvm::FoldingSetNodeID ID;
Expand Down Expand Up @@ -7537,8 +7568,8 @@ QualType ASTContext::getArrayDecayedType(QualType Ty) const {

// int x[_Nullable] -> int * _Nullable
if (auto Nullability = Ty->getNullability()) {
Result = const_cast<ASTContext *>(this)->getAttributedType(
AttributedType::getNullabilityAttrKind(*Nullability), Result, Result);
Result = const_cast<ASTContext *>(this)->getAttributedType(*Nullability,
Result, Result);
}
return Result;
}
Expand Down Expand Up @@ -13773,7 +13804,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
return QualType();
// FIXME: It's inefficient to have to unify the modified types.
return Ctx.getAttributedType(Kind, Ctx.getCommonSugaredType(MX, MY),
Ctx.getQualifiedType(Underlying));
Ctx.getQualifiedType(Underlying),
AX->getAttr());
}
case Type::BTFTagAttributed: {
const auto *BX = cast<BTFTagAttributedType>(X);
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/AST/ASTDiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
QualType SugarRT = FT->getReturnType();
QualType RT = desugarForDiagnostic(Context, SugarRT, DesugarReturn);
if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
RT = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*nullability), RT, RT);
RT = Context.getAttributedType(*nullability, RT, RT);
}

bool DesugarArgument = false;
Expand All @@ -97,8 +96,7 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
QualType PT = desugarForDiagnostic(Context, SugarPT, DesugarArgument);
if (auto nullability =
AttributedType::stripOuterNullability(SugarPT)) {
PT = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*nullability), PT, PT);
PT = Context.getAttributedType(*nullability, PT, PT);
}
Args.push_back(PT);
}
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1580,8 +1580,9 @@ ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
if (!ToEquivalentTypeOrErr)
return ToEquivalentTypeOrErr.takeError();

return Importer.getToContext().getAttributedType(T->getAttrKind(),
*ToModifiedTypeOrErr, *ToEquivalentTypeOrErr);
return Importer.getToContext().getAttributedType(
T->getAttrKind(), *ToModifiedTypeOrErr, *ToEquivalentTypeOrErr,
T->getAttr());
}

ExpectedType
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/AST/ByteCode/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,16 @@ QualType Descriptor::getElemQualType() const {
QualType T = getType();
if (T->isPointerOrReferenceType())
return T->getPointeeType();
if (const auto *AT = T->getAsArrayTypeUnsafe())
if (const auto *AT = T->getAsArrayTypeUnsafe()) {
// For primitive arrays, we don't save a QualType at all,
// just a PrimType. Try to figure out the QualType here.
if (isPrimitiveArray()) {
while (T->isArrayType())
T = T->getAsArrayTypeUnsafe()->getElementType();
return T;
}
return AT->getElementType();
}
if (const auto *CT = T->getAs<ComplexType>())
return CT->getElementType();
if (const auto *CT = T->getAs<VectorType>())
Expand Down
18 changes: 18 additions & 0 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,13 @@ static bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
return runRecordDestructor(S, OpPC, Pointer(const_cast<Block *>(B)), Desc);
}

static bool hasVirtualDestructor(QualType T) {
if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
if (const CXXDestructorDecl *DD = RD->getDestructor())
return DD->isVirtual();
return false;
}

bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
bool IsGlobalDelete) {
if (!CheckDynamicMemoryAllocation(S, OpPC))
Expand All @@ -1019,9 +1026,20 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
return true;

// Remove base casts.
QualType InitialType = Ptr.getType();
while (Ptr.isBaseClass())
Ptr = Ptr.getBase();

// For the non-array case, the types must match if the static type
// does not have a virtual destructor.
if (!DeleteIsArrayForm && Ptr.getType() != InitialType &&
!hasVirtualDestructor(InitialType)) {
S.FFDiag(S.Current->getSource(OpPC),
diag::note_constexpr_delete_base_nonvirt_dtor)
<< InitialType << Ptr.getType();
return false;
}

if (!Ptr.isRoot() || Ptr.isOnePastEnd() || Ptr.isArrayElement()) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_delete_subobject)
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/AST/ByteCode/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,14 @@ bool CheckArraySize(InterpState &S, CodePtr OpPC, SizeT *NumElements,
*NumElements > MaxElements) {
if (!IsNoThrow) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_new_too_large)
<< NumElements->toDiagnosticString(S.getASTContext());

if (NumElements->isSigned() && NumElements->isNegative()) {
S.FFDiag(Loc, diag::note_constexpr_new_negative)
<< NumElements->toDiagnosticString(S.getASTContext());
} else {
S.FFDiag(Loc, diag::note_constexpr_new_too_large)
<< NumElements->toDiagnosticString(S.getASTContext());
}
}
return false;
}
Expand Down
24 changes: 17 additions & 7 deletions clang/lib/AST/ByteCode/Pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,26 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
// Build the path into the object.
Pointer Ptr = *this;
while (Ptr.isField() || Ptr.isArrayElement()) {

if (Ptr.isArrayRoot()) {
Path.push_back(APValue::LValuePathEntry(
{Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false}));
// An array root may still be an array element itself.
if (Ptr.isArrayElement()) {
Ptr = Ptr.expand();
unsigned Index = Ptr.getIndex();
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
QualType ElemType = Ptr.getFieldDesc()->getElemQualType();
Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));
Ptr = Ptr.getArray();
} else {
Path.push_back(APValue::LValuePathEntry(
{Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false}));

if (const auto *FD =
dyn_cast_if_present<FieldDecl>(Ptr.getFieldDesc()->asDecl()))
Offset += getFieldOffset(FD);
if (const auto *FD =
dyn_cast_if_present<FieldDecl>(Ptr.getFieldDesc()->asDecl()))
Offset += getFieldOffset(FD);

Ptr = Ptr.getBase();
Ptr = Ptr.getBase();
}
} else if (Ptr.isArrayElement()) {
Ptr = Ptr.expand();
unsigned Index;
Expand All @@ -219,7 +230,6 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {

QualType ElemType = Ptr.getFieldDesc()->getElemQualType();
Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));

Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
Ptr = Ptr.getArray();
} else {
Expand Down
20 changes: 17 additions & 3 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1241,8 +1241,8 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
== T->getEquivalentType().getAsOpaquePtr())
return QualType(T, 0);

return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
equivalentType);
return Ctx.getAttributedType(T->getAttrKind(), modifiedType, equivalentType,
T->getAttr());
}

QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
Expand Down Expand Up @@ -1545,7 +1545,8 @@ struct SubstObjCTypeArgsVisitor

// Rebuild the attributed type.
return Ctx.getAttributedType(newAttrType->getAttrKind(),
newAttrType->getModifiedType(), newEquivType);
newAttrType->getModifiedType(), newEquivType,
newAttrType->getAttr());
}
};

Expand Down Expand Up @@ -4115,6 +4116,19 @@ bool RecordType::hasConstFields() const {
return false;
}

AttributedType::AttributedType(QualType canon, const Attr *attr,
QualType modified, QualType equivalent)
: AttributedType(canon, attr->getKind(), attr, modified, equivalent) {}

AttributedType::AttributedType(QualType canon, attr::Kind attrKind,
const Attr *attr, QualType modified,
QualType equivalent)
: Type(Attributed, canon, equivalent->getDependence()), Attribute(attr),
ModifiedType(modified), EquivalentType(equivalent) {
AttributedTypeBits.AttrKind = attrKind;
assert(!attr || attr->getKind() == attrKind);
}

bool AttributedType::isQualifier() const {
// FIXME: Generate this with TableGen.
switch (getAttrKind()) {
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1934,6 +1934,14 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
return;
}

if (T->getAttrKind() == attr::SwiftAttr) {
if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
<< "\")))";
}
return;
}

OS << " __attribute__((";
switch (T->getAttrKind()) {
#define TYPE_ATTR(NAME)
Expand Down Expand Up @@ -1994,6 +2002,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::NonAllocating:
case attr::Blocking:
case attr::Allocating:
case attr::SwiftAttr:
llvm_unreachable("This attribute should have been handled already");

case attr::NSReturnsRetained:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1714,7 +1714,7 @@ void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
if (Triple.isArm64e())
Builder.defineMacro("__arm64e__", "1");

getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
DarwinTargetInfo<AArch64leTargetInfo>::getOSDefines(Opts, Triple, Builder);
}

TargetInfo::BuiltinVaListKind
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Basic/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasAMXTILE = true;
} else if (Feature == "+amx-complex") {
HasAMXCOMPLEX = true;
} else if (Feature == "+amx-fp8") {
HasAMXFP8 = true;
} else if (Feature == "+cmpccxadd") {
HasCMPCCXADD = true;
} else if (Feature == "+raoint") {
Expand Down Expand Up @@ -947,6 +949,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__AMX_FP16__");
if (HasAMXCOMPLEX)
Builder.defineMacro("__AMX_COMPLEX__");
if (HasAMXFP8)
Builder.defineMacro("__AMX_FP8__");
if (HasCMPCCXADD)
Builder.defineMacro("__CMPCCXADD__");
if (HasRAOINT)
Expand Down Expand Up @@ -1077,6 +1081,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("amx-fp16", true)
.Case("amx-int8", true)
.Case("amx-tile", true)
.Case("amx-fp8", true)
.Case("avx", true)
.Case("avx10.1-256", true)
.Case("avx10.1-512", true)
Expand Down Expand Up @@ -1195,6 +1200,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("amx-fp16", HasAMXFP16)
.Case("amx-int8", HasAMXINT8)
.Case("amx-tile", HasAMXTILE)
.Case("amx-fp8", HasAMXFP8)
.Case("avx", SSELevel >= AVX)
.Case("avx10.1-256", HasAVX10_1)
.Case("avx10.1-512", HasAVX10_1_512)
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasAMXINT8 = false;
bool HasAMXBF16 = false;
bool HasAMXCOMPLEX = false;
bool HasAMXFP8 = false;
bool HasSERIALIZE = false;
bool HasTSXLDTRK = false;
bool HasUSERMSR = false;
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,9 +1013,10 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
if (IsThinLTOPostLink)
PB.registerPipelineStartEPCallback(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
/*ImportSummary=*/nullptr,
/*DropTypeTests=*/true));
MPM.addPass(LowerTypeTestsPass(
/*ExportSummary=*/nullptr,
/*ImportSummary=*/nullptr,
/*DropTypeTests=*/lowertypetests::DropTestKind::Assume));
});

// Register callbacks to schedule sanitizer passes at the appropriate part
Expand Down
16 changes: 10 additions & 6 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19115,8 +19115,6 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
return emitBuiltinWithOneOverloadedType<2>(*this, E,
Intrinsic::amdgcn_ds_swizzle);
case AMDGPU::BI__builtin_amdgcn_mov_dpp8:
return emitBuiltinWithOneOverloadedType<2>(*this, E,
Intrinsic::amdgcn_mov_dpp8);
case AMDGPU::BI__builtin_amdgcn_mov_dpp:
case AMDGPU::BI__builtin_amdgcn_update_dpp: {
llvm::SmallVector<llvm::Value *, 6> Args;
Expand All @@ -19130,14 +19128,20 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
unsigned Size = DataTy->getPrimitiveSizeInBits();
llvm::Type *IntTy =
llvm::IntegerType::get(Builder.getContext(), std::max(Size, 32u));
Function *F = CGM.getIntrinsic(Intrinsic::amdgcn_update_dpp, IntTy);
assert(E->getNumArgs() == 5 || E->getNumArgs() == 6);
bool InsertOld = E->getNumArgs() == 5;
Function *F =
CGM.getIntrinsic(BuiltinID == AMDGPU::BI__builtin_amdgcn_mov_dpp8
? Intrinsic::amdgcn_mov_dpp8
: Intrinsic::amdgcn_update_dpp,
IntTy);
assert(E->getNumArgs() == 5 || E->getNumArgs() == 6 ||
E->getNumArgs() == 2);
bool InsertOld = BuiltinID == AMDGPU::BI__builtin_amdgcn_mov_dpp;
if (InsertOld)
Args.push_back(llvm::PoisonValue::get(IntTy));
for (unsigned I = 0; I != E->getNumArgs(); ++I) {
llvm::Value *V = EmitScalarOrConstFoldImmArg(ICEArguments, I, E);
if (I <= (InsertOld ? 0u : 1u) && Size < 32) {
if (I < (BuiltinID == AMDGPU::BI__builtin_amdgcn_update_dpp ? 2u : 1u) &&
Size < 32) {
if (!DataTy->isIntegerTy())
V = Builder.CreateBitCast(
V, llvm::IntegerType::get(Builder.getContext(), Size));
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4791,6 +4791,11 @@ Action *Driver::ConstructPhaseAction(
if (Phase == phases::Assemble && Input->getType() != types::TY_PP_Asm)
return Input;

// Use of --sycl-link will only allow for the link phase to occur. This is
// for all input files.
if (Args.hasArg(options::OPT_sycl_link) && Phase != phases::Link)
return Input;

// Build the appropriate action.
switch (Phase) {
case phases::Link:
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,9 +899,7 @@ bool ToolChain::needsProfileRT(const ArgList &Args) {
Args.hasArg(options::OPT_fprofile_instr_generate) ||
Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
Args.hasArg(options::OPT_fcreate_profile) ||
Args.hasArg(options::OPT_forder_file_instrumentation) ||
Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage) ||
Args.hasArg(options::OPT_fprofile_generate_cold_function_coverage_EQ);
Args.hasArg(options::OPT_forder_file_instrumentation);
}

bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) {
Expand Down
20 changes: 0 additions & 20 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,26 +632,6 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
}
}

if (auto *ColdFuncCoverageArg = Args.getLastArg(
options::OPT_fprofile_generate_cold_function_coverage,
options::OPT_fprofile_generate_cold_function_coverage_EQ)) {
SmallString<128> Path(
ColdFuncCoverageArg->getOption().matches(
options::OPT_fprofile_generate_cold_function_coverage_EQ)
? ColdFuncCoverageArg->getValue()
: "");
llvm::sys::path::append(Path, "default_%m.profraw");
// FIXME: Idealy the file path should be passed through
// `-fprofile-instrument-path=`(InstrProfileOutput), however, this field is
// shared with other profile use path(see PGOOptions), we need to refactor
// PGOOptions to make it work.
CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString(
Twine("--instrument-cold-function-only-path=") + Path));
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("--pgo-function-entry-coverage");
}

Arg *PGOGenArg = nullptr;
if (PGOGenerateArg) {
assert(!CSPGOGenerateArg);
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Driver/ToolChains/SPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,21 @@ void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());

// Use of --sycl-link will call the clang-sycl-linker instead of
// the default linker (spirv-link).
if (Args.hasArg(options::OPT_sycl_link))
Linker = ToolChain.GetProgramPath("clang-sycl-linker");
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
Args.MakeArgString(Linker), CmdArgs,
Inputs, Output));
}

SPIRVToolChain::SPIRVToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: ToolChain(D, Triple, Args) {
// TODO: Revisit need/use of --sycl-link option once SYCL toolchain is
// available and SYCL linking support is moved there.
NativeLLVMSupport = Args.hasArg(options::OPT_sycl_link);
}

bool SPIRVToolChain::HasNativeLLVMSupport() const { return NativeLLVMSupport; }
5 changes: 3 additions & 2 deletions clang/lib/Driver/ToolChains/SPIRV.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain {

public:
SPIRVToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args)
: ToolChain(D, Triple, Args) {}
const llvm::opt::ArgList &Args);

bool useIntegratedAs() const override { return true; }

Expand All @@ -72,6 +71,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain {
}
bool isPICDefaultForced() const override { return false; }
bool SupportsProfiling() const override { return false; }
bool HasNativeLLVMSupport() const override;

clang::driver::Tool *SelectTool(const JobAction &JA) const override;

Expand All @@ -81,6 +81,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain {

private:
clang::driver::Tool *getTranslator() const;
bool NativeLLVMSupport;
};

} // namespace toolchains
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Headers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ set(x86_files
amxcomplexintrin.h
amxfp16intrin.h
amxintrin.h
amxfp8intrin.h
avx10_2_512bf16intrin.h
avx10_2_512convertintrin.h
avx10_2_512minmaxintrin.h
Expand Down
95 changes: 95 additions & 0 deletions clang/lib/Headers/amxfp8intrin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*===------------- amxfp8intrin.h - AMX intrinsics -*- C++ -*----------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*===------------------------------------------------------------------------===
*/

#ifndef __IMMINTRIN_H
#error "Never use <amxfp8intrin.h> directly; include <immintrin.h> instead."
#endif /* __IMMINTRIN_H */

#ifndef __AMXFP8INTRIN_H
#define __AMXFP8INTRIN_H
#ifdef __x86_64__

/// Peform the dot product of a BF8 value \a a by a BF8 value \a b accumulating
/// into a Single Precision (FP32) source/dest \a dst.
///
/// \headerfile <immintrin.h>
///
/// \code
/// void _tile_dpbf8ps (__tile dst, __tile a, __tile b)
/// \endcode
///
/// This intrinsic corresponds to the \c TDPBF8PS instruction.
///
/// \param dst
/// The destination tile. Max size is 1024 Bytes.
/// \param a
/// The 1st source tile. Max size is 1024 Bytes.
/// \param b
/// The 2nd source tile. Max size is 1024 Bytes.
#define _tile_dpbf8ps(dst, a, b) __builtin_ia32_tdpbf8ps((dst), (a), (b))

/// Perform the dot product of a BF8 value \a a by an HF8 value \a b
/// accumulating into a Single Precision (FP32) source/dest \a dst.
///
/// \headerfile <immintrin.h>
///
/// \code
/// void _tile_dpbhf8ps (__tile dst, __tile a, __tile b)
/// \endcode
///
/// This intrinsic corresponds to the \c TDPBHF8PS instruction.
///
/// \param dst
/// The destination tile. Max size is 1024 Bytes.
/// \param a
/// The 1st source tile. Max size is 1024 Bytes.
/// \param b
/// The 2nd source tile. Max size is 1024 Bytes.
#define _tile_dpbhf8ps(dst, a, b) __builtin_ia32_tdpbhf8ps((dst), (a), (b))

/// Perform the dot product of an HF8 value \a a by a BF8 value \a b
/// accumulating into a Single Precision (FP32) source/dest \a dst.
///
/// \headerfile <immintrin.h>
///
/// \code
/// void _tile_dphbf8ps (__tile dst, __tile a, __tile b)
/// \endcode
///
/// This intrinsic corresponds to the \c TDPHBF8PS instruction.
///
/// \param dst
/// The destination tile. Max size is 1024 Bytes.
/// \param a
/// The 1st source tile. Max size is 1024 Bytes.
/// \param b
/// The 2nd source tile. Max size is 1024 Bytes.
#define _tile_dphbf8ps(dst, a, b) __builtin_ia32_tdphbf8ps((dst), (a), (b))

/// Perform the dot product of an HF8 value \a a by an HF8 value \a b
/// accumulating into a Single Precision (FP32) source/dest \a dst.
///
/// \headerfile <immintrin.h>
///
/// \code
/// void _tile_dphf8ps (__tile dst, __tile a, __tile b)
/// \endcode
///
/// This intrinsic corresponds to the \c TDPHF8PS instruction.
///
/// \param dst
/// The destination tile. Max size is 1024 Bytes.
/// \param a
/// The 1st source tile. Max size is 1024 Bytes.
/// \param b
/// The 2nd source tile. Max size is 1024 Bytes.
#define _tile_dphf8ps(dst, a, b) __builtin_ia32_tdphf8ps((dst), (a), (b))

#endif /* __x86_64__ */
#endif /* __AMXFP8INTRIN_H */
4 changes: 4 additions & 0 deletions clang/lib/Headers/immintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,10 @@ _storebe_i64(void * __P, long long __D) {
#include <amxcomplexintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_FP8__)
#include <amxfp8intrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || \
defined(__AVX512VP2INTERSECT__)
#include <avx512vp2intersectintrin.h>
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/Parse/ParseObjc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1454,7 +1454,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,

SmallVector<const IdentifierInfo *, 12> KeyIdents;
SmallVector<SourceLocation, 12> KeyLocs;
SmallVector<SemaObjC::ObjCArgInfo, 12> ArgInfos;
SmallVector<ParmVarDecl *, 12> ObjCParamInfo;
ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
Scope::FunctionDeclarationScope | Scope::DeclScope);

Expand Down Expand Up @@ -1495,7 +1495,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
ArgInfo.NameLoc = Tok.getLocation();
ConsumeToken(); // Eat the identifier.

ArgInfos.push_back(ArgInfo);
ParmVarDecl *Param = Actions.ObjC().ActOnMethodParmDeclaration(
getCurScope(), ArgInfo, ObjCParamInfo.size(), MethodDefinition);
ObjCParamInfo.push_back(Param);
KeyIdents.push_back(SelIdent);
KeyLocs.push_back(selLoc);

Expand Down Expand Up @@ -1567,8 +1569,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
&KeyIdents[0]);
Decl *Result = Actions.ObjC().ActOnMethodDeclaration(
getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
MethodImplKind, isVariadic, MethodDefinition);
Sel, ObjCParamInfo.data(), CParamInfo.data(), CParamInfo.size(),
methodAttrs, MethodImplKind, isVariadic, MethodDefinition);

PD.complete(Result);
return Result;
Expand Down
85 changes: 43 additions & 42 deletions clang/lib/Sema/SemaAMDGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,49 +63,12 @@ bool SemaAMDGPU::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID,
OrderIndex = 0;
ScopeIndex = 1;
break;
case AMDGPU::BI__builtin_amdgcn_mov_dpp: {
if (SemaRef.checkArgCountRange(TheCall, 5, 5))
return true;
Expr *ValArg = TheCall->getArg(0);
QualType Ty = ValArg->getType();
// TODO: Vectors can also be supported.
if (!Ty->isArithmeticType() || Ty->isAnyComplexType()) {
SemaRef.Diag(ValArg->getBeginLoc(),
diag::err_typecheck_cond_expect_int_float)
<< Ty << ValArg->getSourceRange();
return true;
}
return false;
}
case AMDGPU::BI__builtin_amdgcn_mov_dpp:
return checkMovDPPFunctionCall(TheCall, 5, 1);
case AMDGPU::BI__builtin_amdgcn_mov_dpp8:
return checkMovDPPFunctionCall(TheCall, 2, 1);
case AMDGPU::BI__builtin_amdgcn_update_dpp: {
if (SemaRef.checkArgCountRange(TheCall, 6, 6))
return true;
Expr *Args[2];
QualType ArgTys[2];
for (unsigned I = 0; I != 2; ++I) {
Args[I] = TheCall->getArg(I);
ArgTys[I] = Args[I]->getType();
// TODO: Vectors can also be supported.
if (!ArgTys[I]->isArithmeticType() || ArgTys[I]->isAnyComplexType()) {
SemaRef.Diag(Args[I]->getBeginLoc(),
diag::err_typecheck_cond_expect_int_float)
<< ArgTys[I] << Args[I]->getSourceRange();
return true;
}
}
if (getASTContext().hasSameUnqualifiedType(ArgTys[0], ArgTys[1]))
return false;
if (((ArgTys[0]->isUnsignedIntegerType() &&
ArgTys[1]->isSignedIntegerType()) ||
(ArgTys[0]->isSignedIntegerType() &&
ArgTys[1]->isUnsignedIntegerType())) &&
getASTContext().getTypeSize(ArgTys[0]) ==
getASTContext().getTypeSize(ArgTys[1]))
return false;
SemaRef.Diag(Args[1]->getBeginLoc(),
diag::err_typecheck_call_different_arg_types)
<< ArgTys[0] << ArgTys[1];
return true;
return checkMovDPPFunctionCall(TheCall, 6, 2);
}
default:
return false;
Expand Down Expand Up @@ -152,6 +115,44 @@ bool SemaAMDGPU::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID,
return false;
}

bool SemaAMDGPU::checkMovDPPFunctionCall(CallExpr *TheCall, unsigned NumArgs,
unsigned NumDataArgs) {
assert(NumDataArgs <= 2);
if (SemaRef.checkArgCountRange(TheCall, NumArgs, NumArgs))
return true;
Expr *Args[2];
QualType ArgTys[2];
for (unsigned I = 0; I != NumDataArgs; ++I) {
Args[I] = TheCall->getArg(I);
ArgTys[I] = Args[I]->getType();
// TODO: Vectors can also be supported.
if (!ArgTys[I]->isArithmeticType() || ArgTys[I]->isAnyComplexType()) {
SemaRef.Diag(Args[I]->getBeginLoc(),
diag::err_typecheck_cond_expect_int_float)
<< ArgTys[I] << Args[I]->getSourceRange();
return true;
}
}
if (NumDataArgs < 2)
return false;

if (getASTContext().hasSameUnqualifiedType(ArgTys[0], ArgTys[1]))
return false;

if (((ArgTys[0]->isUnsignedIntegerType() &&
ArgTys[1]->isSignedIntegerType()) ||
(ArgTys[0]->isSignedIntegerType() &&
ArgTys[1]->isUnsignedIntegerType())) &&
getASTContext().getTypeSize(ArgTys[0]) ==
getASTContext().getTypeSize(ArgTys[1]))
return false;

SemaRef.Diag(Args[1]->getBeginLoc(),
diag::err_typecheck_call_different_arg_types)
<< ArgTys[0] << ArgTys[1];
return true;
}

static bool
checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr,
const AMDGPUFlatWorkGroupSizeAttr &Attr) {
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3332,9 +3332,7 @@ static void mergeParamDeclTypes(ParmVarDecl *NewParam,
}
} else {
QualType NewT = NewParam->getType();
NewT = S.Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*Oldnullability),
NewT, NewT);
NewT = S.Context.getAttributedType(*Oldnullability, NewT, NewT);
NewParam->setType(NewT);
}
}
Expand Down
116 changes: 59 additions & 57 deletions clang/lib/Sema/SemaDeclObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4572,9 +4572,7 @@ static QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc,
return type;

// Otherwise, provide the result with the same nullability.
return S.Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*prevNullability),
type, type);
return S.Context.getAttributedType(*prevNullability, type, type);
}

/// Merge information from the declaration of a method in the \@interface
Expand Down Expand Up @@ -4720,13 +4718,67 @@ static void checkObjCDirectMethodClashes(Sema &S, ObjCInterfaceDecl *IDecl,
diagClash(IMD);
}

ParmVarDecl *SemaObjC::ActOnMethodParmDeclaration(Scope *S,
ObjCArgInfo &ArgInfo,
int ParamIndex,
bool MethodDefinition) {
ASTContext &Context = getASTContext();
QualType ArgType;
TypeSourceInfo *DI;

if (!ArgInfo.Type) {
ArgType = Context.getObjCIdType();
DI = nullptr;
} else {
ArgType = SemaRef.GetTypeFromParser(ArgInfo.Type, &DI);
}
LookupResult R(SemaRef, ArgInfo.Name, ArgInfo.NameLoc,
Sema::LookupOrdinaryName,
SemaRef.forRedeclarationInCurContext());
SemaRef.LookupName(R, S);
if (R.isSingleResult()) {
NamedDecl *PrevDecl = R.getFoundDecl();
if (S->isDeclScope(PrevDecl)) {
Diag(ArgInfo.NameLoc,
(MethodDefinition ? diag::warn_method_param_redefinition
: diag::warn_method_param_declaration))
<< ArgInfo.Name;
Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
}
}
SourceLocation StartLoc =
DI ? DI->getTypeLoc().getBeginLoc() : ArgInfo.NameLoc;

// Temporarily put parameter variables in the translation unit. This is what
// ActOnParamDeclarator does in the case of C arguments to the Objective-C
// method too.
ParmVarDecl *Param = SemaRef.CheckParameter(
Context.getTranslationUnitDecl(), StartLoc, ArgInfo.NameLoc, ArgInfo.Name,
ArgType, DI, SC_None);
Param->setObjCMethodScopeInfo(ParamIndex);
Param->setObjCDeclQualifier(
CvtQTToAstBitMask(ArgInfo.DeclSpec.getObjCDeclQualifier()));

// Apply the attributes to the parameter.
SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, ArgInfo.ArgAttrs);
SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param);
if (Param->hasAttr<BlocksAttr>()) {
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
Param->setInvalidDecl();
}

S->AddDecl(Param);
SemaRef.IdResolver.AddDecl(Param);
return Param;
}

Decl *SemaObjC::ActOnMethodDeclaration(
Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc,
tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
unsigned CNumArgs, // c-style args
const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodDeclKind,
bool isVariadic, bool MethodDefinition) {
Expand Down Expand Up @@ -4768,60 +4820,10 @@ Decl *SemaObjC::ActOnMethodDeclaration(
HasRelatedResultType);

SmallVector<ParmVarDecl*, 16> Params;

for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
QualType ArgType;
TypeSourceInfo *DI;

if (!ArgInfo[i].Type) {
ArgType = Context.getObjCIdType();
DI = nullptr;
} else {
ArgType = SemaRef.GetTypeFromParser(ArgInfo[i].Type, &DI);
}

LookupResult R(SemaRef, ArgInfo[i].Name, ArgInfo[i].NameLoc,
Sema::LookupOrdinaryName,
SemaRef.forRedeclarationInCurContext());
SemaRef.LookupName(R, S);
if (R.isSingleResult()) {
NamedDecl *PrevDecl = R.getFoundDecl();
if (S->isDeclScope(PrevDecl)) {
Diag(ArgInfo[i].NameLoc,
(MethodDefinition ? diag::warn_method_param_redefinition
: diag::warn_method_param_declaration))
<< ArgInfo[i].Name;
Diag(PrevDecl->getLocation(),
diag::note_previous_declaration);
}
}

SourceLocation StartLoc = DI
? DI->getTypeLoc().getBeginLoc()
: ArgInfo[i].NameLoc;

ParmVarDecl *Param =
SemaRef.CheckParameter(ObjCMethod, StartLoc, ArgInfo[i].NameLoc,
ArgInfo[i].Name, ArgType, DI, SC_None);

Param->setObjCMethodScopeInfo(i);

Param->setObjCDeclQualifier(
CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));

// Apply the attributes to the parameter.
SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param,
ArgInfo[i].ArgAttrs);
SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param);
for (unsigned I = 0; I < Sel.getNumArgs(); ++I) {
ParmVarDecl *Param = ArgInfo[I];
Param->setDeclContext(ObjCMethod);
SemaRef.ProcessAPINotes(Param);

if (Param->hasAttr<BlocksAttr>()) {
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
Param->setInvalidDecl();
}
S->AddDecl(Param);
SemaRef.IdResolver.AddDecl(Param);

Params.push_back(Param);
}

Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8757,8 +8757,7 @@ static QualType computeConditionalNullability(QualType ResTy, bool IsBin,
ResTy = ResTy.getSingleStepDesugaredType(Ctx);

// Create a new AttributedType with the new nullability kind.
auto NewAttr = AttributedType::getNullabilityAttrKind(MergedKind);
return Ctx.getAttributedType(NewAttr, ResTy, ResTy);
return Ctx.getAttributedType(MergedKind, ResTy, ResTy);
}

ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
Expand Down
29 changes: 9 additions & 20 deletions clang/lib/Sema/SemaExprObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,7 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
const llvm::UTF8 *StrEnd = Str.bytes_end();
// Check that this is a valid UTF-8 string.
if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
BoxedType = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(
NullabilityKind::NonNull),
BoxedType = Context.getAttributedType(NullabilityKind::NonNull,
NSStringPointer, NSStringPointer);
return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);
}
Expand Down Expand Up @@ -605,9 +603,8 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
std::optional<NullabilityKind> Nullability =
BoxingMethod->getReturnType()->getNullability();
if (Nullability)
BoxedType = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*Nullability), BoxedType,
BoxedType);
BoxedType =
Context.getAttributedType(*Nullability, BoxedType, BoxedType);
}
} else if (ValueType->isBuiltinType()) {
// The other types we support are numeric, char and BOOL/bool. We could also
Expand Down Expand Up @@ -1444,10 +1441,8 @@ static QualType stripObjCInstanceType(ASTContext &Context, QualType T) {
QualType origType = T;
if (auto nullability = AttributedType::stripOuterNullability(T)) {
if (T == Context.getObjCInstanceType()) {
return Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*nullability),
Context.getObjCIdType(),
Context.getObjCIdType());
return Context.getAttributedType(*nullability, Context.getObjCIdType(),
Context.getObjCIdType());
}

return origType;
Expand Down Expand Up @@ -1485,10 +1480,7 @@ static QualType getBaseMessageSendResultType(Sema &S,
(void)AttributedType::stripOuterNullability(type);

// Form a new attributed type using the method result type's nullability.
return Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*nullability),
type,
type);
return Context.getAttributedType(*nullability, type, type);
}

return type;
Expand Down Expand Up @@ -1559,9 +1551,8 @@ QualType SemaObjC::getMessageSendResultType(const Expr *Receiver,
QualType NewResultType = Context.getObjCObjectPointerType(
Context.getObjCInterfaceType(MD->getClassInterface()));
if (auto Nullability = resultType->getNullability())
NewResultType = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*Nullability),
NewResultType, NewResultType);
NewResultType = Context.getAttributedType(*Nullability, NewResultType,
NewResultType);
return NewResultType;
}
}
Expand Down Expand Up @@ -1623,9 +1614,7 @@ QualType SemaObjC::getMessageSendResultType(const Expr *Receiver,
if (newResultNullabilityIdx > 0) {
auto newNullability
= static_cast<NullabilityKind>(newResultNullabilityIdx-1);
return Context.getAttributedType(
AttributedType::getNullabilityAttrKind(newNullability),
resultType, resultType);
return Context.getAttributedType(newNullability, resultType, resultType);
}

return resultType;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaObjCProperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2460,7 +2460,7 @@ void SemaObjC::ProcessPropertyDecl(ObjCPropertyDecl *property) {
QualType modifiedTy = resultTy;
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
if (*nullability == NullabilityKind::Unspecified)
resultTy = Context.getAttributedType(attr::TypeNonNull,
resultTy = Context.getAttributedType(NullabilityKind::NonNull,
modifiedTy, modifiedTy);
}
}
Expand Down Expand Up @@ -2538,7 +2538,7 @@ void SemaObjC::ProcessPropertyDecl(ObjCPropertyDecl *property) {
QualType modifiedTy = paramTy;
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
if (*nullability == NullabilityKind::Unspecified)
paramTy = Context.getAttributedType(attr::TypeNullable,
paramTy = Context.getAttributedType(NullabilityKind::Nullable,
modifiedTy, modifiedTy);
}
}
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/Sema/SemaSwift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,16 @@ static bool isValidSwiftErrorResultType(QualType Ty) {
}

void SemaSwift::handleAttrAttr(Decl *D, const ParsedAttr &AL) {
if (AL.isInvalid() || AL.isUsedAsTypeAttr())
return;

// Make sure that there is a string literal as the annotation's single
// argument.
StringRef Str;
if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str))
if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str)) {
AL.setInvalid();
return;
}

D->addAttr(::new (getASTContext()) SwiftAttrAttr(getASTContext(), AL, Str));
}
Expand Down
67 changes: 63 additions & 4 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ namespace {
QualType getAttributedType(Attr *A, QualType ModifiedType,
QualType EquivType) {
QualType T =
sema.Context.getAttributedType(A->getKind(), ModifiedType, EquivType);
sema.Context.getAttributedType(A, ModifiedType, EquivType);
AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});
AttrsForTypesSorted = false;
return T;
Expand Down Expand Up @@ -7161,6 +7161,60 @@ static bool HandleWebAssemblyFuncrefAttr(TypeProcessingState &State,
return false;
}

static void HandleSwiftAttr(TypeProcessingState &State, TypeAttrLocation TAL,
QualType &QT, ParsedAttr &PAttr) {
if (TAL == TAL_DeclName)
return;

Sema &S = State.getSema();
auto &D = State.getDeclarator();

// If the attribute appears in declaration specifiers
// it should be handled as a declaration attribute,
// unless it's associated with a type or a function
// prototype (i.e. appears on a parameter or result type).
if (State.isProcessingDeclSpec()) {
if (!(D.isPrototypeContext() ||
D.getContext() == DeclaratorContext::TypeName))
return;

if (auto *chunk = D.getInnermostNonParenChunk()) {
moveAttrFromListToList(PAttr, State.getCurrentAttributes(),
const_cast<DeclaratorChunk *>(chunk)->getAttrs());
return;
}
}

StringRef Str;
if (!S.checkStringLiteralArgumentAttr(PAttr, 0, Str)) {
PAttr.setInvalid();
return;
}

// If the attribute as attached to a paren move it closer to
// the declarator. This can happen in block declarations when
// an attribute is placed before `^` i.e. `(__attribute__((...)) ^)`.
//
// Note that it's actually invalid to use GNU style attributes
// in a block but such cases are currently handled gracefully
// but the parser and behavior should be consistent between
// cases when attribute appears before/after block's result
// type and inside (^).
if (TAL == TAL_DeclChunk) {
auto chunkIdx = State.getCurrentChunkIndex();
if (chunkIdx >= 1 &&
D.getTypeObject(chunkIdx).Kind == DeclaratorChunk::Paren) {
moveAttrFromListToList(PAttr, State.getCurrentAttributes(),
D.getTypeObject(chunkIdx - 1).getAttrs());
return;
}
}

auto *A = ::new (S.Context) SwiftAttrAttr(S.Context, PAttr, Str);
QT = State.getAttributedType(A, QT, QT);
PAttr.setUsedAsTypeAttr();
}

/// Rebuild an attributed type without the nullability attribute on it.
static QualType rebuildAttributedTypeWithoutNullability(ASTContext &Ctx,
QualType Type) {
Expand All @@ -7177,7 +7231,8 @@ static QualType rebuildAttributedTypeWithoutNullability(ASTContext &Ctx,
Ctx, Attributed->getModifiedType());
assert(Modified.getTypePtr() != Attributed->getModifiedType().getTypePtr());
return Ctx.getAttributedType(Attributed->getAttrKind(), Modified,
Attributed->getEquivalentType());
Attributed->getEquivalentType(),
Attributed->getAttr());
}

/// Map a nullability attribute kind to a nullability kind.
Expand Down Expand Up @@ -7306,8 +7361,7 @@ static bool CheckNullabilityTypeSpecifier(
Attr *A = createNullabilityAttr(S.Context, *PAttr, Nullability);
QT = State->getAttributedType(A, QT, QT);
} else {
attr::Kind attrKind = AttributedType::getNullabilityAttrKind(Nullability);
QT = S.Context.getAttributedType(attrKind, QT, QT);
QT = S.Context.getAttributedType(Nullability, QT, QT);
}
return false;
}
Expand Down Expand Up @@ -8749,6 +8803,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
break;
}

case ParsedAttr::AT_SwiftAttr: {
HandleSwiftAttr(state, TAL, type, attr);
break;
}

MS_TYPE_ATTRS_CASELIST:
if (!handleMSPointerTypeQualifierAttr(state, attr, type))
attr.setUsedAsTypeAttr();
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaX86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,10 @@ bool SemaX86::CheckBuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall) {
case X86::BI__builtin_ia32_tdpfp16ps:
case X86::BI__builtin_ia32_tcmmimfp16ps:
case X86::BI__builtin_ia32_tcmmrlfp16ps:
case X86::BI__builtin_ia32_tdpbf8ps:
case X86::BI__builtin_ia32_tdpbhf8ps:
case X86::BI__builtin_ia32_tdphbf8ps:
case X86::BI__builtin_ia32_tdphf8ps:
return CheckBuiltinTileRangeAndDuplicate(TheCall, {0, 1, 2});
}
}
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -7435,7 +7435,8 @@ QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,

result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
modifiedType,
equivalentType);
equivalentType,
TL.getAttr());
}

AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,11 +860,12 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
// If one of the operands is a symbol and the other is a constant,
// build an expression for use by the constraint manager.
if (SymbolRef rSym = rhs.getAsLocSymbol()) {
// We can only build expressions with symbols on the left,
// so we need a reversible operator.
if (!BinaryOperator::isComparisonOp(op) || op == BO_Cmp)
if (op == BO_Cmp)
return UnknownVal();

if (!BinaryOperator::isComparisonOp(op))
return makeNonLoc(L.getValue(), op, rSym, resultTy);

op = BinaryOperator::reverseComparisonOp(op);
return makeNonLoc(rSym, op, L.getValue(), resultTy);
}
Expand Down
19 changes: 19 additions & 0 deletions clang/test/AST/ByteCode/new-delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,15 @@ namespace NowThrowNew {
static_assert(erroneous_array_bound_nothrow2(-1) == 0);// expected-error {{not an integral constant expression}}
static_assert(!erroneous_array_bound_nothrow2(1LL << 62));// expected-error {{not an integral constant expression}}

constexpr bool erroneous_array_bound(long long n) {
delete[] new int[n]; // both-note {{array bound -1 is negative}} both-note {{array bound 4611686018427387904 is too large}}
return true;
}
static_assert(erroneous_array_bound(3));
static_assert(erroneous_array_bound(0));
static_assert(erroneous_array_bound(-1)); // both-error {{constant expression}} both-note {{in call}}
static_assert(erroneous_array_bound(1LL << 62)); // both-error {{constant expression}} both-note {{in call}}

constexpr bool evaluate_nothrow_arg() {
bool ok = false;
delete new ((ok = true, std::nothrow)) int;
Expand Down Expand Up @@ -569,6 +578,16 @@ namespace CastedDelete {
return a;
}
static_assert(vdtor_1() == 1);

constexpr int foo() { // both-error {{never produces a constant expression}}
struct S {};
struct T : S {};
S *p = new T();
delete p; // both-note 2{{delete of object with dynamic type 'T' through pointer to base class type 'S' with non-virtual destructor}}
return 1;
}
static_assert(foo() == 1); // both-error {{not an integral constant expression}} \
// both-note {{in call to}}
}

constexpr void use_after_free_2() { // both-error {{never produces a constant expression}}
Expand Down
47 changes: 46 additions & 1 deletion clang/test/AST/attr-swift_attr.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
// RUN: %clang_cc1 -fblocks -ast-dump %s | FileCheck %s

__attribute__((swift_attr("@actor")))
@interface View
Expand All @@ -14,3 +14,48 @@ @interface Contact

// CHECK-LABEL: InterfaceDecl {{.*}} Contact
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@sendable"

#define SWIFT_SENDABLE __attribute__((swift_attr("@Sendable")))

@interface InTypeContext
- (nullable id)test:(nullable SWIFT_SENDABLE id)obj SWIFT_SENDABLE;
@end

// CHECK-LABEL: InterfaceDecl {{.*}} InTypeContext
// CHECK-NEXT: MethodDecl {{.*}} - test: 'id _Nullable':'id'
// CHECK-NEXT: ParmVarDecl {{.*}} obj 'SWIFT_SENDABLE id _Nullable':'id'
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@Sendable"

@interface Generic<T: SWIFT_SENDABLE id>
@end

// CHECK-LABEL: InterfaceDecl {{.*}} Generic
// CHECK-NEXT: TypeParamDecl {{.*}} T bounded 'SWIFT_SENDABLE id':'id'

typedef SWIFT_SENDABLE Generic<id> Alias;

// CHECK-LABEL: TypedefDecl {{.*}} Alias 'Generic<id>'
// CHECK-NEXT: ObjectType {{.*}} 'Generic<id>'
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@Sendable"

SWIFT_SENDABLE
typedef struct {
void *ptr;
} SendableStruct;

// CHECK-LABEL: TypedefDecl {{.*}} SendableStruct 'struct SendableStruct':'SendableStruct'
// CHECK: SwiftAttrAttr {{.*}} "@Sendable"

@interface TestAttrPlacementInBlock1
-(void) withHandler: (void (SWIFT_SENDABLE ^)(id)) handler;
@end

// CHECK-LABEL: ObjCInterfaceDecl {{.*}} TestAttrPlacementInBlock1
// CHECK: handler 'SWIFT_SENDABLE void (^)(id)':'void (^)(id)'

@interface TestAttrPlacementInBlock2
-(void) withHandler: (void (^ SWIFT_SENDABLE)(id)) handler;
@end

// CHECK-LABEL: ObjCInterfaceDecl {{.*}} TestAttrPlacementInBlock2
// CHECK: handler 'SWIFT_SENDABLE void (^)(id)':'void (^)(id)'
1 change: 1 addition & 0 deletions clang/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ list(APPEND CLANG_TEST_DEPS
clang-nvlink-wrapper
clang-offload-bundler
clang-offload-packager
clang-sycl-linker
diagtool
hmaptool
)
Expand Down
27 changes: 27 additions & 0 deletions clang/test/CodeGen/X86/amx_fp8.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-fp8 \
// RUN: -emit-llvm -o - -Werror -pedantic | FileCheck %s
#include <immintrin.h>

void test_amx(void *data) {
//CHECK-LABEL: @test_amx
//CHECK: call void @llvm.x86.tdpbf8ps(i8 1, i8 2, i8 3)
_tile_dpbf8ps(1, 2, 3);
}

void test_amx2(void *data) {
//CHECK-LABEL: @test_amx2
//CHECK: call void @llvm.x86.tdpbhf8ps(i8 1, i8 2, i8 3)
_tile_dpbhf8ps(1, 2, 3);
}

void test_amx3(void *data) {
//CHECK-LABEL: @test_amx3
//CHECK: call void @llvm.x86.tdphbf8ps(i8 1, i8 2, i8 3)
_tile_dphbf8ps(1, 2, 3);
}

void test_amx4(void *data) {
//CHECK-LABEL: @test_amx4
//CHECK: call void @llvm.x86.tdphf8ps(i8 1, i8 2, i8 3)
_tile_dphf8ps(1, 2, 3);
}
10 changes: 10 additions & 0 deletions clang/test/CodeGen/X86/amx_fp8_errors.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-tile -target-feature +amx-fp8 -verify

#include <immintrin.h>

void test_amx(void *data) {
_tile_dpbf8ps(4, 3, 3); // expected-error {{tile arguments must refer to different tiles}}
_tile_dpbhf8ps(4, 3, 3); // expected-error {{tile arguments must refer to different tiles}}
_tile_dphbf8ps(4, 3, 3); // expected-error {{tile arguments must refer to different tiles}}
_tile_dphf8ps(4, 3, 3); // expected-error {{tile arguments must refer to different tiles}}
}
32 changes: 32 additions & 0 deletions clang/test/CodeGen/X86/amx_fp8_inline_asm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-fp8 -emit-llvm -o - -Wall -Werror -pedantic | FileCheck %s

void f_tilemul(short a)
{
//CHECK: call void asm sideeffect "tileloadd 0(%rsi,%r13,4), %tmm0 \0A\09tileloadd 0(%rdx,%r14,4), %tmm6 \0A\09tdpbf8ps %tmm6, %tmm0, %tmm7 \0A\09tilestored %tmm7, 0(%r12,%r15,4) \0A\09", "~{memory},~{tmm0},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags}"()
__asm__ volatile ("tileloadd 0(%%rsi,%%r13,4), %%tmm0 \n\t"
"tileloadd 0(%%rdx,%%r14,4), %%tmm6 \n\t"
"tdpbf8ps %%tmm6, %%tmm0, %%tmm7 \n\t"
"tilestored %%tmm7, 0(%%r12,%%r15,4) \n\t"
::: "memory", "tmm0", "tmm6", "tmm7");

//CHECK: call void asm sideeffect "tileloadd 0(%rsi,%r13,4), %tmm0 \0A\09tileloadd 0(%rdx,%r14,4), %tmm6 \0A\09tdpbhf8ps %tmm6, %tmm0, %tmm7 \0A\09tilestored %tmm7, 0(%r12,%r15,4) \0A\09", "~{memory},~{tmm0},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags}"()
__asm__ volatile ("tileloadd 0(%%rsi,%%r13,4), %%tmm0 \n\t"
"tileloadd 0(%%rdx,%%r14,4), %%tmm6 \n\t"
"tdpbhf8ps %%tmm6, %%tmm0, %%tmm7 \n\t"
"tilestored %%tmm7, 0(%%r12,%%r15,4) \n\t"
::: "memory", "tmm0", "tmm6", "tmm7");

//CHECK: call void asm sideeffect "tileloadd 0(%rsi,%r13,4), %tmm0 \0A\09tileloadd 0(%rdx,%r14,4), %tmm6 \0A\09tdphbf8ps %tmm6, %tmm0, %tmm7 \0A\09tilestored %tmm7, 0(%r12,%r15,4) \0A\09", "~{memory},~{tmm0},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags}"()
__asm__ volatile ("tileloadd 0(%%rsi,%%r13,4), %%tmm0 \n\t"
"tileloadd 0(%%rdx,%%r14,4), %%tmm6 \n\t"
"tdphbf8ps %%tmm6, %%tmm0, %%tmm7 \n\t"
"tilestored %%tmm7, 0(%%r12,%%r15,4) \n\t"
::: "memory", "tmm0", "tmm6", "tmm7");

//CHECK: call void asm sideeffect "tileloadd 0(%rsi,%r13,4), %tmm0 \0A\09tileloadd 0(%rdx,%r14,4), %tmm6 \0A\09tdphf8ps %tmm6, %tmm0, %tmm7 \0A\09tilestored %tmm7, 0(%r12,%r15,4) \0A\09", "~{memory},~{tmm0},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags}"()
__asm__ volatile ("tileloadd 0(%%rsi,%%r13,4), %%tmm0 \n\t"
"tileloadd 0(%%rdx,%%r14,4), %%tmm6 \n\t"
"tdphf8ps %%tmm6, %%tmm0, %%tmm7 \n\t"
"tilestored %%tmm7, 0(%%r12,%%r15,4) \n\t"
::: "memory", "tmm0", "tmm6", "tmm7");
}
19 changes: 0 additions & 19 deletions clang/test/CodeGen/pgo-cold-function-coverage.c

This file was deleted.

60 changes: 57 additions & 3 deletions clang/test/CodeGenOpenCL/builtins-amdgcn-gfx10.cl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1012 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -o - %s | FileCheck %s

#pragma OPENCL EXTENSION cl_khr_fp16 : enable

typedef unsigned int uint;
typedef unsigned long ulong;

Expand All @@ -19,12 +21,64 @@ void test_permlanex16(global uint* out, uint a, uint b, uint c, uint d) {
*out = __builtin_amdgcn_permlanex16(a, b, c, d, 0, 0);
}

// CHECK-LABEL: @test_mov_dpp8(
// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.mov.dpp8.i32(i32 %a, i32 1)
void test_mov_dpp8(global uint* out, uint a) {
// CHECK-LABEL: @test_mov_dpp8_uint(
// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.mov.dpp8.i32(i32 %a, i32 1)
// CHECK-NEXT: store i32 %0,
void test_mov_dpp8_uint(global uint* out, uint a) {
*out = __builtin_amdgcn_mov_dpp8(a, 1);
}

// CHECK-LABEL: @test_mov_dpp8_long(
// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.mov.dpp8.i64(i64 %a, i32 1)
// CHECK-NEXT: store i64 %0,
void test_mov_dpp8_long(global long* out, long a) {
*out = __builtin_amdgcn_mov_dpp8(a, 1);
}

// CHECK-LABEL: @test_mov_dpp8_float(
// CHECK: %0 = bitcast float %a to i32
// CHECK-NEXT: %1 = tail call{{.*}} i32 @llvm.amdgcn.mov.dpp8.i32(i32 %0, i32 1)
// CHECK-NEXT: store i32 %1,
void test_mov_dpp8_float(global float* out, float a) {
*out = __builtin_amdgcn_mov_dpp8(a, 1);
}

// CHECK-LABEL: @test_mov_dpp8_double
// CHECK: %0 = bitcast double %x to i64
// CHECK-NEXT: %1 = tail call{{.*}} i64 @llvm.amdgcn.mov.dpp8.i64(i64 %0, i32 1)
// CHECK-NEXT: store i64 %1,
void test_mov_dpp8_double(double x, global double *p) {
*p = __builtin_amdgcn_mov_dpp8(x, 1);
}

// CHECK-LABEL: @test_mov_dpp8_short
// CHECK: %0 = zext i16 %x to i32
// CHECK-NEXT: %1 = tail call{{.*}} i32 @llvm.amdgcn.mov.dpp8.i32(i32 %0, i32 1)
// CHECK-NEXT: %2 = trunc i32 %1 to i16
// CHECK-NEXT: store i16 %2,
void test_mov_dpp8_short(short x, global short *p) {
*p = __builtin_amdgcn_mov_dpp8(x, 1);
}

// CHECK-LABEL: @test_mov_dpp8_char
// CHECK: %0 = zext i8 %x to i32
// CHECK-NEXT: %1 = tail call{{.*}} i32 @llvm.amdgcn.mov.dpp8.i32(i32 %0, i32 1)
// CHECK-NEXT: %2 = trunc i32 %1 to i8
// CHECK-NEXT: store i8 %2,
void test_mov_dpp8_char(char x, global char *p) {
*p = __builtin_amdgcn_mov_dpp8(x, 1);
}

// CHECK-LABEL: @test_mov_dpp8_half
// CHECK: %0 = load i16,
// CHECK: %1 = zext i16 %0 to i32
// CHECK-NEXT: %2 = tail call{{.*}} i32 @llvm.amdgcn.mov.dpp8.i32(i32 %1, i32 1)
// CHECK-NEXT: %3 = trunc i32 %2 to i16
// CHECK-NEXT: store i16 %3,
void test_mov_dpp8_half(half *x, global half *p) {
*p = __builtin_amdgcn_mov_dpp8(*x, 1);
}

// CHECK-LABEL: @test_s_memtime
// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.s.memtime()
void test_s_memtime(global ulong* out)
Expand Down
48 changes: 48 additions & 0 deletions clang/test/Driver/clang-sycl-linker-test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Tests the clang-sycl-linker tool.
//
// Test a simple case without arguments.
// RUN: %clangxx -emit-llvm -c %s -o %t_1.bc
// RUN: %clangxx -emit-llvm -c %s -o %t_2.bc
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SIMPLE
// SIMPLE: "{{.*}}llvm-link{{.*}}" {{.*}}.bc {{.*}}.bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
// SIMPLE-NEXT: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv [[FIRSTLLVMLINKOUT]].bc
//
// Test that llvm-link is not called when only one input is present.
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SIMPLE-NO-LINK
// SIMPLE-NO-LINK: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv {{.*}}.bc
//
// Test a simple case with device library files specified.
// RUN: touch %T/lib1.bc
// RUN: touch %T/lib2.bc
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=DEVLIBS
// DEVLIBS: "{{.*}}llvm-link{{.*}}" {{.*}}.bc {{.*}}.bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
// DEVLIBS-NEXT: "{{.*}}llvm-link{{.*}}" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}lib1.bc {{.*}}lib2.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings
// DEVLIBS-NEXT: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv [[SECONDLLVMLINKOUT]].bc
//
// Test a simple case with .o (fat object) as input.
// TODO: Remove this test once fat object support is added.
// RUN: %clangxx -c %s -o %t.o
// RUN: not clang-sycl-linker --dry-run -triple spirv64 %t.o -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=FILETYPEERROR
// FILETYPEERROR: Unsupported file type
//
// Test to see if device library related errors are emitted.
// RUN: not clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs= -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=DEVLIBSERR1
// DEVLIBSERR1: Number of device library files cannot be zero
// RUN: not clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc,lib3.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=DEVLIBSERR2
// DEVLIBSERR2: '{{.*}}lib3.bc' SYCL device library file is not found
//
// Test if correct set of llvm-spirv options are emitted for windows environment.
// RUN: clang-sycl-linker --dry-run -triple spirv64 --is-windows-msvc-env %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=LLVMOPTSWIN
// LLVMOPTSWIN: -spirv-debug-info-version=ocl-100 -spirv-allow-extra-diexpressions -spirv-allow-unknown-intrinsics=llvm.genx. -spirv-ext=
//
// Test if correct set of llvm-spirv options are emitted for linux environment.
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=LLVMOPTSLIN
// LLVMOPTSLIN: -spirv-debug-info-version=nonsemantic-shader-200 -spirv-allow-unknown-intrinsics=llvm.genx. -spirv-ext=
8 changes: 0 additions & 8 deletions clang/test/Driver/fprofile-generate-cold-function-coverage.c

This file was deleted.

9 changes: 9 additions & 0 deletions clang/test/Driver/sycl-link-spirv-target.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Tests the driver when linking LLVM IR bitcode files and targeting SPIR-V
// architecture.
//
// Test that -Xlinker options are being passed to clang-sycl-linker.
// RUN: touch %t.bc
// RUN: %clangxx -### --target=spirv64 --sycl-link -Xlinker --llvm-spirv-path=/tmp \
// RUN: -Xlinker --library-path=/tmp -Xlinker --device-libs=lib1.bc,lib2.bc %t.bc 2>&1 \
// RUN: | FileCheck %s -check-prefix=XLINKEROPTS
// XLINKEROPTS: "{{.*}}clang-sycl-linker{{.*}}" "--llvm-spirv-path=/tmp" "--library-path=/tmp" "--device-libs=lib1.bc,lib2.bc" "{{.*}}.bc" "-o" "a.out"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm -fretain-comments-from-system-headers
// RUN: %clang_cc1 -std=c++20 %t/b.cpp -fmodule-file=a=%t/a.pcm -verify -fsyntax-only

//--- a.cppm
export module a;

//--- b.cpp
// expected-no-diagnostics
import a;
4 changes: 4 additions & 0 deletions clang/test/SemaObjC/validate-attr-swift_attr.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ @interface I
__attribute__((swift_attr(1)))
@interface J
@end

@interface Error<T: __attribute__((swift_attr(1))) id>
// expected-error@-1 {{expected string literal as argument of 'swift_attr' attribute}}
@end
19 changes: 19 additions & 0 deletions clang/test/SemaOpenCL/builtins-amdgcn-error-gfx10.cl
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,30 @@
// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx900 -verify -S -o - %s
// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx908 -verify -S -o - %s

#pragma OPENCL EXTENSION cl_khr_fp16 : enable

typedef unsigned int uint;
typedef int int2 __attribute__((ext_vector_type(2)));

struct S {
int x;
};

void test(global uint* out, uint a, uint b, uint c, uint d) {
*out = __builtin_amdgcn_permlane16(a, b, c, d, 1, 1); // expected-error {{'__builtin_amdgcn_permlane16' needs target feature gfx10-insts}}
*out = __builtin_amdgcn_permlanex16(a, b, c, d, 1, 1); // expected-error {{'__builtin_amdgcn_permlanex16' needs target feature gfx10-insts}}
*out = __builtin_amdgcn_mov_dpp8(a, 1); // expected-error {{'__builtin_amdgcn_mov_dpp8' needs target feature gfx10-insts}}
}

void test_mov_dpp8(global int* out, int src, int i, int2 i2, struct S s, float _Complex fc)
{
*out = __builtin_amdgcn_mov_dpp8(src, i); // expected-error{{argument to '__builtin_amdgcn_mov_dpp8' must be a constant integer}}
*out = __builtin_amdgcn_mov_dpp8(src, 0.1); // expected-error{{argument to '__builtin_amdgcn_mov_dpp8' must be a constant integer}}
*out = __builtin_amdgcn_mov_dpp8(src); // expected-error{{too few arguments to function call, expected 2, have 1}}
*out = __builtin_amdgcn_mov_dpp8(src, 0, 0); // expected-error{{too many arguments to function call, expected at most 2, have 3}}
*out = __builtin_amdgcn_mov_dpp8(out, 0); // expected-error{{used type '__global int *__private' where integer or floating point type is required}}
*out = __builtin_amdgcn_mov_dpp8("aa", 0); // expected-error{{used type '__constant char[3]' where integer or floating point type is required}}
*out = __builtin_amdgcn_mov_dpp8(i2, 0); // expected-error{{used type '__private int2' (vector of 2 'int' values) where integer or floating point type is required}}
*out = __builtin_amdgcn_mov_dpp8(s, 0); // expected-error{{used type '__private struct S' where integer or floating point type is required}}
*out = __builtin_amdgcn_mov_dpp8(fc, 0); // expected-error{{used type '__private _Complex float' where integer or floating point type is required}}
}
1 change: 1 addition & 0 deletions clang/test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
"yaml2obj",
"clang-linker-wrapper",
"clang-nvlink-wrapper",
"clang-sycl-linker",
"llvm-lto",
"llvm-lto2",
"llvm-profdata",
Expand Down
1 change: 1 addition & 0 deletions clang/tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ add_clang_subdirectory(clang-nvlink-wrapper)
add_clang_subdirectory(clang-offload-packager)
add_clang_subdirectory(clang-offload-bundler)
add_clang_subdirectory(clang-scan-deps)
add_clang_subdirectory(clang-sycl-linker)
add_clang_subdirectory(clang-installapi)
if(HAVE_CLANG_REPL_SUPPORT)
add_clang_subdirectory(clang-repl)
Expand Down
45 changes: 0 additions & 45 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,33 +216,6 @@ void printCommands(ArrayRef<StringRef> CmdArgs) {
exit(EXIT_FAILURE);
}

/// Create an extra user-specified \p OffloadFile.
/// TODO: We should find a way to wrap these as libraries instead.
Expected<OffloadFile> getInputBitcodeLibrary(StringRef Input) {
auto [Device, Path] = StringRef(Input).split('=');
auto [String, Arch] = Device.rsplit('-');
auto [Kind, Triple] = String.split('-');

llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> ImageOrError =
llvm::MemoryBuffer::getFileOrSTDIN(Path);
if (std::error_code EC = ImageOrError.getError())
return createFileError(Path, EC);

OffloadingImage Image{};
Image.TheImageKind = IMG_Bitcode;
Image.TheOffloadKind = getOffloadKind(Kind);
Image.StringData["triple"] = Triple;
Image.StringData["arch"] = Arch;
Image.Image = std::move(*ImageOrError);

std::unique_ptr<MemoryBuffer> Binary =
MemoryBuffer::getMemBufferCopy(OffloadBinary::write(Image));
auto NewBinaryOrErr = OffloadBinary::create(*Binary);
if (!NewBinaryOrErr)
return NewBinaryOrErr.takeError();
return OffloadFile(std::move(*NewBinaryOrErr), std::move(Binary));
}

std::string getMainExecutable(const char *Name) {
void *Ptr = (void *)(intptr_t)&getMainExecutable;
auto COWPath = sys::fs::getMainExecutable(Name, Ptr);
Expand Down Expand Up @@ -600,17 +573,6 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
for (StringRef Arg : Args.getAllArgValues(OPT_compiler_arg_EQ))
CmdArgs.push_back(Args.MakeArgString(Arg));

for (StringRef Arg : Args.getAllArgValues(OPT_builtin_bitcode_EQ)) {
if (llvm::Triple(Arg.split('=').first) == Triple)
CmdArgs.append({"-Xclang", "-mlink-builtin-bitcode", "-Xclang",
Args.MakeArgString(Arg.split('=').second)});
}

// The OpenMPOpt pass can introduce new calls and is expensive, we do
// not want this when running CodeGen through clang.
if (Args.hasArg(OPT_clang_backend) || Args.hasArg(OPT_builtin_bitcode_EQ))
CmdArgs.append({"-mllvm", "-openmp-opt-disable"});

if (Error Err = executeCommands(*ClangPath, CmdArgs))
return std::move(Err);

Expand Down Expand Up @@ -1362,13 +1324,6 @@ getDeviceInput(const ArgList &Args) {
}
}

for (StringRef Library : Args.getAllArgValues(OPT_bitcode_library_EQ)) {
auto FileOrErr = getInputBitcodeLibrary(Library);
if (!FileOrErr)
return FileOrErr.takeError();
InputFiles[*FileOrErr].push_back(std::move(*FileOrErr));
}

SmallVector<SmallVector<OffloadFile>> InputsForTarget;
for (auto &[ID, Input] : InputFiles)
InputsForTarget.emplace_back(std::move(Input));
Expand Down
10 changes: 0 additions & 10 deletions clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,12 @@ def host_triple_EQ : Joined<["--"], "host-triple=">,
def opt_level : Joined<["--"], "opt-level=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<O0, O1, O2, or O3>">,
HelpText<"Optimization level for LTO">;
def bitcode_library_EQ : Joined<["--"], "bitcode-library=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<kind>-<triple>-<arch>=<path>">,
HelpText<"Extra bitcode library to link">;
def builtin_bitcode_EQ : Joined<["--"], "builtin-bitcode=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<triple>=<path>">,
HelpText<"Perform a special internalizing link on the bitcode file. "
"This is necessary for some vendor libraries to be linked correctly">;
def device_linker_args_EQ : Joined<["--"], "device-linker=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<value> or <triple>=<value>">,
HelpText<"Arguments to pass to the device linker invocation">;
def device_compiler_args_EQ : Joined<["--"], "device-compiler=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<value> or <triple>=<value>">,
HelpText<"Arguments to pass to the device compiler invocation">;
def clang_backend : Flag<["--"], "clang-backend">,
Flags<[WrapperOnlyOption]>,
HelpText<"Run the backend using clang rather than the LTO backend">;
def dry_run : Flag<["--"], "dry-run">,
Flags<[WrapperOnlyOption]>,
HelpText<"Print program arguments without running">;
Expand Down
28 changes: 28 additions & 0 deletions clang/tools/clang-sycl-linker/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
Option
)

set(LLVM_TARGET_DEFINITIONS SYCLLinkOpts.td)
tablegen(LLVM SYCLLinkOpts.inc -gen-opt-parser-defs)
add_public_tablegen_target(SYCLLinkerOpts)

if(NOT CLANG_BUILT_STANDALONE)
set(tablegen_deps intrinsics_gen SYCLLinkerOpts)
endif()

add_clang_tool(clang-sycl-linker
ClangSYCLLinker.cpp

DEPENDS
${tablegen_deps}
)

set(CLANG_SYCL_LINKER_LIB_DEPS
clangBasic
)

target_link_libraries(clang-sycl-linker
PRIVATE
${CLANG_SYCL_LINKER_LIB_DEPS}
)
Loading