585 changes: 585 additions & 0 deletions clang/docs/SafeBuffers.rst

Large diffs are not rendered by default.

17 changes: 14 additions & 3 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3371,12 +3371,23 @@ Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy, wmem
alpha.unix.cstring.NotNullTerminated (C)
""""""""""""""""""""""""""""""""""""""""
Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat, wcslen, wcsnlen``.
Check for arguments which are not null-terminated strings;
applies to the ``strlen``, ``strcpy``, ``strcat``, ``strcmp`` family of functions.
Only very fundamental cases are detected where the passed memory block is
absolutely different from a null-terminated string. This checker does not
find if a memory buffer is passed where the terminating zero character
is missing.
.. code-block:: c
void test() {
int y = strlen((char *)&test); // warn
void test1() {
int l = strlen((char *)&test); // warn
}
void test2() {
label:
int l = strlen((char *)&&label); // warn
}
.. _alpha-unix-cstring-OutOfBounds:
Expand Down
1 change: 1 addition & 0 deletions clang/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Using Clang as a Compiler
CrossCompilation
ClangStaticAnalyzer
ThreadSafetyAnalysis
SafeBuffers
DataFlowAnalysisIntro
AddressSanitizer
ThreadSanitizer
Expand Down
18 changes: 17 additions & 1 deletion clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -2085,7 +2085,11 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
class ClassTemplatePartialSpecializationDecl
: public ClassTemplateSpecializationDecl {
/// The list of template parameters
TemplateParameterList* TemplateParams = nullptr;
TemplateParameterList *TemplateParams = nullptr;

/// The set of "injected" template arguments used within this
/// partial specialization.
TemplateArgument *InjectedArgs = nullptr;

/// The class template partial specialization from which this
/// class template partial specialization was instantiated.
Expand Down Expand Up @@ -2132,6 +2136,10 @@ class ClassTemplatePartialSpecializationDecl
return TemplateParams;
}

/// Retrieve the template arguments list of the template parameter list
/// of this template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();

/// \brief All associated constraints of this partial specialization,
/// including the requires clause and any constraints derived from
/// constrained-parameters.
Expand Down Expand Up @@ -2856,6 +2864,10 @@ class VarTemplatePartialSpecializationDecl
/// The list of template parameters
TemplateParameterList *TemplateParams = nullptr;

/// The set of "injected" template arguments used within this
/// partial specialization.
TemplateArgument *InjectedArgs = nullptr;

/// The variable template partial specialization from which this
/// variable template partial specialization was instantiated.
///
Expand Down Expand Up @@ -2902,6 +2914,10 @@ class VarTemplatePartialSpecializationDecl
return TemplateParams;
}

/// Retrieve the template arguments list of the template parameter list
/// of this template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();

/// \brief All associated constraints of this partial specialization,
/// including the requires clause and any constraints derived from
/// constrained-parameters.
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4197,9 +4197,9 @@ AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>,
/// \endcode
/// cxxMemberCallExpr(onImplicitObjectArgument(hasType(
/// cxxRecordDecl(hasName("Y")))))
/// matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`.
/// matches `y.m()`, `x.m()` and (`g()).m()`, but not `x.g()`).
/// cxxMemberCallExpr(on(callExpr()))
/// does not match `(g()).m()`, because the parens are not ignored.
/// only matches `(g()).m()` (the parens are ignored).
///
/// FIXME: Overload to allow directly matching types?
AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
//===-- CachedConstAccessorsLattice.h ---------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the lattice mixin that additionally maintains a cache of
// stable method call return values to model const accessor member functions.
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CACHED_CONST_ACCESSORS_LATTICE_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CACHED_CONST_ACCESSORS_LATTICE_H

#include "clang/AST/Expr.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLFunctionalExtras.h"

namespace clang {
namespace dataflow {

/// A mixin for a lattice that additionally maintains a cache of stable method
/// call return values to model const accessors methods. When a non-const method
/// is called, the cache should be cleared causing the next call to a const
/// method to be considered a different value. NOTE: The user is responsible for
/// clearing the cache.
///
/// For example:
///
/// class Bar {
/// public:
/// const std::optional<Foo>& getFoo() const;
/// void clear();
/// };
//
/// void func(Bar& s) {
/// if (s.getFoo().has_value()) {
/// use(s.getFoo().value()); // safe (checked earlier getFoo())
/// s.clear();
/// use(s.getFoo().value()); // unsafe (invalidate cache for s)
/// }
/// }
template <typename Base> class CachedConstAccessorsLattice : public Base {
public:
using Base::Base; // inherit all constructors

/// Creates or returns a previously created `Value` associated with a const
/// method call `obj.getFoo()` where `RecordLoc` is the
/// `RecordStorageLocation` of `obj`.
/// Returns nullptr if unable to find or create a value.
///
/// Requirements:
///
/// - `CE` should return a value (not a reference or record type)
Value *
getOrCreateConstMethodReturnValue(const RecordStorageLocation &RecordLoc,
const CallExpr *CE, Environment &Env);

/// Creates or returns a previously created `StorageLocation` associated with
/// a const method call `obj.getFoo()` where `RecordLoc` is the
/// `RecordStorageLocation` of `obj`.
///
/// The callback `Initialize` runs on the storage location if newly created.
/// Returns nullptr if unable to find or create a value.
///
/// Requirements:
///
/// - `CE` should return a location (GLValue or a record type).
StorageLocation *getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const CallExpr *CE,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize);

void clearConstMethodReturnValues(const RecordStorageLocation &RecordLoc) {
ConstMethodReturnValues.erase(&RecordLoc);
}

void clearConstMethodReturnStorageLocations(
const RecordStorageLocation &RecordLoc) {
ConstMethodReturnStorageLocations.erase(&RecordLoc);
}

bool operator==(const CachedConstAccessorsLattice &Other) const {
return Base::operator==(Other);
}

LatticeJoinEffect join(const CachedConstAccessorsLattice &Other);

private:
// Maps a record storage location and const method to the value to return
// from that const method.
using ConstMethodReturnValuesType =
llvm::SmallDenseMap<const RecordStorageLocation *,
llvm::SmallDenseMap<const FunctionDecl *, Value *>>;
ConstMethodReturnValuesType ConstMethodReturnValues;

// Maps a record storage location and const method to the record storage
// location to return from that const method.
using ConstMethodReturnStorageLocationsType = llvm::SmallDenseMap<
const RecordStorageLocation *,
llvm::SmallDenseMap<const FunctionDecl *, StorageLocation *>>;
ConstMethodReturnStorageLocationsType ConstMethodReturnStorageLocations;
};

namespace internal {

template <typename T>
llvm::SmallDenseMap<const RecordStorageLocation *,
llvm::SmallDenseMap<const FunctionDecl *, T *>>
joinConstMethodMap(
const llvm::SmallDenseMap<const RecordStorageLocation *,
llvm::SmallDenseMap<const FunctionDecl *, T *>>
&Map1,
const llvm::SmallDenseMap<const RecordStorageLocation *,
llvm::SmallDenseMap<const FunctionDecl *, T *>>
&Map2,
LatticeEffect &Effect) {
llvm::SmallDenseMap<const RecordStorageLocation *,
llvm::SmallDenseMap<const FunctionDecl *, T *>>
Result;
for (auto &[Loc, DeclToT] : Map1) {
auto It = Map2.find(Loc);
if (It == Map2.end()) {
Effect = LatticeJoinEffect::Changed;
continue;
}
const auto &OtherDeclToT = It->second;
auto &JoinedDeclToT = Result[Loc];
for (auto [Func, Var] : DeclToT) {
T *OtherVar = OtherDeclToT.lookup(Func);
if (OtherVar == nullptr || OtherVar != Var) {
Effect = LatticeJoinEffect::Changed;
continue;
}
JoinedDeclToT.insert({Func, Var});
}
}
return Result;
}

} // namespace internal

template <typename Base>
LatticeEffect CachedConstAccessorsLattice<Base>::join(
const CachedConstAccessorsLattice<Base> &Other) {

LatticeEffect Effect = Base::join(Other);

// For simplicity, we only retain values that are identical, but not ones that
// are non-identical but equivalent. This is likely to be sufficient in
// practice, and it reduces implementation complexity considerably.

ConstMethodReturnValues = internal::joinConstMethodMap<Value>(
ConstMethodReturnValues, Other.ConstMethodReturnValues, Effect);

ConstMethodReturnStorageLocations =
internal::joinConstMethodMap<StorageLocation>(
ConstMethodReturnStorageLocations,
Other.ConstMethodReturnStorageLocations, Effect);

return Effect;
}

template <typename Base>
Value *CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnValue(
const RecordStorageLocation &RecordLoc, const CallExpr *CE,
Environment &Env) {
QualType Type = CE->getType();
assert(!Type.isNull());
assert(!Type->isReferenceType());
assert(!Type->isRecordType());

auto &ObjMap = ConstMethodReturnValues[&RecordLoc];
const FunctionDecl *DirectCallee = CE->getDirectCallee();
if (DirectCallee == nullptr)
return nullptr;
auto it = ObjMap.find(DirectCallee);
if (it != ObjMap.end())
return it->second;

Value *Val = Env.createValue(Type);
if (Val != nullptr)
ObjMap.insert({DirectCallee, Val});
return Val;
}

template <typename Base>
StorageLocation *
CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const CallExpr *CE,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize) {
assert(!CE->getType().isNull());
assert(CE->isGLValue() || CE->getType()->isRecordType());
auto &ObjMap = ConstMethodReturnStorageLocations[&RecordLoc];
const FunctionDecl *DirectCallee = CE->getDirectCallee();
if (DirectCallee == nullptr)
return nullptr;
auto it = ObjMap.find(DirectCallee);
if (it != ObjMap.end())
return it->second;

StorageLocation &Loc =
Env.createStorageLocation(CE->getType().getNonReferenceType());
Initialize(Loc);

ObjMap.insert({DirectCallee, &Loc});
return &Loc;
}

} // namespace dataflow
} // namespace clang

#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CACHED_CONST_ACCESSORS_LATTICE_H
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/AArch64SVEACLETypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ SVE_VECTOR_TYPE_FLOAT("__SVFloat64_t", "__SVFloat64_t", SveFloat64, SveFloat64Ty

SVE_VECTOR_TYPE_BFLOAT("__SVBfloat16_t", "__SVBfloat16_t", SveBFloat16, SveBFloat16Ty, 8, 16, 1)

// This is a 8 bits opaque type.
SVE_VECTOR_TYPE_INT("__SVMfloat8_t", "__SVMfloat8_t", SveMFloat8, SveMFloat8Ty, 16, 8, 1, false)

//
// x2
//
Expand Down
25 changes: 25 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4593,6 +4593,31 @@ def HLSLResourceBinding: InheritableAttr {
let LangOpts = [HLSL];
let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>];
let Documentation = [HLSLResourceBindingDocs];
let AdditionalMembers = [{
public:
enum class RegisterType : unsigned { SRV, UAV, CBuffer, Sampler, C, I };

private:
RegisterType RegType;
unsigned SlotNumber;
unsigned SpaceNumber;

public:
void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum) {
RegType = RT;
SlotNumber = SlotNum;
SpaceNumber = SpaceNum;
}
RegisterType getRegisterType() const {
return RegType;
}
unsigned getSlotNumber() const {
return SlotNumber;
}
unsigned getSpaceNumber() const {
return SpaceNumber;
}
}];
}

def HLSLPackOffset: HLSLAnnotationAttr {
Expand Down
7 changes: 5 additions & 2 deletions clang/include/clang/Basic/arm_neon.td
Original file line number Diff line number Diff line change
Expand Up @@ -1968,13 +1968,16 @@ let TargetGuard = "v8.3a,neon" in {
def VCADDQ_ROT90 : SInst<"vcaddq_rot90", "QQQ", "f">;
def VCADDQ_ROT270 : SInst<"vcaddq_rot270", "QQQ", "f">;

defm VCMLA_F32 : VCMLA_ROTS<"f", "uint64x1_t", "uint64x2_t">;
defm VCMLA_F32 : VCMLA_ROTS<"f", "uint64x1_t", "uint64x2_t">;
}
let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)", TargetGuard = "v8.3a,neon" in {
def VCADDQ_ROT90_FP64 : SInst<"vcaddq_rot90", "QQQ", "d">;
def VCADDQ_ROT270_FP64 : SInst<"vcaddq_rot270", "QQQ", "d">;

defm VCMLA_FP64 : VCMLA_ROTS<"d", "uint64x2_t", "uint64x2_t">;
def VCMLAQ_FP64 : SInst<"vcmlaq", "QQQQ", "d">;
def VCMLAQ_ROT90_FP64 : SInst<"vcmlaq_rot90", "QQQQ", "d">;
def VCMLAQ_ROT180_FP64 : SInst<"vcmlaq_rot180", "QQQQ", "d">;
def VCMLAQ_ROT270_FP64 : SInst<"vcmlaq_rot270", "QQQQ", "d">;
}

// V8.2-A BFloat intrinsics
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/arm_sve_sme_incl.td
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def EltTyBool16 : EltType<10>;
def EltTyBool32 : EltType<11>;
def EltTyBool64 : EltType<12>;
def EltTyBFloat16 : EltType<13>;
def EltTyMFloat8 : EltType<14>;

class MemEltType<int val> {
int Value = val;
Expand Down
24 changes: 19 additions & 5 deletions clang/include/clang/CodeGen/CodeGenABITypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,25 @@ const CGFunctionInfo &arrangeCXXMethodType(CodeGenModule &CGM,
const FunctionProtoType *FTP,
const CXXMethodDecl *MD);

const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
CanQualType returnType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args);
const CGFunctionInfo &
arrangeCXXMethodCall(CodeGenModule &CGM, CanQualType returnType,
ArrayRef<CanQualType> argTypes, FunctionType::ExtInfo info,
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
RequiredArgs args);

const CGFunctionInfo &arrangeFreeFunctionCall(
CodeGenModule &CGM, CanQualType returnType, ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
RequiredArgs args);

// An overload with an empty `paramInfos`
inline const CGFunctionInfo &
arrangeFreeFunctionCall(CodeGenModule &CGM, CanQualType returnType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info, RequiredArgs args) {
return arrangeFreeFunctionCall(CGM, returnType, argTypes, info, {}, args);
}

/// Returns the implicit arguments to add to a complete, non-delegating C++
/// constructor call.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -8531,7 +8531,7 @@ def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">,
HelpText<"Set runtime encoding, supports only UTF-8">,
Alias<fexec_charset_EQ>;
def _SLASH_std : CLCompileJoined<"std:">,
HelpText<"Set language version (c++14,c++17,c++20,c++latest,c11,c17)">;
HelpText<"Set language version (c++14,c++17,c++20,c++23preview,c++latest,c11,c17)">;
def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
MetaVarName<"<macro>">, Alias<U>;
def _SLASH_validate_charset : CLFlag<"validate-charset">,
Expand Down
37 changes: 35 additions & 2 deletions clang/include/clang/ExtractAPI/API.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/TargetParser/Triple.h"
#include <cstddef>
#include <iterator>
Expand Down Expand Up @@ -615,7 +616,24 @@ struct TagRecord : APIRecord, RecordContext {
return classofKind(Record->getKind());
}
static bool classofKind(RecordKind K) {
return K == RK_Struct || K == RK_Union || K == RK_Enum;
switch (K) {
case RK_Enum:
LLVM_FALLTHROUGH;
case RK_Struct:
LLVM_FALLTHROUGH;
case RK_Union:
LLVM_FALLTHROUGH;
case RK_CXXClass:
LLVM_FALLTHROUGH;
case RK_ClassTemplate:
LLVM_FALLTHROUGH;
case RK_ClassTemplateSpecialization:
LLVM_FALLTHROUGH;
case RK_ClassTemplatePartialSpecialization:
return true;
default:
return false;
}
}

bool IsEmbeddedInVarDeclarator;
Expand Down Expand Up @@ -684,7 +702,22 @@ struct RecordRecord : TagRecord {
return classofKind(Record->getKind());
}
static bool classofKind(RecordKind K) {
return K == RK_Struct || K == RK_Union;
switch (K) {
case RK_Struct:
LLVM_FALLTHROUGH;
case RK_Union:
LLVM_FALLTHROUGH;
case RK_CXXClass:
LLVM_FALLTHROUGH;
case RK_ClassTemplate:
LLVM_FALLTHROUGH;
case RK_ClassTemplateSpecialization:
LLVM_FALLTHROUGH;
case RK_ClassTemplatePartialSpecialization:
return true;
default:
return false;
}
}

bool isAnonymousWithNoTypedef() { return Name.empty(); }
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -6755,7 +6755,7 @@ class Sema final : public SemaBase {

ExprResult BuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK);
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
ExprResult ActOnIntegerConstant(SourceLocation Loc, int64_t Val);

bool CheckLoopHintExpr(Expr *E, SourceLocation Loc, bool AllowZero);

Expand Down
57 changes: 57 additions & 0 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,60 @@ class AttributeCommonInfo;
class IdentifierInfo;
class ParsedAttr;
class Scope;
class VarDecl;

using llvm::dxil::ResourceClass;

// FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no
// longer need to create builtin buffer types in HLSLExternalSemaSource.
bool CreateHLSLAttributedResourceType(
Sema &S, QualType Wrapped, ArrayRef<const Attr *> AttrList,
QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo = nullptr);

enum class BindingType : uint8_t { NotAssigned, Explicit, Implicit };

// DeclBindingInfo struct stores information about required/assigned resource
// binding onon a declaration for specific resource class.
struct DeclBindingInfo {
const VarDecl *Decl;
ResourceClass ResClass;
const HLSLResourceBindingAttr *Attr;
BindingType BindType;

DeclBindingInfo(const VarDecl *Decl, ResourceClass ResClass,
BindingType BindType = BindingType::NotAssigned,
const HLSLResourceBindingAttr *Attr = nullptr)
: Decl(Decl), ResClass(ResClass), Attr(Attr), BindType(BindType) {}

void setBindingAttribute(HLSLResourceBindingAttr *A, BindingType BT) {
assert(Attr == nullptr && BindType == BindingType::NotAssigned &&
"binding attribute already assigned");
Attr = A;
BindType = BT;
}
};

// ResourceBindings class stores information about all resource bindings
// in a shader. It is used for binding diagnostics and implicit binding
// assigments.
class ResourceBindings {
public:
DeclBindingInfo *addDeclBindingInfo(const VarDecl *VD,
ResourceClass ResClass);
DeclBindingInfo *getDeclBindingInfo(const VarDecl *VD,
ResourceClass ResClass);
bool hasBindingInfoForDecl(const VarDecl *VD) const;

private:
// List of all resource bindings required by the shader.
// A global declaration can have multiple bindings for different
// resource classes. They are all stored sequentially in this list.
// The DeclToBindingListIndex hashtable maps a declaration to the
// index of the first binding info in the list.
llvm::SmallVector<DeclBindingInfo> BindingsList;
llvm::DenseMap<const VarDecl *, unsigned> DeclToBindingListIndex;
};

class SemaHLSL : public SemaBase {
public:
SemaHLSL(Sema &S);
Expand All @@ -55,6 +102,7 @@ class SemaHLSL : public SemaBase {
mergeParamModifierAttr(Decl *D, const AttributeCommonInfo &AL,
HLSLParamModifierAttr::Spelling Spelling);
void ActOnTopLevelFunction(FunctionDecl *FD);
void ActOnVariableDeclarator(VarDecl *VD);
void CheckEntryPoint(FunctionDecl *FD);
void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
const HLSLAnnotationAttr *AnnotationAttr);
Expand Down Expand Up @@ -102,6 +150,15 @@ class SemaHLSL : public SemaBase {
llvm::DenseMap<const HLSLAttributedResourceType *,
HLSLAttributedResourceLocInfo>
LocsForHLSLAttributedResources;

// List of all resource bindings
ResourceBindings Bindings;

private:
void collectResourcesOnVarDecl(VarDecl *D);
void collectResourcesOnUserRecordDecl(const VarDecl *VD,
const RecordType *RT);
void processExplicitBindingsOnDecl(VarDecl *D);
};

} // namespace clang
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 505;
const unsigned NUM_PREDEF_TYPE_IDS = 506;

// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
Expand Down
13 changes: 6 additions & 7 deletions clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,12 @@ ANALYZER_OPTION(

ANALYZER_OPTION(
bool, ShouldEagerlyAssume, "eagerly-assume",
"Whether we should eagerly assume evaluations of conditionals, thus, "
"bifurcating the path. This indicates how the engine should handle "
"expressions such as: 'x = (y != 0)'. When this is true then the "
"subexpression 'y != 0' will be eagerly assumed to be true or false, thus "
"evaluating it to the integers 0 or 1 respectively. The upside is that "
"this can increase analysis precision until we have a better way to lazily "
"evaluate such logic. The downside is that it eagerly bifurcates paths.",
"If this is enabled (the default behavior), when the analyzer encounters "
"a comparison operator or logical negation, it immediately splits the "
"state to separate the case when the expression is true and the case when "
"it's false. The upside is that this can increase analysis precision until "
"we have a better way to lazily evaluate such logic; the downside is that "
"it eagerly bifurcates paths.",
true)

ANALYZER_OPTION(
Expand Down
8 changes: 3 additions & 5 deletions clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzerNoteAnalysisEntryPoints : 1;

unsigned eagerlyAssumeBinOpBifurcation : 1;

unsigned TrimGraph : 1;
unsigned visualizeExplodedGraphWithGraphViz : 1;
unsigned UnoptimizedCFG : 1;
Expand Down Expand Up @@ -293,9 +291,9 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
ShowConfigOptionsList(false),
ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false),
AnalyzerDisplayProgress(false), AnalyzerNoteAnalysisEntryPoints(false),
eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {}
TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false),
AnalyzerWerror(false) {}

/// Interprets an option's string value as a boolean. The "true" string is
/// interpreted as true and the "false" string is interpreted as false.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,14 +583,13 @@ class ExprEngine {
ExplodedNode *Pred,
ExplodedNodeSet &Dst);

/// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
/// with those assumptions.
void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
const Expr *Ex);
/// evalEagerlyAssumeBifurcation - Given the nodes in 'Src', eagerly assume
/// concrete boolean values for 'Ex', storing the resulting nodes in 'Dst'.
void evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
const Expr *Ex);

static std::pair<const ProgramPointTag *, const ProgramPointTag *>
geteagerlyAssumeBinOpBifurcationTags();
getEagerlyAssumeBifurcationTags();

ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
const LocationContext *LCtx, QualType T,
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/AST/ByteCode/Integral.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,14 @@ template <unsigned Bits, bool Signed> class Integral final {
APSInt toAPSInt() const {
return APSInt(APInt(Bits, static_cast<uint64_t>(V), Signed), !Signed);
}
APSInt toAPSInt(unsigned NumBits) const {
APSInt toAPSInt(unsigned BitWidth) const { return APSInt(toAPInt(BitWidth)); }
APInt toAPInt(unsigned BitWidth) const {
if constexpr (Signed)
return APSInt(toAPSInt().sextOrTrunc(NumBits), !Signed);
return APInt(Bits, static_cast<uint64_t>(V), Signed)
.sextOrTrunc(BitWidth);
else
return APSInt(toAPSInt().zextOrTrunc(NumBits), !Signed);
return APInt(Bits, static_cast<uint64_t>(V), Signed)
.zextOrTrunc(BitWidth);
}
APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }

Expand Down
6 changes: 2 additions & 4 deletions clang/lib/AST/ByteCode/IntegralAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ template <bool Signed> class IntegralAP final {

IntegralAP(APInt V) : V(V) {}
/// Arbitrary value for uninitialized variables.
IntegralAP() : IntegralAP(-1, 3) {}
IntegralAP() : IntegralAP(Signed ? -1 : 7, 3) {}

IntegralAP operator-() const { return IntegralAP(-V); }
IntegralAP operator-(const IntegralAP &Other) const {
Expand Down Expand Up @@ -112,9 +112,7 @@ template <bool Signed> class IntegralAP final {

template <unsigned Bits, bool InputSigned>
static IntegralAP from(Integral<Bits, InputSigned> I, unsigned BitWidth) {
APInt Copy = APInt(BitWidth, static_cast<uint64_t>(I), InputSigned);

return IntegralAP<Signed>(Copy);
return IntegralAP<Signed>(I.toAPInt(BitWidth));
}

static IntegralAP zero(int32_t BitWidth) {
Expand Down
1 change: 0 additions & 1 deletion clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,6 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
return nullptr;
};

AllocType->dump();
if (const FunctionDecl *VirtualDelete =
getVirtualOperatorDelete(AllocType);
VirtualDelete &&
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,20 @@ SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
return Range;
}

ArrayRef<TemplateArgument>
ClassTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
TemplateParameterList *Params = getTemplateParameters();
auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
if (!First->InjectedArgs) {
auto &Context = getASTContext();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
}
return llvm::ArrayRef(First->InjectedArgs, Params->size());
}

//===----------------------------------------------------------------------===//
// FriendTemplateDecl Implementation
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1535,6 +1549,20 @@ SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
return Range;
}

ArrayRef<TemplateArgument>
VarTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
TemplateParameterList *Params = getTemplateParameters();
auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
if (!First->InjectedArgs) {
auto &Context = getASTContext();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
}
return llvm::ArrayRef(First->InjectedArgs, Params->size());
}

static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
// typename T
Expand Down
43 changes: 43 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7237,6 +7237,7 @@ class APValueToBufferConverter {

case APValue::ComplexInt:
case APValue::ComplexFloat:
return visitComplex(Val, Ty, Offset);
case APValue::FixedPoint:
// FIXME: We should support these.

Expand Down Expand Up @@ -7323,6 +7324,31 @@ class APValueToBufferConverter {
return true;
}

bool visitComplex(const APValue &Val, QualType Ty, CharUnits Offset) {
const ComplexType *ComplexTy = Ty->castAs<ComplexType>();
QualType EltTy = ComplexTy->getElementType();
CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
bool IsInt = Val.isComplexInt();

if (IsInt) {
if (!visitInt(Val.getComplexIntReal(), EltTy,
Offset + (0 * EltSizeChars)))
return false;
if (!visitInt(Val.getComplexIntImag(), EltTy,
Offset + (1 * EltSizeChars)))
return false;
} else {
if (!visitFloat(Val.getComplexFloatReal(), EltTy,
Offset + (0 * EltSizeChars)))
return false;
if (!visitFloat(Val.getComplexFloatImag(), EltTy,
Offset + (1 * EltSizeChars)))
return false;
}

return true;
}

bool visitVector(const APValue &Val, QualType Ty, CharUnits Offset) {
const VectorType *VTy = Ty->castAs<VectorType>();
QualType EltTy = VTy->getElementType();
Expand Down Expand Up @@ -7595,6 +7621,23 @@ class BufferToAPValueConverter {
return ArrayValue;
}

std::optional<APValue> visit(const ComplexType *Ty, CharUnits Offset) {
QualType ElementType = Ty->getElementType();
CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
bool IsInt = ElementType->isIntegerType();

std::optional<APValue> Values[2];
for (unsigned I = 0; I != 2; ++I) {
Values[I] = visitType(Ty->getElementType(), Offset + I * ElementWidth);
if (!Values[I])
return std::nullopt;
}

if (IsInt)
return APValue(Values[0]->getInt(), Values[1]->getInt());
return APValue(Values[0]->getFloat(), Values[1]->getFloat());
}

std::optional<APValue> visit(const VectorType *VTy, CharUnits Offset) {
QualType EltTy = VTy->getElementType();
unsigned NElts = VTy->getNumElements();
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2525,6 +2525,7 @@ bool Type::isSveVLSBuiltinType() const {
case BuiltinType::SveBool:
case BuiltinType::SveBoolx2:
case BuiltinType::SveBoolx4:
case BuiltinType::SveMFloat8:
return true;
default:
return false;
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Basic/Targets/OSTargets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,11 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));

if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
if (Opts.CPlusPlus23)
if (Opts.CPlusPlus26)
// TODO update to the proper value.
Builder.defineMacro("_MSVC_LANG", "202004L");
Builder.defineMacro("_MSVC_LANG", "202400L");
else if (Opts.CPlusPlus23)
Builder.defineMacro("_MSVC_LANG", "202302L");
else if (Opts.CPlusPlus20)
Builder.defineMacro("_MSVC_LANG", "202002L");
else if (Opts.CPlusPlus17)
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5657,13 +5657,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
*Arg3 = EmitScalarExpr(E->getArg(3));
llvm::FunctionType *FTy = llvm::FunctionType::get(
Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Value *ACast = Builder.CreateAddrSpaceCast(Arg3, I8PTy);
// We know the third argument is an integer type, but we may need to cast
// it to i32.
if (Arg2->getType() != Int32Ty)
Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty);
return RValue::get(
EmitRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name),
{Arg0, Arg1, Arg2, Arg3, PacketSize, PacketAlign}));
{Arg0, Arg1, Arg2, ACast, PacketSize, PacketAlign}));
}
}
// OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/CGVTT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
cast<llvm::StructType>(VTable->getValueType())
->getElementType(AddressPoint.VTableIndex));
unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
llvm::APInt(32, VTableSize - Offset, true));
llvm::ConstantRange InRange(
llvm::APInt(32, (int)-Offset, true),
llvm::APInt(32, (int)(VTableSize - Offset), true));
llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr(
VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange);

Expand Down
25 changes: 17 additions & 8 deletions clang/lib/CodeGen/CodeGenABITypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,23 @@ CodeGen::arrangeCXXMethodType(CodeGenModule &CGM,
return CGM.getTypes().arrangeCXXMethodType(RD, FTP, MD);
}

const CGFunctionInfo &
CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM,
CanQualType returnType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args) {
return CGM.getTypes().arrangeLLVMFunctionInfo(returnType, FnInfoOpts::None,
argTypes, info, {}, args);
const CGFunctionInfo &CodeGen::arrangeCXXMethodCall(
CodeGenModule &CGM, CanQualType returnType, ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
RequiredArgs args) {
return CGM.getTypes().arrangeLLVMFunctionInfo(
returnType, FnInfoOpts::IsInstanceMethod, argTypes, info, paramInfos,
args);
}

const CGFunctionInfo &CodeGen::arrangeFreeFunctionCall(
CodeGenModule &CGM, CanQualType returnType, ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
RequiredArgs args) {
return CGM.getTypes().arrangeLLVMFunctionInfo(
returnType, FnInfoOpts::None, argTypes, info, paramInfos, args);
}

ImplicitCXXConstructorArgs
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
return createCommonSPIRTargetCodeGenInfo(CGM);
case llvm::Triple::spirv32:
case llvm::Triple::spirv64:
case llvm::Triple::spirv:
return createSPIRVTargetCodeGenInfo(CGM);
case llvm::Triple::dxil:
return createDirectXTargetCodeGenInfo(CGM);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2066,7 +2066,7 @@ struct CounterCoverageMappingBuilder
GapRegionCounter = OutCount;
}

if (!S->isConsteval() && !llvm::EnableSingleByteCoverage)
if (!llvm::EnableSingleByteCoverage)
// Create Branch Region around condition.
createBranchRegion(S->getCond(), ThenCount,
subtractCounters(ParentCount, ThenCount));
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2099,8 +2099,9 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
unsigned VTableSize =
ComponentSize * Layout.getVTableSize(AddressPoint.VTableIndex);
unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
llvm::APInt(32, VTableSize - Offset, true));
llvm::ConstantRange InRange(
llvm::APInt(32, (int)-Offset, true),
llvm::APInt(32, (int)(VTableSize - Offset), true));
return llvm::ConstantExpr::getGetElementPtr(
VTable->getValueType(), VTable, Indices, /*InBounds=*/true, InRange);
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/Targets/DirectX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(CodeGenModule &CGM,
llvm_unreachable("dx.Sampler handles are not implemented yet");
break;
}
llvm_unreachable("Unknown llvm::dxil::ResourceClass enum");
}

} // namespace
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7225,6 +7225,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
.Case("c++17", "-std=c++17")
.Case("c++20", "-std=c++20")
// TODO add c++23 and c++26 when MSVC supports it.
.Case("c++23preview", "-std=c++23")
.Case("c++latest", "-std=c++26")
.Default("");
if (LanguageStandard.empty())
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,16 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
CmdArgs.push_back("-lFortranRuntime");
CmdArgs.push_back("-lFortranDecimal");
}

// libomp needs libatomic for atomic operations if using libgcc
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false)) {
Driver::OpenMPRuntimeKind OMPRuntime =
TC.getDriver().getOpenMPRuntime(Args);
ToolChain::RuntimeLibType RuntimeLib = TC.GetRuntimeLibType(Args);
if (OMPRuntime == Driver::OMPRT_OMP && RuntimeLib == ToolChain::RLT_Libgcc)
CmdArgs.push_back("-latomic");
}
}

void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Parse/ParseInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,9 @@ ExprResult Parser::createEmbedExpr() {
ASTContext &Context = Actions.getASTContext();
SourceLocation StartLoc = ConsumeAnnotationToken();
if (Data->BinaryData.size() == 1) {
Res = IntegerLiteral::Create(Context,
llvm::APInt(CHAR_BIT, Data->BinaryData.back()),
Context.UnsignedCharTy, StartLoc);
Res = IntegerLiteral::Create(
Context, llvm::APInt(CHAR_BIT, (unsigned char)Data->BinaryData.back()),
Context.UnsignedCharTy, StartLoc);
} else {
auto CreateStringLiteralFromStringRef = [&](StringRef Str, QualType Ty) {
llvm::APSInt ArraySize =
Expand Down
11 changes: 7 additions & 4 deletions clang/lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1518,10 +1518,13 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
SourceLocation ConstevalLoc;

if (Tok.is(tok::kw_constexpr)) {
Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if
: diag::ext_constexpr_if);
IsConstexpr = true;
ConsumeToken();
// C23 supports constexpr keyword, but only for object definitions.
if (getLangOpts().CPlusPlus) {
Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if
: diag::ext_constexpr_if);
IsConstexpr = true;
ConsumeToken();
}
} else {
if (Tok.is(tok::exclaim)) {
NotLocation = ConsumeToken();
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7883,6 +7883,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewVD, D);

if (getLangOpts().HLSL)
HLSL().ActOnVariableDeclarator(NewVD);

// FIXME: This is probably the wrong location to be doing this and we should
// probably be doing this for more attributes (especially for function
// pointer attributes such as format, warn_unused_result, etc.). Ideally
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18273,7 +18273,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
}

// The return types aren't either both pointers or references to a class type.
if (NewClassTy.isNull()) {
if (NewClassTy.isNull() || !NewClassTy->isStructureOrClassType()) {
Diag(New->getLocation(),
diag::err_different_return_type_for_overriding_virtual_function)
<< New->getDeclName() << NewTy << OldTy
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3598,9 +3598,10 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
Lit, Tok.getLocation());
}

ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, int64_t Val) {
unsigned IntSize = Context.getTargetInfo().getIntWidth();
return IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
return IntegerLiteral::Create(Context,
llvm::APInt(IntSize, Val, /*isSigned=*/true),
Context.IntTy, Loc);
}

Expand Down
376 changes: 263 additions & 113 deletions clang/lib/Sema/SemaHLSL.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2216,7 +2216,7 @@ ExprResult SemaOpenACC::CheckGangExpr(OpenACCGangKind GK, Expr *E) {
case OpenACCGangKind::Static:
return CheckGangStaticExpr(*this, E);
}
}
} break;
default:
llvm_unreachable("Non compute construct in active compute construct?");
}
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5697,7 +5697,9 @@ StmtResult SemaOpenMP::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
llvm_unreachable("unhandled unary increment operator");
}
Step = IntegerLiteral::Create(
Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
Ctx,
llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction, /*isSigned=*/true),
LogicalTy, {});
} else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
if (IncBin->getOpcode() == BO_AddAssign) {
Step = IncBin->getRHS();
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ struct TemplateInstantiationArgumentCollecter
if (Innermost)
AddInnermostTemplateArguments(VTPSD);
else if (ForConstraintInstantiation)
AddOuterTemplateArguments(VTPSD, VTPSD->getTemplateArgs().asArray(),
AddOuterTemplateArguments(VTPSD, VTPSD->getInjectedTemplateArgs(),
/*Final=*/false);

if (VTPSD->isMemberSpecialization())
Expand Down Expand Up @@ -274,7 +274,7 @@ struct TemplateInstantiationArgumentCollecter
if (Innermost)
AddInnermostTemplateArguments(CTPSD);
else if (ForConstraintInstantiation)
AddOuterTemplateArguments(CTPSD, CTPSD->getTemplateArgs().asArray(),
AddOuterTemplateArguments(CTPSD, CTPSD->getInjectedTemplateArgs(),
/*Final=*/false);

if (CTPSD->isMemberSpecialization())
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2695,7 +2695,7 @@ ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
PathSensitiveBugReport &BR) {
ProgramPoint ProgPoint = N->getLocation();
const std::pair<const ProgramPointTag *, const ProgramPointTag *> &Tags =
ExprEngine::geteagerlyAssumeBinOpBifurcationTags();
ExprEngine::getEagerlyAssumeBifurcationTags();

// If an assumption was made on a branch, it should be caught
// here by looking at the state transition.
Expand Down
41 changes: 18 additions & 23 deletions clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2129,7 +2129,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
(B->isRelationalOp() || B->isEqualityOp())) {
ExplodedNodeSet Tmp;
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
evalEagerlyAssumeBifurcation(Dst, Tmp, cast<Expr>(S));
}
else
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
Expand Down Expand Up @@ -2402,7 +2402,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) {
ExplodedNodeSet Tmp;
VisitUnaryOperator(U, Pred, Tmp);
evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
evalEagerlyAssumeBifurcation(Dst, Tmp, U);
}
else
VisitUnaryOperator(U, Pred, Dst);
Expand Down Expand Up @@ -3742,23 +3742,20 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
BldrTop.addNodes(Tmp);
}

std::pair<const ProgramPointTag *, const ProgramPointTag*>
ExprEngine::geteagerlyAssumeBinOpBifurcationTags() {
static SimpleProgramPointTag
eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
"Eagerly Assume True"),
eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
"Eagerly Assume False");
return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
&eagerlyAssumeBinOpBifurcationFalse);
std::pair<const ProgramPointTag *, const ProgramPointTag *>
ExprEngine::getEagerlyAssumeBifurcationTags() {
static SimpleProgramPointTag TrueTag(TagProviderName, "Eagerly Assume True"),
FalseTag(TagProviderName, "Eagerly Assume False");

return std::make_pair(&TrueTag, &FalseTag);
}

void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
ExplodedNodeSet &Src,
const Expr *Ex) {
void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst,
ExplodedNodeSet &Src,
const Expr *Ex) {
StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx);

for (const auto Pred : Src) {
for (ExplodedNode *Pred : Src) {
// Test if the previous node was as the same expression. This can happen
// when the expression fails to evaluate to anything meaningful and
// (as an optimization) we don't generate a node.
Expand All @@ -3767,28 +3764,26 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
continue;
}

ProgramStateRef state = Pred->getState();
SVal V = state->getSVal(Ex, Pred->getLocationContext());
ProgramStateRef State = Pred->getState();
SVal V = State->getSVal(Ex, Pred->getLocationContext());
std::optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>();
if (SEV && SEV->isExpression()) {
const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
geteagerlyAssumeBinOpBifurcationTags();
const auto &[TrueTag, FalseTag] = getEagerlyAssumeBifurcationTags();

ProgramStateRef StateTrue, StateFalse;
std::tie(StateTrue, StateFalse) = state->assume(*SEV);
auto [StateTrue, StateFalse] = State->assume(*SEV);

// First assume that the condition is true.
if (StateTrue) {
SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
Bldr.generateNode(Ex, Pred, StateTrue, tags.first);
Bldr.generateNode(Ex, Pred, StateTrue, TrueTag);
}

// Next, assume that the condition is false.
if (StateFalse) {
SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
Bldr.generateNode(Ex, Pred, StateFalse, tags.second);
Bldr.generateNode(Ex, Pred, StateFalse, FalseTag);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions clang/test/AST/ast-dump-aarch64-sve-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
// CHECK: TypedefDecl {{.*}} implicit __SVBfloat16_t '__SVBfloat16_t'
// CHECK-NEXT: -BuiltinType {{.*}} '__SVBfloat16_t'

// CHECK: TypedefDecl {{.*}} implicit __SVMfloat8_t '__SVMfloat8_t'
// CHECK-NEXT: -BuiltinType {{.*}} '__SVMfloat8_t'

// CHECK: TypedefDecl {{.*}} implicit __SVBool_t '__SVBool_t'
// CHECK-NEXT: -BuiltinType {{.*}} '__SVBool_t'

Expand Down
46 changes: 40 additions & 6 deletions clang/test/Analysis/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ void strcpy_fn_const(char *x) {
strcpy(x, (const char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
}

void strcpy_fn_dst(const char *x) {
strcpy((char*)&strcpy_fn, x); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
}

extern int globalInt;
void strcpy_effects(char *x, char *y) {
char a = x[0];
Expand Down Expand Up @@ -469,8 +473,22 @@ void strcat_null_src(char *x) {
strcat(x, NULL); // expected-warning{{Null pointer passed as 2nd argument to string concatenation function}}
}

void strcat_fn(char *x) {
strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to string concatenation function is the address of the function 'strcat_fn', which is not a null-terminated string}}
void strcat_fn_dst(const char *x) {
strcat((char*)&strcat_fn_dst, x); // expected-warning{{Argument to string concatenation function is the address of the function 'strcat_fn_dst', which is not a null-terminated string}}
}

void strcat_fn_src(char *x) {
strcat(x, (char*)&strcat_fn_src); // expected-warning{{Argument to string concatenation function is the address of the function 'strcat_fn_src', which is not a null-terminated string}}
}

void strcat_label_dst(const char *x) {
label:
strcat((char*)&&label, x); // expected-warning{{Argument to string concatenation function is the address of the label 'label', which is not a null-terminated string}}
}

void strcat_label_src(char *x) {
label:
strcat(x, (char*)&&label); // expected-warning{{Argument to string concatenation function is the address of the label 'label', which is not a null-terminated string}}
}

void strcat_effects(char *y) {
Expand Down Expand Up @@ -568,8 +586,12 @@ void strncpy_null_src(char *x) {
strncpy(x, NULL, 5); // expected-warning{{Null pointer passed as 2nd argument to string copy function}}
}

void strncpy_fn(char *x) {
strncpy(x, (char*)&strcpy_fn, 5); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
void strncpy_fn_src(char *x) {
strncpy(x, (char*)&strncpy_fn_src, 5); // expected-warning{{Argument to string copy function is the address of the function 'strncpy_fn_src', which is not a null-terminated string}}
}

void strncpy_fn_dst(const char *x) {
strncpy((char*)&strncpy_fn_dst, x, 5); // expected-warning{{Argument to string copy function is the address of the function 'strncpy_fn_dst', which is not a null-terminated string}}
}

void strncpy_effects(char *x, char *y) {
Expand Down Expand Up @@ -680,8 +702,12 @@ void strncat_null_src(char *x) {
strncat(x, NULL, 4); // expected-warning{{Null pointer passed as 2nd argument to string concatenation function}}
}

void strncat_fn(char *x) {
strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to string concatenation function is the address of the function 'strncat_fn', which is not a null-terminated string}}
void strncat_fn_src(char *x) {
strncat(x, (char*)&strncat_fn_src, 4); // expected-warning{{Argument to string concatenation function is the address of the function 'strncat_fn_src', which is not a null-terminated string}}
}

void strncat_fn_dst(const char *x) {
strncat((char*)&strncat_fn_dst, x, 4); // expected-warning{{Argument to string concatenation function is the address of the function 'strncat_fn_dst', which is not a null-terminated string}}
}

void strncat_effects(char *y) {
Expand Down Expand Up @@ -921,6 +947,14 @@ int strcmp_null_argument(char *a) {
return strcmp(a, b); // expected-warning{{Null pointer passed as 2nd argument to string comparison function}}
}

void strcmp_fn_r(char *x) {
strcmp(x, (char*)&strcmp_null_argument); // expected-warning{{Argument to string comparison function is the address of the function 'strcmp_null_argument', which is not a null-terminated string}}
}

void strcmp_fn_l(char *x) {
strcmp((char*)&strcmp_null_argument, x); // expected-warning{{Argument to string comparison function is the address of the function 'strcmp_null_argument', which is not a null-terminated string}}
}

//===----------------------------------------------------------------------===
// strncmp()
//===----------------------------------------------------------------------===
Expand Down
10 changes: 9 additions & 1 deletion clang/test/Analysis/string.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,debug.ExprInspection -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,alpha.unix.cstring,debug.ExprInspection -verify %s

// Test functions that are called "memcpy" but aren't the memcpy
// we're looking for. Unfortunately, this test cannot be put into
// a namespace. The out-of-class weird memcpy needs to be recognized
// as a normal C function for the test to make sense.
typedef __typeof(sizeof(int)) size_t;
void *memcpy(void *, const void *, size_t);
size_t strlen(const char *s);

int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
Expand Down Expand Up @@ -45,3 +46,10 @@ void log(const char* fmt, const Args&... args) {
void test_gh_74269_no_crash() {
log("%d", 1);
}

struct TestNotNullTerm {
void test1() {
TestNotNullTerm * const &x = this;
strlen((char *)&x); // expected-warning{{Argument to string length function is not a null-terminated string}}
}
};
284 changes: 164 additions & 120 deletions clang/test/CXX/temp/temp.constr/temp.constr.decl/p4.cpp
Original file line number Diff line number Diff line change
@@ -1,175 +1,219 @@
// RUN: %clang_cc1 -std=c++20 -verify %s
// expected-no-diagnostics

template<typename T>
concept D = true;
namespace Primary {
template<typename T>
concept D = true;

template<typename T>
struct A {
template<typename U, bool V>
void f() requires V;
template<typename T>
struct A {
template<typename U, bool V>
void f() requires V;

template<>
void f<short, true>();
template<>
void f<short, true>();

template<D U>
void g();

template<typename U, bool V> requires V
struct B;

template<typename U, bool V> requires V
struct B<U*, V>;

template<>
struct B<short, true>;

template<D U>
struct C;

template<D U>
struct C<U*>;

template<typename U, bool V> requires V
static int x;

template<typename U, bool V> requires V
static int x<U*, V>;

template<>
int x<short, true>;

template<D U>
static int y;

template<D U>
static int y<U*>;
};

template<typename T>
template<typename U, bool V>
void A<T>::f() requires V { }

template<typename T>
template<D U>
void g();
void A<T>::g() { }

template<typename T>
template<typename U, bool V> requires V
struct B;
struct A<T>::B { };

template<typename T>
template<typename U, bool V> requires V
struct B<U*, V>;
struct A<T>::B<U*, V> { };

template<>
struct B<short, true>;
template<typename T>
template<typename U, bool V> requires V
struct A<T>::B<U&, V> { };

template<typename T>
template<D U>
struct C;
struct A<T>::C { };

template<typename T>
template<D U>
struct C<U*>;
struct A<T>::C<U*> { };

template<typename T>
template<typename U, bool V> requires V
static int x;
int A<T>::x = 0;

template<typename T>
template<typename U, bool V> requires V
static int x<U*, V>;
int A<T>::x<U*, V> = 0;

template<>
int x<short, true>;
template<typename T>
template<typename U, bool V> requires V
int A<T>::x<U&, V> = 0;

template<typename T>
template<D U>
static int y;
int A<T>::y = 0;

template<typename T>
template<D U>
static int y<U*>;
};

template<typename T>
template<typename U, bool V>
void A<T>::f() requires V { }
int A<T>::y<U*> = 0;

template<typename T>
template<D U>
void A<T>::g() { }

template<typename T>
template<typename U, bool V> requires V
struct A<T>::B { };
template<>
template<typename U, bool V>
void A<short>::f() requires V;

template<typename T>
template<typename U, bool V> requires V
struct A<T>::B<U*, V> { };
template<>
template<>
void A<short>::f<int, true>();

template<typename T>
template<typename U, bool V> requires V
struct A<T>::B<U&, V> { };
template<>
template<>
void A<void>::f<int, true>();

template<typename T>
template<D U>
struct A<T>::C { };
template<>
template<D U>
void A<short>::g();

template<typename T>
template<D U>
struct A<T>::C<U*> { };
template<>
template<typename U, bool V> requires V
struct A<int>::B;

template<typename T>
template<typename U, bool V> requires V
int A<T>::x = 0;
template<>
template<>
struct A<int>::B<int, true>;

template<typename T>
template<typename U, bool V> requires V
int A<T>::x<U*, V> = 0;
template<>
template<>
struct A<void>::B<int, true>;

template<typename T>
template<typename U, bool V> requires V
int A<T>::x<U&, V> = 0;
template<>
template<typename U, bool V> requires V
struct A<int>::B<U*, V>;

template<typename T>
template<D U>
int A<T>::y = 0;
template<>
template<typename U, bool V> requires V
struct A<int>::B<U&, V>;

template<typename T>
template<D U>
int A<T>::y<U*> = 0;
template<>
template<D U>
struct A<int>::C;

template<>
template<typename U, bool V>
void A<short>::f() requires V;
template<>
template<D U>
struct A<int>::C<U*>;

template<>
template<>
void A<short>::f<int, true>();
template<>
template<D U>
struct A<int>::C<U&>;

template<>
template<>
void A<void>::f<int, true>();
template<>
template<typename U, bool V> requires V
int A<long>::x;

template<>
template<D U>
void A<short>::g();
template<>
template<>
int A<long>::x<int, true>;

template<>
template<typename U, bool V> requires V
struct A<int>::B;
template<>
template<>
int A<void>::x<int, true>;

template<>
template<>
struct A<int>::B<int, true>;
template<>
template<typename U, bool V> requires V
int A<long>::x<U*, V>;

template<>
template<>
struct A<void>::B<int, true>;
template<>
template<typename U, bool V> requires V
int A<long>::x<U&, V>;

template<>
template<typename U, bool V> requires V
struct A<int>::B<U*, V>;
template<>
template<D U>
int A<long>::y;

template<>
template<typename U, bool V> requires V
struct A<int>::B<U&, V>;
template<>
template<D U>
int A<long>::y<U*>;

template<>
template<D U>
struct A<int>::C;
template<>
template<D U>
int A<long>::y<U&>;
} // namespace Primary

template<>
template<D U>
struct A<int>::C<U*>;
namespace Partial {
template<typename T, bool B>
struct A;

template<>
template<D U>
struct A<int>::C<U&>;
template<bool U>
struct A<int, U>
{
template<typename V> requires U
void f();

template<>
template<typename U, bool V> requires V
int A<long>::x;
template<typename V> requires U
static const int x;

template<>
template<>
int A<long>::x<int, true>;
template<typename V> requires U
struct B;
};

template<>
template<>
int A<void>::x<int, true>;
template<bool U>
template<typename V> requires U
void A<int, U>::f() { }

template<>
template<typename U, bool V> requires V
int A<long>::x<U*, V>;
template<bool U>
template<typename V> requires U
constexpr int A<int, U>::x = 0;

template<>
template<typename U, bool V> requires V
int A<long>::x<U&, V>;
template<bool U>
template<typename V> requires U
struct A<int, U>::B { };

template<>
template<D U>
int A<long>::y;
template<>
template<typename V> requires true
void A<int, true>::f() { }

template<>
template<D U>
int A<long>::y<U*>;
template<>
template<typename V> requires true
constexpr int A<int, true>::x = 1;

template<>
template<D U>
int A<long>::y<U&>;
template<>
template<typename V> requires true
struct A<int, true>::B { };
} // namespace Partial
2 changes: 2 additions & 0 deletions clang/test/CodeGen/aarch64-sve.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// CHECK: %f16 = alloca <vscale x 8 x half>, align 16
// CHECK: %f32 = alloca <vscale x 4 x float>, align 16
// CHECK: %f64 = alloca <vscale x 2 x double>, align 16
// CHECK: %mf8 = alloca <vscale x 16 x i8>, align 16
// CHECK: %bf16 = alloca <vscale x 8 x bfloat>, align 16
// CHECK: %b8 = alloca <vscale x 16 x i1>, align 2

Expand All @@ -33,6 +34,7 @@ void test_locals(void) {
__SVFloat32_t f32;
__SVFloat64_t f64;

__SVMfloat8_t mf8;
__SVBfloat16_t bf16;

__SVBool_t b8;
Expand Down
42 changes: 42 additions & 0 deletions clang/test/CodeGen/sanitize-coverage-gated-callbacks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// RUN: %clang %s -target arm64-apple-darwin -emit-llvm -S -fsanitize-coverage=trace-pc-guard -mllvm -sanitizer-coverage-gated-trace-callbacks=1 -o - | FileCheck %s --check-prefixes=CHECK,GATED
// RUN: %clang %s -target arm64-apple-darwin -emit-llvm -S -fsanitize-coverage=trace-pc-guard -mllvm -sanitizer-coverage-gated-trace-callbacks=0 -o - | FileCheck %s --check-prefixes=CHECK,PLAIN
// RUN: not %clang %s -target arm64-apple-darwin -emit-llvm -S -fsanitize-coverage=trace-pc -mllvm -sanitizer-coverage-gated-trace-callbacks=1 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=INCOMPATIBLE
// RUN: not %clang %s -target arm64-apple-darwin -emit-llvm -S -fsanitize-coverage=inline-8bit-counters -mllvm -sanitizer-coverage-gated-trace-callbacks=1 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=INCOMPATIBLE
// RUN: not %clang %s -target arm64-apple-darwin -emit-llvm -S -fsanitize-coverage=inline-bool-flag -mllvm -sanitizer-coverage-gated-trace-callbacks=1 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=INCOMPATIBLE

// Verify that we do not emit the __sancov_gate section for "plain" trace-pc-guard
// GATED: section "__DATA,__sancov_gate"
// PLAIN-NOT: section "__DATA,__sancov_gate"

// Produce an error for all incompatible sanitizer coverage modes.
// INCOMPATIBLE: error: 'sanitizer-coverage-gated-trace-callbacks' is only supported with trace-pc-guard

int x[10];

// CHECK: define{{.*}} void @foo
void foo(int n, int m) {
// COM: Verify that we're emitting the call to __sanitizer_cov_trace_pc_guard upon
// COM: checking the value of __sancov_should_track.
// GATED: [[VAL:%.*]] = load i64, {{.*}}@__sancov_should_track
// GATED-NOT: [[VAL:%.*]] = load i64, i64* @__sancov_should_track
// GATED-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 0
// GATED-NEXT: br i1 [[CMP]], label %[[L_TRUE:.*]], label %[[L_FALSE:.*]], !prof [[WEIGHTS:!.+]]
// GATED: [[L_TRUE]]:
// GATED-NEXT: call void @__sanitizer_cov_trace_pc_guard
// GATED: br i1 [[CMP]], label %[[L_TRUE_2:.*]], label %[[L_FALSE_2:.*]]
// GATED: [[L_TRUE_2]]:
// GATED-NEXT: call void @__sanitizer_cov_trace_pc_guard
// GATED: [[WEIGHTS]] = !{!"branch_weights", i32 1, i32 100000}

// COM: With the non-gated instrumentation, we should not emit the
// COM: __sancov_should_track global.
// PLAIN-NOT: __sancov_should_track
// But we should still be emitting the calls to the callback.
// PLAIN: call void @__sanitizer_cov_trace_pc_guard
if (n) {
x[n] = 42;
if (m) {
x[m] = 41;
}
}
}
4 changes: 4 additions & 0 deletions clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void f(__SVFloat16_t, __SVFloat16_t);
void f(__SVFloat32_t, __SVFloat32_t);
void f(__SVFloat64_t, __SVFloat64_t);
void f(__SVBfloat16_t, __SVBfloat16_t);
void f(__SVMfloat8_t, __SVMfloat8_t);
void f(__SVBool_t, __SVBool_t);
void f(__SVCount_t, __SVCount_t);

Expand Down Expand Up @@ -150,6 +151,7 @@ void f(__clang_svboolx4_t, __clang_svboolx4_t);
// CHECK-NEXT: call void @_Z1fu13__SVFloat16_tS_(<vscale x 8 x half> zeroinitializer, <vscale x 8 x half> zeroinitializer)
// CHECK-NEXT: call void @_Z1fu13__SVFloat32_tS_(<vscale x 4 x float> zeroinitializer, <vscale x 4 x float> zeroinitializer)
// CHECK-NEXT: call void @_Z1fu13__SVFloat64_tS_(<vscale x 2 x double> zeroinitializer, <vscale x 2 x double> zeroinitializer)
// CHECK-NEXT: call void @_Z1fu13__SVMfloat8_tS_(<vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8> zeroinitializer)
// CHECK-NEXT: call void @_Z1fu14__SVBfloat16_tS_(<vscale x 8 x bfloat> zeroinitializer, <vscale x 8 x bfloat> zeroinitializer)
// CHECK-NEXT: call void @_Z1fu10__SVBool_tS_(<vscale x 16 x i1> zeroinitializer, <vscale x 16 x i1> zeroinitializer)
// CHECK-NEXT: call void @_Z1fu11__SVCount_tS_(target("aarch64.svcount") zeroinitializer, target("aarch64.svcount") zeroinitializer)
Expand Down Expand Up @@ -664,6 +666,7 @@ void f(__clang_svboolx4_t, __clang_svboolx4_t);
// COMPAT_17-NEXT: call void @_Z1fu13__SVFloat16_tu13__SVFloat16_t(<vscale x 8 x half> zeroinitializer, <vscale x 8 x half> zeroinitializer)
// COMPAT_17-NEXT: call void @_Z1fu13__SVFloat32_tu13__SVFloat32_t(<vscale x 4 x float> zeroinitializer, <vscale x 4 x float> zeroinitializer)
// COMPAT_17-NEXT: call void @_Z1fu13__SVFloat64_tu13__SVFloat64_t(<vscale x 2 x double> zeroinitializer, <vscale x 2 x double> zeroinitializer)
// COMPAT_17-NEXT: call void @_Z1fu13__SVMfloat8_tu13__SVMfloat8_t(<vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8> zeroinitializer)
// COMPAT_17-NEXT: call void @_Z1fu14__SVBFloat16_tu14__SVBFloat16_t(<vscale x 8 x bfloat> zeroinitializer, <vscale x 8 x bfloat> zeroinitializer)
// COMPAT_17-NEXT: call void @_Z1fu10__SVBool_tu10__SVBool_t(<vscale x 16 x i1> zeroinitializer, <vscale x 16 x i1> zeroinitializer)
// COMPAT_17-NEXT: call void @_Z1fu11__SVCount_tu11__SVCount_t(target("aarch64.svcount") zeroinitializer, target("aarch64.svcount") zeroinitializer)
Expand Down Expand Up @@ -1100,6 +1103,7 @@ void foo() {
f(__SVFloat16_t(), __SVFloat16_t());
f(__SVFloat32_t(), __SVFloat32_t());
f(__SVFloat64_t(), __SVFloat64_t());
f(__SVMfloat8_t(), __SVMfloat8_t());
f(__SVBfloat16_t(), __SVBfloat16_t());
f(__SVBool_t(), __SVBool_t());
f(__SVCount_t(), __SVCount_t());
Expand Down
5 changes: 5 additions & 0 deletions clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ auto &f64 = typeid(__SVFloat64_t);

auto &bf16 = typeid(__SVBfloat16_t);

auto &mf8 = typeid(__SVMfloat8_t);

auto &b8 = typeid(__SVBool_t);
auto &c8 = typeid(__SVCount_t);

Expand Down Expand Up @@ -60,6 +62,9 @@ auto &c8 = typeid(__SVCount_t);
// CHECK-DAG: @_ZTSu14__SVBfloat16_t = {{.*}} c"u14__SVBfloat16_t\00"
// CHECK-DAG: @_ZTIu14__SVBfloat16_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu14__SVBfloat16_t

// CHECK-DAG: @_ZTSu13__SVMfloat8_t = {{.*}} c"u13__SVMfloat8_t\00"
// CHECK-DAG: @_ZTIu13__SVMfloat8_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu13__SVMfloat8_t

// CHECK-DAG: @_ZTSu10__SVBool_t = {{.*}} c"u10__SVBool_t\00"
// CHECK-DAG: @_ZTIu10__SVBool_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu10__SVBool_t

Expand Down
17 changes: 17 additions & 0 deletions clang/test/CodeGenCXX/aarch64-sve-vector-init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// CHECK-NEXT: [[U16:%.*]] = alloca <vscale x 8 x i16>, align 16
// CHECK-NEXT: [[U32:%.*]] = alloca <vscale x 4 x i32>, align 16
// CHECK-NEXT: [[U64:%.*]] = alloca <vscale x 2 x i64>, align 16
// CHECK-NEXT: [[MF8:%.*]] = alloca <vscale x 16 x i8>, align 16
// CHECK-NEXT: [[F16:%.*]] = alloca <vscale x 8 x half>, align 16
// CHECK-NEXT: [[F32:%.*]] = alloca <vscale x 4 x float>, align 16
// CHECK-NEXT: [[F64:%.*]] = alloca <vscale x 2 x double>, align 16
Expand Down Expand Up @@ -64,6 +65,7 @@
// CHECK-NEXT: store <vscale x 8 x i16> zeroinitializer, ptr [[U16]], align 16
// CHECK-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[U32]], align 16
// CHECK-NEXT: store <vscale x 2 x i64> zeroinitializer, ptr [[U64]], align 16
// CHECK-NEXT: store <vscale x 16 x i8> zeroinitializer, ptr [[MF8]], align 16
// CHECK-NEXT: store <vscale x 8 x half> zeroinitializer, ptr [[F16]], align 16
// CHECK-NEXT: store <vscale x 4 x float> zeroinitializer, ptr [[F32]], align 16
// CHECK-NEXT: store <vscale x 2 x double> zeroinitializer, ptr [[F64]], align 16
Expand Down Expand Up @@ -119,6 +121,7 @@ void test_locals(void) {
__SVUint16_t u16{};
__SVUint32_t u32{};
__SVUint64_t u64{};
__SVMfloat8_t mf8{};
__SVFloat16_t f16{};
__SVFloat32_t f32{};
__SVFloat64_t f64{};
Expand Down Expand Up @@ -282,6 +285,20 @@ void test_copy_u64(__SVUint64_t a) {
__SVUint64_t b{a};
}

// CHECK-LABEL: define dso_local void @_Z13test_copy_mf8u13__SVMfloat8_t
// CHECK-SAME: (<vscale x 16 x i8> [[A:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <vscale x 16 x i8>, align 16
// CHECK-NEXT: [[B:%.*]] = alloca <vscale x 16 x i8>, align 16
// CHECK-NEXT: store <vscale x 16 x i8> [[A]], ptr [[A_ADDR]], align 16
// CHECK-NEXT: [[TMP0:%.*]] = load <vscale x 16 x i8>, ptr [[A_ADDR]], align 16
// CHECK-NEXT: store <vscale x 16 x i8> [[TMP0]], ptr [[B]], align 16
// CHECK-NEXT: ret void
//
void test_copy_mf8(__SVMfloat8_t a) {
__SVMfloat8_t b{a};
}

// CHECK-LABEL: define dso_local void @_Z13test_copy_f16u13__SVFloat16_t
// CHECK-SAME: (<vscale x 8 x half> [[A:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
Expand Down
20 changes: 10 additions & 10 deletions clang/test/CodeGenHLSL/builtins/WaveReadLaneAt.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,65 +10,65 @@
// CHECK-LABEL: test_int
int test_int(int expr, uint idx) {
// CHECK-SPIRV: %[[#entry_tok0:]] = call token @llvm.experimental.convergence.entry()
// CHECK-SPIRV: %[[RET:.*]] = call [[TY:.*]] @llvm.spv.wave.readlane.i32([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok0]]) ]
// CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.readlane.i32([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok0]]) ]
// CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.readlane.i32([[TY]] %[[#]], i32 %[[#]])
// CHECK: ret [[TY]] %[[RET]]
return WaveReadLaneAt(expr, idx);
}

// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.i32([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.i32([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.i32([[TY]], i32) #[[#attr:]]

#ifdef __HLSL_ENABLE_16_BIT
// CHECK-LABEL: test_int16
int16_t test_int16(int16_t expr, uint idx) {
// CHECK-SPIRV: %[[#entry_tok1:]] = call token @llvm.experimental.convergence.entry()
// CHECK-SPIRV: %[[RET:.*]] = call [[TY:.*]] @llvm.spv.wave.readlane.i16([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok1]]) ]
// CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.readlane.i16([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok1]]) ]
// CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.readlane.i16([[TY]] %[[#]], i32 %[[#]])
// CHECK: ret [[TY]] %[[RET]]
return WaveReadLaneAt(expr, idx);
}

// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.i16([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.i16([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.i16([[TY]], i32) #[[#attr:]]
#endif

// Test basic lowering to runtime function call with array and float values.

// CHECK-LABEL: test_half
half test_half(half expr, uint idx) {
// CHECK-SPIRV: %[[#entry_tok2:]] = call token @llvm.experimental.convergence.entry()
// CHECK-SPIRV: %[[RET:.*]] = call [[TY:.*]] @llvm.spv.wave.readlane.f16([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok2]]) ]
// CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.readlane.f16([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok2]]) ]
// CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.readlane.f16([[TY]] %[[#]], i32 %[[#]])
// CHECK: ret [[TY]] %[[RET]]
return WaveReadLaneAt(expr, idx);
}

// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.f16([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.f16([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.f16([[TY]], i32) #[[#attr:]]

// CHECK-LABEL: test_double
double test_double(double expr, uint idx) {
// CHECK-SPIRV: %[[#entry_tok3:]] = call token @llvm.experimental.convergence.entry()
// CHECK-SPIRV: %[[RET:.*]] = call [[TY:.*]] @llvm.spv.wave.readlane.f64([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok3]]) ]
// CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.readlane.f64([[TY]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok3]]) ]
// CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.readlane.f64([[TY]] %[[#]], i32 %[[#]])
// CHECK: ret [[TY]] %[[RET]]
return WaveReadLaneAt(expr, idx);
}

// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.f64([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.f64([[TY]], i32) #[[#attr:]]
// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.f64([[TY]], i32) #[[#attr:]]

// CHECK-LABEL: test_floatv4
float4 test_floatv4(float4 expr, uint idx) {
// CHECK-SPIRV: %[[#entry_tok4:]] = call token @llvm.experimental.convergence.entry()
// CHECK-SPIRV: %[[RET1:.*]] = call [[TY1:.*]] @llvm.spv.wave.readlane.v4f32([[TY1]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok4]]) ]
// CHECK-SPIRV: %[[RET1:.*]] = call spir_func [[TY1:.*]] @llvm.spv.wave.readlane.v4f32([[TY1]] %[[#]], i32 %[[#]]) [ "convergencectrl"(token %[[#entry_tok4]]) ]
// CHECK-DXIL: %[[RET1:.*]] = call [[TY1:.*]] @llvm.dx.wave.readlane.v4f32([[TY1]] %[[#]], i32 %[[#]])
// CHECK: ret [[TY1]] %[[RET1]]
return WaveReadLaneAt(expr, idx);
}

// CHECK-DXIL: declare [[TY1]] @llvm.dx.wave.readlane.v4f32([[TY1]], i32) #[[#attr]]
// CHECK-SPIRV: declare [[TY1]] @llvm.spv.wave.readlane.v4f32([[TY1]], i32) #[[#attr]]
// CHECK-SPIRV: declare spir_func [[TY1]] @llvm.spv.wave.readlane.v4f32([[TY1]], i32) #[[#attr]]

// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}}
8 changes: 4 additions & 4 deletions clang/test/CodeGenHLSL/builtins/sign.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -202,19 +202,19 @@ int4 test_sign_int64_t4(int64_t4 p0) { return sign(p0); }
// CHECK: define [[FNATTRS]] i32 @
// CHECK: [[CMP:%.*]] = icmp eq i64 [[ARG:%.*]], 0
// CHECK: %hlsl.sign = select i1 [[CMP]], i32 0, i32 1
int test_sign_int64_t(uint64_t p0) { return sign(p0); }
int test_sign_uint64_t(uint64_t p0) { return sign(p0); }

// CHECK: define [[FNATTRS]] <2 x i32> @
// CHECK: [[CMP:%.*]] = icmp eq <2 x i64> [[ARG:%.*]], zeroinitializer
// CHECK: %hlsl.sign = select <2 x i1> [[CMP]], <2 x i32> zeroinitializer, <2 x i32> <i32 1, i32 1>
int2 test_sign_int64_t2(uint64_t2 p0) { return sign(p0); }
int2 test_sign_uint64_t2(uint64_t2 p0) { return sign(p0); }

// CHECK: define [[FNATTRS]] <3 x i32> @
// CHECK: [[CMP:%.*]] = icmp eq <3 x i64> [[ARG:%.*]], zeroinitializer
// CHECK: %hlsl.sign = select <3 x i1> [[CMP]], <3 x i32> zeroinitializer, <3 x i32> <i32 1, i32 1, i32 1>
int3 test_sign_int64_t3(uint64_t3 p0) { return sign(p0); }
int3 test_sign_uint64_t3(uint64_t3 p0) { return sign(p0); }

// CHECK: define [[FNATTRS]] <4 x i32> @
// CHECK: [[CMP:%.*]] = icmp eq <4 x i64> [[ARG:%.*]], zeroinitializer
// CHECK: %hlsl.sign = select <4 x i1> [[CMP]], <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
int4 test_sign_int64_t4(uint64_t4 p0) { return sign(p0); }
int4 test_sign_uint64_t4(uint64_t4 p0) { return sign(p0); }
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void main() {
// CHECK: br i1 {{%.+}}, label %[[LABEL_IF_THEN:.+]], label %[[LABEL_IF_END:.+]]

// CHECK: [[LABEL_IF_THEN]]:
// CHECK: call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[CT_LOOP]]) ]
// CHECK: call spir_func i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[CT_LOOP]]) ]
// CHECK: br label %[[LABEL_WHILE_END:.+]]
if (cond == 2) {
uint index = WaveGetLaneIndex();
Expand All @@ -33,7 +33,7 @@ void main() {
// CHECK: ret void
}

// CHECK-DAG: declare i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]]
// CHECK-DAG: declare spir_func i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]]

// CHECK-DAG: attributes [[A0]] = {{{.*}}convergent{{.*}}}
// CHECK-DAG: attributes [[A1]] = {{{.*}}convergent{{.*}}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
// CHECK-SPIRV: define spir_func noundef i32 @{{.*test_1.*}}() [[A0:#[0-9]+]] {
// CHECK-DXIL: define noundef i32 @{{.*test_1.*}}() [[A0:#[0-9]+]] {
// CHECK-SPIRV: %[[CI:[0-9]+]] = call token @llvm.experimental.convergence.entry()
// CHECK-SPIRV: call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[CI]]) ]
// CHECK-SPIRV: call spir_func i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[CI]]) ]
// CHECK-DXIL: call i32 @llvm.dx.wave.getlaneindex()
int test_1() {
return WaveGetLaneIndex();
}

// CHECK-SPIRV: declare i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]]
// CHECK-SPIRV: declare spir_func i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]]
// CHECK-DXIL: declare i32 @llvm.dx.wave.getlaneindex() [[A1:#[0-9]+]]

// CHECK-DAG: attributes [[A0]] = { {{.*}}convergent{{.*}} }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

// CHECK: define spir_func noundef i32 @_Z6test_1v() [[A0:#[0-9]+]] {
// CHECK: %[[C1:[0-9]+]] = call token @llvm.experimental.convergence.entry()
// CHECK: call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[C1]]) ]
// CHECK: call spir_func i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[C1]]) ]
uint test_1() {
return WaveGetLaneIndex();
}

// CHECK-DAG: declare i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]]
// CHECK-DAG: declare spir_func i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]]

// CHECK: define spir_func noundef i32 @_Z6test_2v() [[A0]] {
// CHECK: %[[C2:[0-9]+]] = call token @llvm.experimental.convergence.entry()
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenHLSL/builtins/wave_is_first_lane.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ void main() {
while (true) {

// CHECK-DXIL: %[[#]] = call i1 @llvm.dx.wave.is.first.lane()
// CHECK-SPIRV: %[[#]] = call i1 @llvm.spv.wave.is.first.lane()
// CHECK-SPIRV: %[[#]] = call spir_func i1 @llvm.spv.wave.is.first.lane()
// CHECK-SPIRV-SAME: [ "convergencectrl"(token %[[#loop_tok]]) ]
if (WaveIsFirstLane()) {
break;
}
}

// CHECK-DXIL: %[[#]] = call i1 @llvm.dx.wave.is.first.lane()
// CHECK-SPIRV: %[[#]] = call i1 @llvm.spv.wave.is.first.lane()
// CHECK-SPIRV: %[[#]] = call spir_func i1 @llvm.spv.wave.is.first.lane()
// CHECK-SPIRV-SAME: [ "convergencectrl"(token %[[#entry_tok]]) ]
if (WaveIsFirstLane()) {
return;
Expand Down
3 changes: 3 additions & 0 deletions clang/test/CodeGenObjC/aarch64-sve-types.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@
// CHECK: error: cannot yet @encode type __SVBfloat16_t
const char bf16[] = @encode(__SVBfloat16_t);

// CHECK: error: cannot yet @encode type __SVMfloat8_t
const char mf8[] = @encode(__SVMfloat8_t);

// CHECK: error: cannot yet @encode type __SVBool_t
const char b8[] = @encode(__SVBool_t);
1,252 changes: 1,171 additions & 81 deletions clang/test/CodeGenOpenCL/addr-space-struct-arg.cl

Large diffs are not rendered by default.

122 changes: 81 additions & 41 deletions clang/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
Original file line number Diff line number Diff line change
@@ -1,67 +1,107 @@
// RUN: %clang_cc1 -O0 -cl-std=CL1.2 -triple amdgcn---amdgizcl -emit-llvm %s -o - | FileCheck -check-prefixes=CHECK,CL12 %s
// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple amdgcn---amdgizcl -emit-llvm %s -o - | FileCheck -check-prefixes=CHECK,CL20 %s
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// RUN: %clang_cc1 -O0 -cl-std=CL1.2 -triple amdgcn-amd-amdhsa -emit-llvm %s -o - | FileCheck -check-prefixes=CL12 %s
// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple amdgcn-amd-amdhsa -emit-llvm %s -o - | FileCheck -check-prefixes=CL20 %s

// CL12-LABEL: define{{.*}} void @func1(ptr addrspace(5) noundef %x)
// CL20-LABEL: define{{.*}} void @func1(ptr noundef %x)
// CL12-LABEL: define dso_local void @func1(
// CL12-SAME: ptr addrspace(5) noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
// CL12-NEXT: [[ENTRY:.*:]]
// CL12-NEXT: [[X_ADDR:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// CL12-NEXT: store ptr addrspace(5) [[X]], ptr addrspace(5) [[X_ADDR]], align 4
// CL12-NEXT: [[TMP0:%.*]] = load ptr addrspace(5), ptr addrspace(5) [[X_ADDR]], align 4
// CL12-NEXT: store i32 1, ptr addrspace(5) [[TMP0]], align 4
// CL12-NEXT: ret void
//
// CL20-LABEL: define dso_local void @func1(
// CL20-SAME: ptr noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
// CL20-NEXT: [[ENTRY:.*:]]
// CL20-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8, addrspace(5)
// CL20-NEXT: store ptr [[X]], ptr addrspace(5) [[X_ADDR]], align 8
// CL20-NEXT: [[TMP0:%.*]] = load ptr, ptr addrspace(5) [[X_ADDR]], align 8
// CL20-NEXT: store i32 1, ptr [[TMP0]], align 4
// CL20-NEXT: ret void
//
void func1(int *x) {
// CL12: %[[x_addr:.*]] = alloca ptr addrspace(5){{.*}}addrspace(5)
// CL12: store ptr addrspace(5) %x, ptr addrspace(5) %[[x_addr]]
// CL12: %[[r0:.*]] = load ptr addrspace(5), ptr addrspace(5) %[[x_addr]]
// CL12: store i32 1, ptr addrspace(5) %[[r0]]
// CL20: %[[x_addr:.*]] = alloca ptr{{.*}}addrspace(5)
// CL20: store ptr %x, ptr addrspace(5) %[[x_addr]]
// CL20: %[[r0:.*]] = load ptr, ptr addrspace(5) %[[x_addr]]
// CL20: store i32 1, ptr %[[r0]]
*x = 1;
}

// CHECK-LABEL: define{{.*}} void @func2()
// CL12-LABEL: define dso_local void @func2(
// CL12-SAME: ) #[[ATTR0]] {
// CL12-NEXT: [[ENTRY:.*:]]
// CL12-NEXT: [[LV1:%.*]] = alloca i32, align 4, addrspace(5)
// CL12-NEXT: [[LV2:%.*]] = alloca i32, align 4, addrspace(5)
// CL12-NEXT: [[LA:%.*]] = alloca [100 x i32], align 4, addrspace(5)
// CL12-NEXT: [[LP1:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// CL12-NEXT: [[LP2:%.*]] = alloca ptr addrspace(5), align 4, addrspace(5)
// CL12-NEXT: [[LVC:%.*]] = alloca i32, align 4, addrspace(5)
// CL12-NEXT: store i32 1, ptr addrspace(5) [[LV1]], align 4
// CL12-NEXT: store i32 2, ptr addrspace(5) [[LV2]], align 4
// CL12-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i32], ptr addrspace(5) [[LA]], i64 0, i64 0
// CL12-NEXT: store i32 3, ptr addrspace(5) [[ARRAYIDX]], align 4
// CL12-NEXT: store ptr addrspace(5) [[LV1]], ptr addrspace(5) [[LP1]], align 4
// CL12-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [100 x i32], ptr addrspace(5) [[LA]], i64 0, i64 0
// CL12-NEXT: store ptr addrspace(5) [[ARRAYDECAY]], ptr addrspace(5) [[LP2]], align 4
// CL12-NEXT: call void @func1(ptr addrspace(5) noundef [[LV1]]) #[[ATTR2:[0-9]+]]
// CL12-NEXT: store i32 4, ptr addrspace(5) [[LVC]], align 4
// CL12-NEXT: store i32 4, ptr addrspace(5) [[LV1]], align 4
// CL12-NEXT: ret void
//
// CL20-LABEL: define dso_local void @func2(
// CL20-SAME: ) #[[ATTR0]] {
// CL20-NEXT: [[ENTRY:.*:]]
// CL20-NEXT: [[LV1:%.*]] = alloca i32, align 4, addrspace(5)
// CL20-NEXT: [[LV2:%.*]] = alloca i32, align 4, addrspace(5)
// CL20-NEXT: [[LA:%.*]] = alloca [100 x i32], align 4, addrspace(5)
// CL20-NEXT: [[LP1:%.*]] = alloca ptr, align 8, addrspace(5)
// CL20-NEXT: [[LP2:%.*]] = alloca ptr, align 8, addrspace(5)
// CL20-NEXT: [[LVC:%.*]] = alloca i32, align 4, addrspace(5)
// CL20-NEXT: store i32 1, ptr addrspace(5) [[LV1]], align 4
// CL20-NEXT: store i32 2, ptr addrspace(5) [[LV2]], align 4
// CL20-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i32], ptr addrspace(5) [[LA]], i64 0, i64 0
// CL20-NEXT: store i32 3, ptr addrspace(5) [[ARRAYIDX]], align 4
// CL20-NEXT: [[LV1_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[LV1]] to ptr
// CL20-NEXT: store ptr [[LV1_ASCAST]], ptr addrspace(5) [[LP1]], align 8
// CL20-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [100 x i32], ptr addrspace(5) [[LA]], i64 0, i64 0
// CL20-NEXT: [[ARRAYDECAY_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ARRAYDECAY]] to ptr
// CL20-NEXT: store ptr [[ARRAYDECAY_ASCAST]], ptr addrspace(5) [[LP2]], align 8
// CL20-NEXT: [[LV1_ASCAST1:%.*]] = addrspacecast ptr addrspace(5) [[LV1]] to ptr
// CL20-NEXT: call void @func1(ptr noundef [[LV1_ASCAST1]]) #[[ATTR2:[0-9]+]]
// CL20-NEXT: store i32 4, ptr addrspace(5) [[LVC]], align 4
// CL20-NEXT: store i32 4, ptr addrspace(5) [[LV1]], align 4
// CL20-NEXT: ret void
//
void func2(void) {
// CHECK: %lv1 = alloca i32, align 4, addrspace(5)
// CHECK: %lv2 = alloca i32, align 4, addrspace(5)
// CHECK: %la = alloca [100 x i32], align 4, addrspace(5)
// CL12: %lp1 = alloca ptr addrspace(5), align 4, addrspace(5)
// CL12: %lp2 = alloca ptr addrspace(5), align 4, addrspace(5)
// CL20: %lp1 = alloca ptr, align 8, addrspace(5)
// CL20: %lp2 = alloca ptr, align 8, addrspace(5)
// CHECK: %lvc = alloca i32, align 4, addrspace(5)

// CHECK: store i32 1, ptr addrspace(5) %lv1
int lv1;
lv1 = 1;
// CHECK: store i32 2, ptr addrspace(5) %lv2

int lv2 = 2;

// CHECK: %[[arrayidx:.*]] = getelementptr inbounds [100 x i32], ptr addrspace(5) %la, i64 0, i64 0
// CHECK: store i32 3, ptr addrspace(5) %[[arrayidx]], align 4
int la[100];
la[0] = 3;

// CL12: store ptr addrspace(5) %lv1, ptr addrspace(5) %lp1, align 4
// CL20: %[[r0:.*]] = addrspacecast ptr addrspace(5) %lv1 to ptr
// CL20: store ptr %[[r0]], ptr addrspace(5) %lp1, align 8
int *lp1 = &lv1;

// CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], ptr addrspace(5) %la, i64 0, i64 0
// CL12: store ptr addrspace(5) %[[arraydecay]], ptr addrspace(5) %lp2, align 4
// CL20: %[[r1:.*]] = addrspacecast ptr addrspace(5) %[[arraydecay]] to ptr
// CL20: store ptr %[[r1]], ptr addrspace(5) %lp2, align 8
int *lp2 = la;

// CL12: call void @func1(ptr addrspace(5) noundef %lv1)
// CL20: %[[r2:.*]] = addrspacecast ptr addrspace(5) %lv1 to ptr
// CL20: call void @func1(ptr noundef %[[r2]])
func1(&lv1);

// CHECK: store i32 4, ptr addrspace(5) %lvc
// CHECK: store i32 4, ptr addrspace(5) %lv1
const int lvc = 4;
lv1 = lvc;
}

// CHECK-LABEL: define{{.*}} void @func3()
// CHECK: %a = alloca [16 x [1 x float]], align 4, addrspace(5)
// CHECK: call void @llvm.memset.p5.i64(ptr addrspace(5) align 4 %a, i8 0, i64 64, i1 false)
// CL12-LABEL: define dso_local void @func3(
// CL12-SAME: ) #[[ATTR0]] {
// CL12-NEXT: [[ENTRY:.*:]]
// CL12-NEXT: [[A:%.*]] = alloca [16 x [1 x float]], align 4, addrspace(5)
// CL12-NEXT: call void @llvm.memset.p5.i64(ptr addrspace(5) align 4 [[A]], i8 0, i64 64, i1 false)
// CL12-NEXT: ret void
//
// CL20-LABEL: define dso_local void @func3(
// CL20-SAME: ) #[[ATTR0]] {
// CL20-NEXT: [[ENTRY:.*:]]
// CL20-NEXT: [[A:%.*]] = alloca [16 x [1 x float]], align 4, addrspace(5)
// CL20-NEXT: call void @llvm.memset.p5.i64(ptr addrspace(5) align 4 [[A]], i8 0, i64 64, i1 false)
// CL20-NEXT: ret void
//
void func3(void) {
float a[16][1] = {{0.}};
}
21 changes: 21 additions & 0 deletions clang/test/CodeGenOpenCL/pipe_builtin.cl
Original file line number Diff line number Diff line change
@@ -1,69 +1,90 @@
// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -cl-ext=+cl_khr_subgroups -O0 -cl-std=clc++ -o - %s | FileCheck --check-prefix=CHECK-SPIR %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -cl-ext=+cl_khr_subgroups -O0 -cl-std=clc++ -o - %s | FileCheck %s
// FIXME: Add MS ABI manglings of OpenCL things and remove %itanium_abi_triple
// above to support OpenCL in the MS C++ ABI.

#pragma OPENCL EXTENSION cl_khr_subgroups : enable

void test1(read_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func i32 @__read_pipe_2(target("spirv.Pipe", 0) %{{.*}}, ptr addrspace(4) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__read_pipe_2(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
read_pipe(p, ptr);
// CHECK-SPIR: call spir_func target("spirv.ReserveId") @__reserve_read_pipe(target("spirv.Pipe", 0) %{{.*}}, i32 {{.*}}, i32 4, i32 4)
// CHECK: call ptr @__reserve_read_pipe(ptr %{{.*}}, i32 {{.*}}, i32 4, i32 4)
reserve_id_t rid = reserve_read_pipe(p, 2);
// CHECK-SPIR: call spir_func i32 @__read_pipe_4(target("spirv.Pipe", 0) %{{.*}}, ptr addrspace(4) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__read_pipe_4(ptr %{{.*}}, ptr %{{.*}}, i32 {{.*}}, ptr %{{.*}}, i32 4, i32 4)
read_pipe(p, rid, 2, ptr);
// CHECK-SPIR: call spir_func void @__commit_read_pipe(target("spirv.Pipe", 0) %{{.*}}, target("spirv.ReserveId") %{{.*}}, i32 4, i32 4)
// CHECK: call void @__commit_read_pipe(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
commit_read_pipe(p, rid);
}

void test2(write_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func i32 @__write_pipe_2(target("spirv.Pipe", 1) %{{.*}}, ptr addrspace(4) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__write_pipe_2(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
write_pipe(p, ptr);
// CHECK-SPIR: call spir_func target("spirv.ReserveId") @__reserve_write_pipe(target("spirv.Pipe", 1) %{{.*}}, i32 {{.*}}, i32 4, i32 4)
// CHECK: call ptr @__reserve_write_pipe(ptr %{{.*}}, i32 {{.*}}, i32 4, i32 4)
reserve_id_t rid = reserve_write_pipe(p, 2);
// CHECK-SPIR: call spir_func i32 @__write_pipe_4(target("spirv.Pipe", 1) %{{.*}}, ptr addrspace(4) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__write_pipe_4(ptr %{{.*}}, ptr %{{.*}}, i32 {{.*}}, ptr %{{.*}}, i32 4, i32 4)
write_pipe(p, rid, 2, ptr);
// CHECK-SPIR: call spir_func void @__commit_write_pipe(target("spirv.Pipe", 1) %{{.*}}, target("spirv.ReserveId") %{{.*}}, i32 4, i32 4)
// CHECK: call void @__commit_write_pipe(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
commit_write_pipe(p, rid);
}

void test3(read_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func target("spirv.ReserveId") @__work_group_reserve_read_pipe(target("spirv.Pipe", 0) %{{.*}}, i32 {{.*}}, i32 4, i32 4)
// CHECK: call ptr @__work_group_reserve_read_pipe(ptr %{{.*}}, i32 {{.*}}, i32 4, i32 4)
reserve_id_t rid = work_group_reserve_read_pipe(p, 2);
// CHECK-SPIR: call spir_func void @__work_group_commit_read_pipe(target("spirv.Pipe", 0) %{{.*}}, target("spirv.ReserveId") %{{.*}}, i32 4, i32 4)
// CHECK: call void @__work_group_commit_read_pipe(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
work_group_commit_read_pipe(p, rid);
}

void test4(write_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func target("spirv.ReserveId") @__work_group_reserve_write_pipe(target("spirv.Pipe", 1) %{{.*}}, i32 {{.*}}, i32 4, i32 4)
// CHECK: call ptr @__work_group_reserve_write_pipe(ptr %{{.*}}, i32 {{.*}}, i32 4, i32 4)
reserve_id_t rid = work_group_reserve_write_pipe(p, 2);
// CHECK-SPIR: call spir_func void @__work_group_commit_write_pipe(target("spirv.Pipe", 1) %{{.*}}, target("spirv.ReserveId") %{{.*}}, i32 4, i32 4)
// CHECK: call void @__work_group_commit_write_pipe(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
work_group_commit_write_pipe(p, rid);
}

void test5(read_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func target("spirv.ReserveId") @__sub_group_reserve_read_pipe(target("spirv.Pipe", 0) %{{.*}}, i32 {{.*}}, i32 4, i32 4)
// CHECK: call ptr @__sub_group_reserve_read_pipe(ptr %{{.*}}, i32 {{.*}}, i32 4, i32 4)
reserve_id_t rid = sub_group_reserve_read_pipe(p, 2);
// CHECK-SPIR: call spir_func void @__sub_group_commit_read_pipe(target("spirv.Pipe", 0) %{{.*}}, target("spirv.ReserveId") %{{.*}}, i32 4, i32 4)
// CHECK: call void @__sub_group_commit_read_pipe(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
sub_group_commit_read_pipe(p, rid);
}

void test6(write_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func target("spirv.ReserveId") @__sub_group_reserve_write_pipe(target("spirv.Pipe", 1) %{{.*}}, i32 {{.*}}, i32 4, i32 4)
// CHECK: call ptr @__sub_group_reserve_write_pipe(ptr %{{.*}}, i32 {{.*}}, i32 4, i32 4)
reserve_id_t rid = sub_group_reserve_write_pipe(p, 2);
// CHECK-SPIR: call spir_func void @__sub_group_commit_write_pipe(target("spirv.Pipe", 1) %{{.*}}, target("spirv.ReserveId") %{{.*}}, i32 4, i32 4)
// CHECK: call void @__sub_group_commit_write_pipe(ptr %{{.*}}, ptr %{{.*}}, i32 4, i32 4)
sub_group_commit_write_pipe(p, rid);
}

void test7(read_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func i32 @__get_pipe_num_packets_ro(target("spirv.Pipe", 0) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__get_pipe_num_packets_ro(ptr %{{.*}}, i32 4, i32 4)
*ptr = get_pipe_num_packets(p);
// CHECK-SPIR: call spir_func i32 @__get_pipe_max_packets_ro(target("spirv.Pipe", 0) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__get_pipe_max_packets_ro(ptr %{{.*}}, i32 4, i32 4)
*ptr = get_pipe_max_packets(p);
}

void test8(write_only pipe int p, global int *ptr) {
// CHECK-SPIR: call spir_func i32 @__get_pipe_num_packets_wo(target("spirv.Pipe", 1) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__get_pipe_num_packets_wo(ptr %{{.*}}, i32 4, i32 4)
*ptr = get_pipe_num_packets(p);
// CHECK-SPIR: call spir_func i32 @__get_pipe_max_packets_wo(target("spirv.Pipe", 1) %{{.*}}, i32 4, i32 4)
// CHECK: call i32 @__get_pipe_max_packets_wo(ptr %{{.*}}, i32 4, i32 4)
*ptr = get_pipe_max_packets(p);
}
42 changes: 39 additions & 3 deletions clang/test/Driver/aarch64-v96a.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,50 @@
// RUN: %clang -target aarch64 -mlittle-endian -march=armv9.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A %s
// RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A %s
// RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A %s
// GENERICV96A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"
// GENERICV96A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+cmpbr"{{.*}} "-target-feature" "+fprcvt"{{.*}} "-target-feature" "+sve2p2"

// RUN: %clang -target aarch64_be -march=armv9.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A-BE %s
// RUN: %clang -target aarch64_be -march=armv9.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A-BE %s
// RUN: %clang -target aarch64 -mbig-endian -march=armv9.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A-BE %s
// RUN: %clang -target aarch64 -mbig-endian -march=armv9.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -march=armv9.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -march=armv9.6-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV96A-BE %s
// GENERICV96A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"
//
// GENERICV96A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+cmpbr"{{.*}} "-target-feature" "+fprcvt"{{.*}} "-target-feature" "+sve2p2"

// ===== Features supported on aarch64 =====

// RUN: %clang -target aarch64 -march=armv9.6a+f8f16mm -### -c %s 2>&1 | FileCheck -check-prefix=V96A-F8F16MM %s
// RUN: %clang -target aarch64 -march=armv9.6-a+f8f16mm -### -c %s 2>&1 | FileCheck -check-prefix=V96A-F8F16MM %s
// V96A-F8F16MM: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+f8f16mm"

// RUN: %clang -target aarch64 -march=armv9.6a+f8f32mm -### -c %s 2>&1 | FileCheck -check-prefix=V96A-F8F32MM %s
// RUN: %clang -target aarch64 -march=armv9.6-a+f8f32mm -### -c %s 2>&1 | FileCheck -check-prefix=V96A-F8F32MM %s
// V96A-F8F32MM: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+f8f32mm"

// RUN: %clang -target aarch64 -march=armv9.6a+lsfe -### -c %s 2>&1 | FileCheck -check-prefix=V96A-LSFE %s
// RUN: %clang -target aarch64 -march=armv9.6-a+lsfe -### -c %s 2>&1 | FileCheck -check-prefix=V96A-LSFE %s
// V96A-LSFE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+lsfe"

// RUN: %clang -target aarch64 -march=armv9.6a+sme2p2 -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SME2p2 %s
// RUN: %clang -target aarch64 -march=armv9.6-a+sme2p2 -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SME2p2 %s
// V96A-SME2p2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+sme2p2"

// RUN: %clang -target aarch64 -march=armv9.6a+ssve-aes -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SSVE-AES %s
// RUN: %clang -target aarch64 -march=armv9.6-a+ssve-aes -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SSVE-AES %s
// V96A-SSVE-AES: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+ssve-aes"

// RUN: %clang -target aarch64 -march=armv9.6a+sve2p2 -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE2p2 %s
// RUN: %clang -target aarch64 -march=armv9.6-a+sve2p2 -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE2p2 %s
// V96A-SVE2p2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+sve2p2"

// RUN: %clang -target aarch64 -march=armv9.6a+sve-aes2 -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE-AES2 %s
// RUN: %clang -target aarch64 -march=armv9.6-a+sve-aes2 -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE-AES2 %s
// V96A-SVE-AES2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+sve-aes2"

// RUN: %clang -target aarch64 -march=armv9.6a+sve-bfscale -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE-BFSCALE %s
// RUN: %clang -target aarch64 -march=armv9.6-a+sve-bfscale -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE-BFSCALE %s
// V96A-SVE-BFSCALE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+sve-bfscale"

// RUN: %clang -target aarch64 -march=armv9.6a+sve-f16f32mm -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE-F16F32MM %s
// RUN: %clang -target aarch64 -march=armv9.6-a+sve-f16f32mm -### -c %s 2>&1 | FileCheck -check-prefix=V96A-SVE-F16F32MM %s
// V96A-SVE-F16F32MM: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.6a"{{.*}} "-target-feature" "+sve-f16f32mm"
3 changes: 3 additions & 0 deletions clang/test/Driver/cl-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,9 @@
// RUN: %clang_cl -fmsc-version=1900 -TP -std:c++20 -### -- %s 2>&1 | FileCheck -check-prefix=STDCXX20 %s
// STDCXX20: -std=c++20

// RUN: %clang_cl -fmsc-version=1900 -TP -std:c++23preview -### -- %s 2>&1 | FileCheck -check-prefix=STDCXX23PREVIEW %s
// STDCXX23PREVIEW: -std=c++23

// RUN: %clang_cl -fmsc-version=1900 -TP -std:c++latest -### -- %s 2>&1 | FileCheck -check-prefix=STDCXXLATEST %s
// STDCXXLATEST: -std=c++26

Expand Down
1 change: 0 additions & 1 deletion clang/test/Driver/hip-include-path.hip
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// REQUIRES: libgcc
// UNSUPPORTED: system-windows

// RUN: %clang -c -### --target=x86_64-unknown-linux-gnu --cuda-gpu-arch=gfx900 \
Expand Down
2 changes: 0 additions & 2 deletions clang/test/Driver/hip-runtime-libs-msvc.hip
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// REQUIRES: system-windows

// RUN: touch %t.o

// Test HIP runtime lib args specified by --rocm-path.
Expand Down
Loading