aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Attr.h7
-rw-r--r--clang/include/clang/AST/StmtOpenACC.h3
-rw-r--r--clang/include/clang/Basic/Attr.td2
-rw-r--r--clang/include/clang/Basic/Builtins.td7
-rw-r--r--clang/include/clang/Basic/BuiltinsX86.td29
-rw-r--r--clang/include/clang/Basic/DiagnosticASTKinds.td6
-rw-r--r--clang/include/clang/Basic/DiagnosticFrontendKinds.td4
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td1
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIROps.td37
-rw-r--r--clang/include/clang/Driver/CommonArgs.h3
-rw-r--r--clang/include/clang/Sema/SemaHLSL.h30
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp91
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp59
-rw-r--r--clang/lib/AST/ExprConstant.cpp36
-rw-r--r--clang/lib/AST/StmtOpenACC.cpp44
-rw-r--r--clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp89
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp21
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCXXABI.h2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExpr.cpp6
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp26
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp7
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp57
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp9
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp3
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.cpp100
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.h34
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp15
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h4
-rw-r--r--clang/lib/Driver/ToolChains/CommonArgs.cpp29
-rw-r--r--clang/lib/Driver/ToolChains/PS4CPU.cpp11
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp12
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp5
-rw-r--r--clang/lib/Headers/CMakeLists.txt3
-rw-r--r--clang/lib/Headers/__float_float.h176
-rw-r--r--clang/lib/Headers/__float_header_macro.h12
-rw-r--r--clang/lib/Headers/__float_infinity_nan.h20
-rw-r--r--clang/lib/Headers/avx2intrin.h21
-rw-r--r--clang/lib/Headers/float.h180
-rw-r--r--clang/lib/Headers/module.modulemap18
-rw-r--r--clang/lib/Headers/tmmintrin.h52
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp6
-rw-r--r--clang/lib/Sema/SemaChecking.cpp22
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp105
-rw-r--r--clang/lib/Sema/SemaOpenACC.cpp1
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp4
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp11
-rw-r--r--clang/test/AST/ByteCode/records.cpp21
-rw-r--r--clang/test/CIR/CodeGen/builtin_prefetech.c43
-rw-r--r--clang/test/CIR/CodeGen/dynamic-cast-exact.cpp34
-rw-r--r--clang/test/CIR/CodeGen/try-catch.cpp47
-rw-r--r--clang/test/CIR/CodeGenOpenACC/atomic-write.cpp55
-rw-r--r--clang/test/CodeGen/X86/avx2-builtins.c7
-rw-r--r--clang/test/CodeGen/X86/mmx-builtins.c5
-rw-r--r--clang/test/CodeGen/X86/ssse3-builtins.c3
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic-struct-1.hlsl23
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic-struct-2.hlsl25
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic-struct-nested-inherit.hlsl30
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic-struct-nested-shadow.hlsl30
-rw-r--r--clang/test/CodeGenHLSL/semantics/semantic-struct-nested.hlsl30
-rw-r--r--clang/test/Driver/DTLTO/Inputs/dtlto-helper.py11
-rw-r--r--clang/test/Driver/DTLTO/dtlto.c23
-rw-r--r--clang/test/Driver/DTLTO/filename.py4
-rw-r--r--clang/test/Driver/DTLTO/lit.local.cfg3
-rw-r--r--clang/test/Driver/DTLTO/ps5-dtlto.c18
-rw-r--r--clang/test/Headers/floatneeds.c41
-rw-r--r--clang/test/Modules/explicit-build-cwd.c17
-rw-r--r--clang/test/Modules/relative-resource-dir.m1
-rw-r--r--clang/test/Preprocessor/cxx_oper_comma.cpp45
-rw-r--r--clang/test/SemaCXX/alloc-token.cpp79
-rw-r--r--clang/test/SemaHLSL/Semantics/entry_parameter.hlsl5
-rw-r--r--clang/test/SemaHLSL/Semantics/position.ps.hlsl5
-rw-r--r--clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl19
-rw-r--r--clang/test/SemaHLSL/Semantics/struct_input.hlsl19
-rw-r--r--clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp12
-rw-r--r--clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp104
-rw-r--r--clang/unittests/Format/FormatTestObjC.cpp6
-rw-r--r--clang/utils/TableGen/ClangAttrEmitter.cpp11
77 files changed, 1741 insertions, 455 deletions
diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index fe388b9..ce273c1 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -239,6 +239,8 @@ class HLSLSemanticAttr : public HLSLAnnotationAttr {
LLVM_PREFERRED_TYPE(bool)
unsigned SemanticExplicitIndex : 1;
+ Decl *TargetDecl = nullptr;
+
protected:
HLSLSemanticAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
attr::Kind AK, bool IsLateParsed,
@@ -259,6 +261,11 @@ public:
unsigned getSemanticIndex() const { return SemanticIndex; }
+ bool isSemanticIndexExplicit() const { return SemanticExplicitIndex; }
+
+ void setTargetDecl(Decl *D) { TargetDecl = D; }
+ Decl *getTargetDecl() const { return TargetDecl; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() >= attr::FirstHLSLSemanticAttr &&
diff --git a/clang/include/clang/AST/StmtOpenACC.h b/clang/include/clang/AST/StmtOpenACC.h
index 4d52805..ae80297 100644
--- a/clang/include/clang/AST/StmtOpenACC.h
+++ b/clang/include/clang/AST/StmtOpenACC.h
@@ -821,6 +821,9 @@ public:
struct StmtInfo {
const Expr *V;
const Expr *X;
+ // Listed as 'expr' in the standard, this is typically a generic expression
+ // as a component.
+ const Expr *RefExpr;
// TODO: OpenACC: We should expand this as we're implementing the other
// atomic construct kinds.
};
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index b320f4b..749f531 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -787,6 +787,8 @@ class HLSLSemanticAttr<bit Indexable> : HLSLAnnotationAttr {
let Spellings = [];
let Subjects = SubjectList<[ParmVar, Field, Function]>;
let LangOpts = [HLSL];
+ let Args = [DeclArgument<Named, "Target">, IntArgument<"SemanticIndex">,
+ BoolArgument<"SemanticExplicitIndex">];
}
/// A target-specific attribute. This class is meant to be used as a mixin
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index a350acd..a2c2021 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4727,6 +4727,13 @@ def PtrauthStringDiscriminator : Builtin {
let Prototype = "size_t(char const*)";
}
+// AllocToken builtins.
+def InferAllocToken : Builtin {
+ let Spellings = ["__builtin_infer_alloc_token"];
+ let Attributes = [NoThrow, Const, Pure, CustomTypeChecking, Constexpr, UnevaluatedArguments];
+ let Prototype = "size_t(...)";
+}
+
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
// We need the generic prototype, since the packet type could be anything.
def ReadPipe : OCLPipeLangBuiltin {
diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td
index 54b3ce0..8332eac 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -123,13 +123,13 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<128>] in {
}
}
- let Features = "ssse3" in {
- def psignb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
- def psignw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
- def psignd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
- }
-
let Features = "ssse3", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
+ def psignb128
+ : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
+ def psignw128
+ : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
+ def psignd128
+ : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
def pmulhrsw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def pmaddubsw128 : X86Builtin<"_Vector<8, short>(_Vector<16, char>, _Vector<16, char>)">;
def pshufb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
@@ -603,10 +603,9 @@ let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] i
def mpsadbw256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Constant char)">;
def palignr256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, "
"_Vector<32, char>, _Constant int)">;
- def psadbw256 : X86Builtin<"_Vector<4, long long int>(_Vector<32, char>, _Vector<32, char>)">;
- def psignb256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>)">;
- def psignw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
- def psignd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
+ def psadbw256
+ : X86Builtin<
+ "_Vector<4, long long int>(_Vector<32, char>, _Vector<32, char>)">;
def psllw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<8, short>)">;
def pslldqi256_byteshift : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Constant int)">;
def pslld256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>)">;
@@ -677,7 +676,15 @@ let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWi
def phsubw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
def phsubd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
def phsubsw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
-
+
+ def psignb256
+ : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>)">;
+ def psignw256
+ : X86Builtin<
+ "_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
+ def psignd256
+ : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
+
def pshuflw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Constant int)">;
def pshufhw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Constant int)">;
def pshufd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Constant int)">;
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 0be9146f..5c462f9 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -403,6 +403,12 @@ def note_constexpr_assumption_failed : Note<
def note_constexpr_countzeroes_zero : Note<
"evaluation of %select{__builtin_elementwise_clzg|__builtin_elementwise_ctzg}0 "
"with a zero value is undefined">;
+def note_constexpr_infer_alloc_token_type_inference_failed : Note<
+ "could not infer allocation type for __builtin_infer_alloc_token">;
+def note_constexpr_infer_alloc_token_no_metadata : Note<
+ "could not get token metadata for inferred type">;
+def note_constexpr_infer_alloc_token_stateful_mode : Note<
+ "stateful alloc token mode not supported in constexpr">;
def err_experimental_clang_interp_failed : Error<
"the experimental clang interpreter failed to evaluate an expression">;
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 64391de..9e34416 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -404,10 +404,6 @@ def warn_hlsl_langstd_minimal :
"recommend using %1 instead">,
InGroup<HLSLDXCCompat>;
-def err_hlsl_semantic_missing : Error<"semantic annotations must be present "
- "for all input and outputs of an entry "
- "function or patch constant function">;
-
// ClangIR frontend errors
def err_cir_to_cir_transform_failed : Error<
"CIR-to-CIR transformation failed">, DefaultFatal;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 20b4994..13f0d59 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13173,6 +13173,7 @@ def err_hlsl_duplicate_parameter_modifier : Error<"duplicate parameter modifier
def err_hlsl_missing_semantic_annotation : Error<
"semantic annotations must be present for all parameters of an entry "
"function or patch constant function">;
+def note_hlsl_semantic_used_here : Note<"%0 used here">;
def err_hlsl_unknown_semantic : Error<"unknown HLSL semantic %0">;
def err_hlsl_semantic_output_not_supported
: Error<"semantic %0 does not support output">;
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 86d09d7..2b361ed 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4053,6 +4053,43 @@ def CIR_ExpectOp : CIR_Op<"expect", [
}
//===----------------------------------------------------------------------===//
+// PrefetchOp
+//===----------------------------------------------------------------------===//
+
+def CIR_PrefetchOp : CIR_Op<"prefetch"> {
+ let summary = "Prefetch operation";
+ let description = [{
+ The `cir.prefetch` operation is a hint to the code generator to insert a
+ prefetch instruction if supported; otherwise, it is a noop. Prefetches
+ have no effect on the behavior of the program but can change its
+ performance characteristics.
+
+ ```mlir
+ cir.prefetch(%0 : !cir.ptr<!void>) locality(1) write
+ ```
+
+ $locality is a temporal locality specifier ranging from (0) - no locality,
+ to (3) - extremely local, keep in cache. If $locality is not present, the
+ default value is 3.
+
+ $isWrite specifies whether the prefetch is for a 'read' or 'write'. If
+ $isWrite is not specified, it means that prefetch is prepared for 'read'.
+ }];
+
+ let arguments = (ins CIR_VoidPtrType:$addr,
+ DefaultValuedAttr<ConfinedAttr<I32Attr, [IntMinValue<0>, IntMaxValue<3>]>,
+ "3">:$locality,
+ UnitAttr:$isWrite);
+
+ let assemblyFormat = [{
+ (`write` $isWrite^) : (`read`)?
+ `locality` `(` $locality `)`
+ $addr `:` qualified(type($addr))
+ attr-dict
+ }];
+}
+
+//===----------------------------------------------------------------------===//
// PtrDiffOp
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h
index 23426c0..ac17d62 100644
--- a/clang/include/clang/Driver/CommonArgs.h
+++ b/clang/include/clang/Driver/CommonArgs.h
@@ -76,6 +76,9 @@ void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
const JobAction &JA, const llvm::opt::ArgList &Args,
const InputInfo &Output, const char *OutFile);
+void addDTLTOOptions(const ToolChain &ToolChain, const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs);
+
void addLTOOptions(const ToolChain &ToolChain, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs, const InputInfo &Output,
const InputInfoList &Inputs, bool IsThinLTO);
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index f9d3a4ea..8c3b6ae 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -130,9 +130,6 @@ public:
bool ActOnUninitializedVarDecl(VarDecl *D);
void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU);
void CheckEntryPoint(FunctionDecl *FD);
- bool isSemanticValid(FunctionDecl *FD, DeclaratorDecl *D);
- void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
- const HLSLAnnotationAttr *AnnotationAttr);
bool CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr,
SourceLocation Loc);
void DiagnoseAttrStageMismatch(
@@ -179,17 +176,17 @@ public:
bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL);
template <typename T>
- T *createSemanticAttr(const ParsedAttr &AL,
+ T *createSemanticAttr(const AttributeCommonInfo &ACI, NamedDecl *TargetDecl,
std::optional<unsigned> Location) {
- T *Attr = ::new (getASTContext()) T(getASTContext(), AL);
- if (Attr->isSemanticIndexable())
- Attr->setSemanticIndex(Location ? *Location : 0);
- else if (Location.has_value()) {
+ T *Attr =
+ ::new (getASTContext()) T(getASTContext(), ACI, TargetDecl,
+ Location.value_or(0), Location.has_value());
+
+ if (!Attr->isSemanticIndexable() && Location.has_value()) {
Diag(Attr->getLocation(), diag::err_hlsl_semantic_indexing_not_supported)
<< Attr->getAttrName()->getName();
return nullptr;
}
-
return Attr;
}
@@ -247,10 +244,25 @@ private:
IdentifierInfo *RootSigOverrideIdent = nullptr;
+ struct SemanticInfo {
+ HLSLSemanticAttr *Semantic;
+ std::optional<uint32_t> Index;
+ };
+
private:
void collectResourceBindingsOnVarDecl(VarDecl *D);
void collectResourceBindingsOnUserRecordDecl(const VarDecl *VD,
const RecordType *RT);
+
+ void checkSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
+ const HLSLSemanticAttr *SemanticAttr);
+ HLSLSemanticAttr *createSemantic(const SemanticInfo &Semantic,
+ DeclaratorDecl *TargetDecl);
+ bool determineActiveSemanticOnScalar(FunctionDecl *FD, DeclaratorDecl *D,
+ SemanticInfo &ActiveSemantic);
+ bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *D,
+ SemanticInfo &ActiveSemantic);
+
void processExplicitBindingsOnDecl(VarDecl *D);
void diagnoseAvailabilityViolations(TranslationUnitDecl *TU);
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index f15b3c1..836d22f 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1842,7 +1842,6 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
const Expr *Init, PrimType T,
bool Activate = false) -> bool {
InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Init));
- InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset));
if (!this->visit(Init))
return false;
@@ -5385,55 +5384,57 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
// instance pointer of the current function frame, but e.g. to the declaration
// currently being initialized. Here we emit the necessary instruction(s) for
// this scenario.
- if (!InitStackActive)
+ if (!InitStackActive || InitStack.empty())
return this->emitThis(E);
- if (!InitStack.empty()) {
- // If our init stack is, for example:
- // 0 Stack: 3 (decl)
- // 1 Stack: 6 (init list)
- // 2 Stack: 1 (field)
- // 3 Stack: 6 (init list)
- // 4 Stack: 1 (field)
- //
- // We want to find the LAST element in it that's an init list,
- // which is marked with the K_InitList marker. The index right
- // before that points to an init list. We need to find the
- // elements before the K_InitList element that point to a base
- // (e.g. a decl or This), optionally followed by field, elem, etc.
- // In the example above, we want to emit elements [0..2].
- unsigned StartIndex = 0;
- unsigned EndIndex = 0;
- // Find the init list.
- for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
- if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
- InitStack[StartIndex].Kind == InitLink::K_This) {
- EndIndex = StartIndex;
- --StartIndex;
- break;
- }
+ // If our init stack is, for example:
+ // 0 Stack: 3 (decl)
+ // 1 Stack: 6 (init list)
+ // 2 Stack: 1 (field)
+ // 3 Stack: 6 (init list)
+ // 4 Stack: 1 (field)
+ //
+ // We want to find the LAST element in it that's an init list,
+ // which is marked with the K_InitList marker. The index right
+ // before that points to an init list. We need to find the
+ // elements before the K_InitList element that point to a base
+ // (e.g. a decl or This), optionally followed by field, elem, etc.
+ // In the example above, we want to emit elements [0..2].
+ unsigned StartIndex = 0;
+ unsigned EndIndex = 0;
+ // Find the init list.
+ for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
+ if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
+ InitStack[StartIndex].Kind == InitLink::K_This) {
+ EndIndex = StartIndex;
+ --StartIndex;
+ break;
}
+ }
- // Walk backwards to find the base.
- for (; StartIndex > 0; --StartIndex) {
- if (InitStack[StartIndex].Kind == InitLink::K_InitList)
- continue;
+ // Walk backwards to find the base.
+ for (; StartIndex > 0; --StartIndex) {
+ if (InitStack[StartIndex].Kind == InitLink::K_InitList)
+ continue;
- if (InitStack[StartIndex].Kind != InitLink::K_Field &&
- InitStack[StartIndex].Kind != InitLink::K_Elem)
- break;
- }
+ if (InitStack[StartIndex].Kind != InitLink::K_Field &&
+ InitStack[StartIndex].Kind != InitLink::K_Elem)
+ break;
+ }
- // Emit the instructions.
- for (unsigned I = StartIndex; I != EndIndex; ++I) {
- if (InitStack[I].Kind == InitLink::K_InitList)
- continue;
- if (!InitStack[I].template emit<Emitter>(this, E))
- return false;
- }
- return true;
+ if (StartIndex == 0 && EndIndex == 0)
+ EndIndex = InitStack.size() - 1;
+
+ assert(StartIndex < EndIndex);
+
+ // Emit the instructions.
+ for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
+ if (InitStack[I].Kind == InitLink::K_InitList)
+ continue;
+ if (!InitStack[I].template emit<Emitter>(this, E))
+ return false;
}
- return this->emitThis(E);
+ return true;
}
template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
@@ -6295,6 +6296,10 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
}
assert(NestedField);
+ unsigned FirstLinkOffset =
+ R->getField(cast<FieldDecl>(IFD->chain()[0]))->Offset;
+ InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
+ InitLinkScope<Emitter> ILS(this, InitLink::Field(FirstLinkOffset));
if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
IsUnion))
return false;
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 2d5ad4a..ff50e6d 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -12,12 +12,14 @@
#include "InterpHelpers.h"
#include "PrimType.h"
#include "Program.h"
+#include "clang/AST/InferAlloc.h"
#include "clang/AST/OSLog.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/AllocToken.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SipHash.h"
@@ -1307,6 +1309,45 @@ interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC,
return true;
}
+static bool interp__builtin_infer_alloc_token(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const CallExpr *Call) {
+ const ASTContext &ASTCtx = S.getASTContext();
+ uint64_t BitWidth = ASTCtx.getTypeSize(ASTCtx.getSizeType());
+ auto Mode =
+ ASTCtx.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
+ uint64_t MaxTokens =
+ ASTCtx.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
+
+ // We do not read any of the arguments; discard them.
+ for (int I = Call->getNumArgs() - 1; I >= 0; --I)
+ discard(S.Stk, *S.getContext().classify(Call->getArg(I)));
+
+ // Note: Type inference from a surrounding cast is not supported in
+ // constexpr evaluation.
+ QualType AllocType = infer_alloc::inferPossibleType(Call, ASTCtx, nullptr);
+ if (AllocType.isNull()) {
+ S.CCEDiag(Call,
+ diag::note_constexpr_infer_alloc_token_type_inference_failed);
+ return false;
+ }
+
+ auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, ASTCtx);
+ if (!ATMD) {
+ S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_no_metadata);
+ return false;
+ }
+
+ auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
+ if (!MaybeToken) {
+ S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_stateful_mode);
+ return false;
+ }
+
+ pushInteger(S, llvm::APInt(BitWidth, *MaybeToken), ASTCtx.getSizeType());
+ return true;
+}
+
static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
@@ -3694,6 +3735,9 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
case Builtin::BI__builtin_ptrauth_string_discriminator:
return interp__builtin_ptrauth_string_discriminator(S, OpPC, Frame, Call);
+ case Builtin::BI__builtin_infer_alloc_token:
+ return interp__builtin_infer_alloc_token(S, OpPC, Frame, Call);
+
case Builtin::BI__noop:
pushInteger(S, 0, Call->getType());
return true;
@@ -3809,6 +3853,21 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
return interp__builtin_ia32_movmsk_op(S, OpPC, Call);
}
+ case X86::BI__builtin_ia32_psignb128:
+ case X86::BI__builtin_ia32_psignb256:
+ case X86::BI__builtin_ia32_psignw128:
+ case X86::BI__builtin_ia32_psignw256:
+ case X86::BI__builtin_ia32_psignd128:
+ case X86::BI__builtin_ia32_psignd256:
+ return interp__builtin_elementwise_int_binop(
+ S, OpPC, Call, [](const APInt &AElem, const APInt &BElem) {
+ if (BElem.isZero())
+ return APInt::getZero(AElem.getBitWidth());
+ if (BElem.isNegative())
+ return -AElem;
+ return AElem;
+ });
+
case clang::X86::BI__builtin_ia32_pavgb128:
case clang::X86::BI__builtin_ia32_pavgw128:
case clang::X86::BI__builtin_ia32_pavgb256:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 00aaaab..2bd4476 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -44,6 +44,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/CurrentSourceLocExprScope.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/InferAlloc.h"
#include "clang/AST/OSLog.h"
#include "clang/AST/OptionalDiagnostic.h"
#include "clang/AST/RecordLayout.h"
@@ -12312,6 +12313,20 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
+ case X86::BI__builtin_ia32_psignb128:
+ case X86::BI__builtin_ia32_psignb256:
+ case X86::BI__builtin_ia32_psignw128:
+ case X86::BI__builtin_ia32_psignw256:
+ case X86::BI__builtin_ia32_psignd128:
+ case X86::BI__builtin_ia32_psignd256:
+ return EvaluateBinOpExpr([](const APInt &AElem, const APInt &BElem) {
+ if (BElem.isZero())
+ return APInt::getZero(AElem.getBitWidth());
+ if (BElem.isNegative())
+ return -AElem;
+ return AElem;
+ });
+
case X86::BI__builtin_ia32_blendvpd:
case X86::BI__builtin_ia32_blendvpd256:
case X86::BI__builtin_ia32_blendvps:
@@ -14649,6 +14664,27 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return Success(Result, E);
}
+ case Builtin::BI__builtin_infer_alloc_token: {
+ // If we fail to infer a type, this fails to be a constant expression; this
+ // can be checked with __builtin_constant_p(...).
+ QualType AllocType = infer_alloc::inferPossibleType(E, Info.Ctx, nullptr);
+ if (AllocType.isNull())
+ return Error(
+ E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
+ auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, Info.Ctx);
+ if (!ATMD)
+ return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
+ auto Mode =
+ Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
+ uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
+ uint64_t MaxTokens =
+ Info.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
+ auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
+ if (!MaybeToken)
+ return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
+ return Success(llvm::APInt(BitWidth, *MaybeToken), E);
+ }
+
case Builtin::BI__builtin_ffs:
case Builtin::BI__builtin_ffsl:
case Builtin::BI__builtin_ffsll: {
diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp
index 2b56c1e..462a10d 100644
--- a/clang/lib/AST/StmtOpenACC.cpp
+++ b/clang/lib/AST/StmtOpenACC.cpp
@@ -324,6 +324,18 @@ OpenACCAtomicConstruct *OpenACCAtomicConstruct::Create(
return Inst;
}
+static std::pair<const Expr *, const Expr *> getBinaryOpArgs(const Expr *Op) {
+ if (const auto *BO = dyn_cast<BinaryOperator>(Op)) {
+ assert(BO->getOpcode() == BO_Assign);
+ return {BO->getLHS(), BO->getRHS()};
+ }
+
+ const auto *OO = cast<CXXOperatorCallExpr>(Op);
+ assert(OO->getOperator() == OO_Equal);
+
+ return {OO->getArg(0), OO->getArg(1)};
+}
+
const OpenACCAtomicConstruct::StmtInfo
OpenACCAtomicConstruct::getAssociatedStmtInfo() const {
// This ends up being a vastly simplified version of SemaOpenACCAtomic, since
@@ -333,27 +345,35 @@ OpenACCAtomicConstruct::getAssociatedStmtInfo() const {
switch (AtomicKind) {
case OpenACCAtomicKind::None:
- case OpenACCAtomicKind::Write:
case OpenACCAtomicKind::Update:
case OpenACCAtomicKind::Capture:
- assert(false && "Only 'read' has been implemented here");
+ assert(false && "Only 'read'/'write' have been implemented here");
return {};
case OpenACCAtomicKind::Read: {
// Read only supports the format 'v = x'; where both sides are a scalar
// expression. This can come in 2 forms; BinaryOperator or
// CXXOperatorCallExpr (rarely).
- const Expr *AssignExpr = cast<const Expr>(getAssociatedStmt());
- if (const auto *BO = dyn_cast<BinaryOperator>(AssignExpr)) {
- assert(BO->getOpcode() == BO_Assign);
- return {BO->getLHS()->IgnoreImpCasts(), BO->getRHS()->IgnoreImpCasts()};
- }
-
- const auto *OO = cast<CXXOperatorCallExpr>(AssignExpr);
- assert(OO->getOperator() == OO_Equal);
-
- return {OO->getArg(0)->IgnoreImpCasts(), OO->getArg(1)->IgnoreImpCasts()};
+ std::pair<const Expr *, const Expr *> BinaryArgs =
+ getBinaryOpArgs(cast<const Expr>(getAssociatedStmt()));
+ // We want the L-value for each side, so we ignore implicit casts.
+ return {BinaryArgs.first->IgnoreImpCasts(),
+ BinaryArgs.second->IgnoreImpCasts(), /*expr=*/nullptr};
}
+ case OpenACCAtomicKind::Write: {
+ // Write supports only the format 'x = expr', where the expression is scalar
+ // type, and 'x' is a scalar l value. As above, this can come in 2 forms;
+ // Binary Operator or CXXOperatorCallExpr.
+ std::pair<const Expr *, const Expr *> BinaryArgs =
+ getBinaryOpArgs(cast<const Expr>(getAssociatedStmt()));
+ // We want the L-value for ONLY the X side, so we ignore implicit casts. For
+ // the right side (the expr), we emit it as an r-value so we need to
+ // maintain implicit casts.
+ return {/*v=*/nullptr, BinaryArgs.first->IgnoreImpCasts(),
+ BinaryArgs.second};
}
+ }
+
+ llvm_unreachable("unknown OpenACC atomic kind");
}
OpenACCCacheConstruct *OpenACCCacheConstruct::CreateEmpty(const ASTContext &C,
diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp
index 598d33a..90551c2 100644
--- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.cpp
@@ -168,6 +168,15 @@ static auto isNotOkStatusCall() {
"::absl::UnimplementedError", "::absl::UnknownError"))));
}
+static auto isPointerComparisonOperatorCall(std::string operator_name) {
+ using namespace ::clang::ast_matchers; // NOLINT: Too many names
+ return binaryOperator(hasOperatorName(operator_name),
+ hasLHS(hasType(hasCanonicalType(pointerType(
+ pointee(anyOf(statusOrType(), statusType())))))),
+ hasRHS(hasType(hasCanonicalType(pointerType(
+ pointee(anyOf(statusOrType(), statusType())))))));
+}
+
static auto
buildDiagnoseMatchSwitch(const UncheckedStatusOrAccessModelOptions &Options) {
return CFGMatchSwitchBuilder<const Environment,
@@ -438,6 +447,58 @@ static void transferComparisonOperator(const CXXOperatorCallExpr *Expr,
State.Env.setValue(*Expr, *LhsAndRhsVal);
}
+static RecordStorageLocation *getPointeeLocation(const Expr &Expr,
+ Environment &Env) {
+ if (auto *PointerVal = Env.get<PointerValue>(Expr))
+ return dyn_cast<RecordStorageLocation>(&PointerVal->getPointeeLoc());
+ return nullptr;
+}
+
+static BoolValue *evaluatePointerEquality(const Expr *LhsExpr,
+ const Expr *RhsExpr,
+ Environment &Env) {
+ assert(LhsExpr->getType()->isPointerType());
+ assert(RhsExpr->getType()->isPointerType());
+ RecordStorageLocation *LhsStatusLoc = nullptr;
+ RecordStorageLocation *RhsStatusLoc = nullptr;
+ if (isStatusOrType(LhsExpr->getType()->getPointeeType()) &&
+ isStatusOrType(RhsExpr->getType()->getPointeeType())) {
+ auto *LhsStatusOrLoc = getPointeeLocation(*LhsExpr, Env);
+ auto *RhsStatusOrLoc = getPointeeLocation(*RhsExpr, Env);
+ if (LhsStatusOrLoc == nullptr || RhsStatusOrLoc == nullptr)
+ return nullptr;
+ LhsStatusLoc = &locForStatus(*LhsStatusOrLoc);
+ RhsStatusLoc = &locForStatus(*RhsStatusOrLoc);
+ } else if (isStatusType(LhsExpr->getType()->getPointeeType()) &&
+ isStatusType(RhsExpr->getType()->getPointeeType())) {
+ LhsStatusLoc = getPointeeLocation(*LhsExpr, Env);
+ RhsStatusLoc = getPointeeLocation(*RhsExpr, Env);
+ }
+ if (LhsStatusLoc == nullptr || RhsStatusLoc == nullptr)
+ return nullptr;
+ auto &LhsOkVal = valForOk(*LhsStatusLoc, Env);
+ auto &RhsOkVal = valForOk(*RhsStatusLoc, Env);
+ auto &Res = Env.makeAtomicBoolValue();
+ auto &A = Env.arena();
+ Env.assume(A.makeImplies(
+ Res.formula(), A.makeEquals(LhsOkVal.formula(), RhsOkVal.formula())));
+ return &Res;
+}
+
+static void transferPointerComparisonOperator(const BinaryOperator *Expr,
+ LatticeTransferState &State,
+ bool IsNegative) {
+ auto *LhsAndRhsVal =
+ evaluatePointerEquality(Expr->getLHS(), Expr->getRHS(), State.Env);
+ if (LhsAndRhsVal == nullptr)
+ return;
+
+ if (IsNegative)
+ State.Env.setValue(*Expr, State.Env.makeNot(*LhsAndRhsVal));
+ else
+ State.Env.setValue(*Expr, *LhsAndRhsVal);
+}
+
static void transferOkStatusCall(const CallExpr *Expr,
const MatchFinder::MatchResult &,
LatticeTransferState &State) {
@@ -455,6 +516,18 @@ static void transferNotOkStatusCall(const CallExpr *Expr,
State.Env.assume(A.makeNot(OkVal.formula()));
}
+static void transferEmplaceCall(const CXXMemberCallExpr *Expr,
+ const MatchFinder::MatchResult &,
+ LatticeTransferState &State) {
+ RecordStorageLocation *StatusOrLoc =
+ getImplicitObjectLocation(*Expr, State.Env);
+ if (StatusOrLoc == nullptr)
+ return;
+
+ auto &OkVal = valForOk(locForStatus(*StatusOrLoc), State.Env);
+ State.Env.assume(OkVal.formula());
+}
+
CFGMatchSwitch<LatticeTransferState>
buildTransferMatchSwitch(ASTContext &Ctx,
CFGMatchSwitchBuilder<LatticeTransferState> Builder) {
@@ -482,8 +555,24 @@ buildTransferMatchSwitch(ASTContext &Ctx,
transferComparisonOperator(Expr, State,
/*IsNegative=*/true);
})
+ .CaseOfCFGStmt<BinaryOperator>(
+ isPointerComparisonOperatorCall("=="),
+ [](const BinaryOperator *Expr, const MatchFinder::MatchResult &,
+ LatticeTransferState &State) {
+ transferPointerComparisonOperator(Expr, State,
+ /*IsNegative=*/false);
+ })
+ .CaseOfCFGStmt<BinaryOperator>(
+ isPointerComparisonOperatorCall("!="),
+ [](const BinaryOperator *Expr, const MatchFinder::MatchResult &,
+ LatticeTransferState &State) {
+ transferPointerComparisonOperator(Expr, State,
+ /*IsNegative=*/true);
+ })
.CaseOfCFGStmt<CallExpr>(isOkStatusCall(), transferOkStatusCall)
.CaseOfCFGStmt<CallExpr>(isNotOkStatusCall(), transferNotOkStatusCall)
+ .CaseOfCFGStmt<CXXMemberCallExpr>(isStatusOrMemberCallWithName("emplace"),
+ transferEmplaceCall)
.Build();
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 27c4d11..62fa04e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -454,6 +454,27 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
assert(!cir::MissingFeatures::coroSizeBuiltinCall());
return getUndefRValue(e->getType());
}
+ case Builtin::BI__builtin_prefetch: {
+ auto evaluateOperandAsInt = [&](const Expr *arg) {
+ Expr::EvalResult res;
+ [[maybe_unused]] bool evalSucceed =
+ arg->EvaluateAsInt(res, cgm.getASTContext());
+ assert(evalSucceed && "expression should be able to evaluate as int");
+ return res.Val.getInt().getZExtValue();
+ };
+
+ bool isWrite = false;
+ if (e->getNumArgs() > 1)
+ isWrite = evaluateOperandAsInt(e->getArg(1));
+
+ int locality = 3;
+ if (e->getNumArgs() > 2)
+ locality = evaluateOperandAsInt(e->getArg(2));
+
+ mlir::Value address = emitScalarExpr(e->getArg(0));
+ cir::PrefetchOp::create(builder, loc, address, locality, isWrite);
+ return RValue::get(nullptr);
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index c78f9b0..d3c7dac0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -124,6 +124,8 @@ public:
virtual void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) = 0;
virtual void emitThrow(CIRGenFunction &cgf, const CXXThrowExpr *e) = 0;
+ virtual void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc) = 0;
+
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
QualType ty) = 0;
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 9df88ad..df6ee56 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2065,7 +2065,11 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
// a surrounding cir.scope, make sure the alloca ends up in the surrounding
// scope instead. This is necessary in order to guarantee all SSA values are
// reachable during cleanups.
- assert(!cir::MissingFeatures::tryOp());
+ if (auto tryOp =
+ llvm::dyn_cast_if_present<cir::TryOp>(entryBlock->getParentOp())) {
+ if (auto scopeOp = llvm::dyn_cast<cir::ScopeOp>(tryOp->getParentOp()))
+ entryBlock = &scopeOp.getScopeRegion().front();
+ }
return emitAlloca(name, ty, loc, alignment,
builder.getBestAllocaInsertPoint(entryBlock), arraySize);
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index fe9e210..a3cdf19 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -801,6 +801,26 @@ void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,
emitNewDeleteCall(*this, deleteFD, deleteFTy, deleteArgs);
}
+static mlir::Value emitDynamicCastToNull(CIRGenFunction &cgf,
+ mlir::Location loc, QualType destTy) {
+ mlir::Type destCIRTy = cgf.convertType(destTy);
+ assert(mlir::isa<cir::PointerType>(destCIRTy) &&
+ "result of dynamic_cast should be a ptr");
+
+ if (!destTy->isPointerType()) {
+ mlir::Region *currentRegion = cgf.getBuilder().getBlock()->getParent();
+ /// C++ [expr.dynamic.cast]p9:
+ /// A failed cast to reference type throws std::bad_cast
+ cgf.cgm.getCXXABI().emitBadCastCall(cgf, loc);
+
+ // The call to bad_cast will terminate the current block. Create a new block
+ // to hold any follow up code.
+ cgf.getBuilder().createBlock(currentRegion, currentRegion->end());
+ }
+
+ return cgf.getBuilder().getNullPtr(destCIRTy, loc);
+}
+
mlir::Value CIRGenFunction::emitDynamicCast(Address thisAddr,
const CXXDynamicCastExpr *dce) {
mlir::Location loc = getLoc(dce->getSourceRange());
@@ -831,10 +851,8 @@ mlir::Value CIRGenFunction::emitDynamicCast(Address thisAddr,
assert(srcRecordTy->isRecordType() && "source type must be a record type!");
assert(!cir::MissingFeatures::emitTypeCheck());
- if (dce->isAlwaysNull()) {
- cgm.errorNYI(dce->getSourceRange(), "emitDynamicCastToNull");
- return {};
- }
+ if (dce->isAlwaysNull())
+ return emitDynamicCastToNull(*this, loc, destTy);
auto destCirTy = mlir::cast<cir::PointerType>(convertType(destTy));
return cgm.getCXXABI().emitDynamicCast(*this, loc, srcRecordTy, destRecordTy,
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index f7c4d18..2dce0b1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -120,6 +120,8 @@ public:
return true;
}
+ void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc) override;
+
mlir::Value
getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
Address thisAddr, const CXXRecordDecl *classDecl,
@@ -1883,6 +1885,11 @@ static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc) {
cgf.getBuilder().clearInsertionPoint();
}
+void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
+ mlir::Location loc) {
+ emitCallToBadCast(cgf, loc);
+}
+
// TODO(cir): This could be shared with classic codegen.
static CharUnits computeOffsetHint(ASTContext &astContext,
const CXXRecordDecl *src,
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
index 77e6f83..349b111 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
@@ -306,9 +306,10 @@ CIRGenFunction::emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s) {
mlir::LogicalResult
CIRGenFunction::emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s) {
- // For now, we are only support 'read', so diagnose. We can switch on the kind
- // later once we start implementing the other 3 forms.
- if (s.getAtomicKind() != OpenACCAtomicKind::Read) {
+ // For now, we are only support 'read'/'write', so diagnose. We can switch on
+ // the kind later once we start implementing the other 2 forms. While we
+ if (s.getAtomicKind() != OpenACCAtomicKind::Read &&
+ s.getAtomicKind() != OpenACCAtomicKind::Write) {
cgm.errorNYI(s.getSourceRange(), "OpenACC Atomic Construct");
return mlir::failure();
}
@@ -318,17 +319,41 @@ CIRGenFunction::emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s) {
// it has custom emit logic.
mlir::Location start = getLoc(s.getSourceRange().getBegin());
OpenACCAtomicConstruct::StmtInfo inf = s.getAssociatedStmtInfo();
- // Atomic 'read' only permits 'v = x', where v and x are both scalar L values.
- // The getAssociatedStmtInfo strips off implicit casts, which includes
- // implicit conversions and L-to-R-Value conversions, so we can just emit it
- // as an L value. The Flang implementation has no problem with different
- // types, so it appears that the dialect can handle the conversions.
- mlir::Value v = emitLValue(inf.V).getPointer();
- mlir::Value x = emitLValue(inf.X).getPointer();
- mlir::Type resTy = convertType(inf.V->getType());
- auto op = mlir::acc::AtomicReadOp::create(builder, start, x, v, resTy,
- /*ifCond=*/{});
- emitOpenACCClauses(op, s.getDirectiveKind(), s.getDirectiveLoc(),
- s.clauses());
- return mlir::success();
+
+ switch (s.getAtomicKind()) {
+ case OpenACCAtomicKind::None:
+ case OpenACCAtomicKind::Update:
+ case OpenACCAtomicKind::Capture:
+ llvm_unreachable("Unimplemented atomic construct type, should have "
+ "diagnosed/returned above");
+ return mlir::failure();
+ case OpenACCAtomicKind::Read: {
+
+ // Atomic 'read' only permits 'v = x', where v and x are both scalar L
+ // values. The getAssociatedStmtInfo strips off implicit casts, which
+ // includes implicit conversions and L-to-R-Value conversions, so we can
+ // just emit it as an L value. The Flang implementation has no problem with
+ // different types, so it appears that the dialect can handle the
+ // conversions.
+ mlir::Value v = emitLValue(inf.V).getPointer();
+ mlir::Value x = emitLValue(inf.X).getPointer();
+ mlir::Type resTy = convertType(inf.V->getType());
+ auto op = mlir::acc::AtomicReadOp::create(builder, start, x, v, resTy,
+ /*ifCond=*/{});
+ emitOpenACCClauses(op, s.getDirectiveKind(), s.getDirectiveLoc(),
+ s.clauses());
+ return mlir::success();
+ }
+ case OpenACCAtomicKind::Write: {
+ mlir::Value x = emitLValue(inf.X).getPointer();
+ mlir::Value expr = emitAnyExpr(inf.RefExpr).getValue();
+ auto op = mlir::acc::AtomicWriteOp::create(builder, start, x, expr,
+ /*ifCond=*/{});
+ emitOpenACCClauses(op, s.getDirectiveKind(), s.getDirectiveLoc(),
+ s.clauses());
+ return mlir::success();
+ }
+ }
+
+ llvm_unreachable("unknown OpenACC atomic kind");
}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index a30ae02..5a6193f 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1695,6 +1695,15 @@ static uint64_t getTypeSize(mlir::Type type, mlir::Operation &op) {
return llvm::divideCeil(layout.getTypeSizeInBits(type), 8);
}
+mlir::LogicalResult CIRToLLVMPrefetchOpLowering::matchAndRewrite(
+ cir::PrefetchOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ rewriter.replaceOpWithNewOp<mlir::LLVM::Prefetch>(
+ op, adaptor.getAddr(), adaptor.getIsWrite(), adaptor.getLocality(),
+ /*DataCache=*/1);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMPtrDiffOpLowering::matchAndRewrite(
cir::PtrDiffOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index c423c4b..468c930 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -684,7 +684,8 @@ static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,
PassBuilder &PB) {
// If the back-end supports KCFI operand bundle lowering, skip KCFIPass.
if (TargetTriple.getArch() == llvm::Triple::x86_64 ||
- TargetTriple.isAArch64(64) || TargetTriple.isRISCV())
+ TargetTriple.isAArch64(64) || TargetTriple.isRISCV() ||
+ TargetTriple.isARM() || TargetTriple.isThumb())
return;
// Ensure we lower KCFI operand bundles with -O0.
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index ecab933..945f9e2 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -562,17 +562,16 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M,
return B.CreateLoad(Ty, GV);
}
-llvm::Value *
-CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
- const clang::DeclaratorDecl *Decl,
- SemanticInfo &ActiveSemantic) {
- if (isa<HLSLSV_GroupIndexAttr>(ActiveSemantic.Semantic)) {
+llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
+ IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl,
+ Attr *Semantic, std::optional<unsigned> Index) {
+ if (isa<HLSLSV_GroupIndexAttr>(Semantic)) {
llvm::Function *GroupIndex =
CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic());
return B.CreateCall(FunctionCallee(GroupIndex));
}
- if (isa<HLSLSV_DispatchThreadIDAttr>(ActiveSemantic.Semantic)) {
+ if (isa<HLSLSV_DispatchThreadIDAttr>(Semantic)) {
llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic();
llvm::Function *ThreadIDIntrinsic =
llvm::Intrinsic::isOverloaded(IntrinID)
@@ -581,7 +580,7 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
return buildVectorInput(B, ThreadIDIntrinsic, Type);
}
- if (isa<HLSLSV_GroupThreadIDAttr>(ActiveSemantic.Semantic)) {
+ if (isa<HLSLSV_GroupThreadIDAttr>(Semantic)) {
llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic();
llvm::Function *GroupThreadIDIntrinsic =
llvm::Intrinsic::isOverloaded(IntrinID)
@@ -590,7 +589,7 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
return buildVectorInput(B, GroupThreadIDIntrinsic, Type);
}
- if (isa<HLSLSV_GroupIDAttr>(ActiveSemantic.Semantic)) {
+ if (isa<HLSLSV_GroupIDAttr>(Semantic)) {
llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic();
llvm::Function *GroupIDIntrinsic =
llvm::Intrinsic::isOverloaded(IntrinID)
@@ -599,8 +598,7 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
return buildVectorInput(B, GroupIDIntrinsic, Type);
}
- if (HLSLSV_PositionAttr *S =
- dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.Semantic)) {
+ if (HLSLSV_PositionAttr *S = dyn_cast<HLSLSV_PositionAttr>(Semantic)) {
if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel)
return createSPIRVBuiltinLoad(B, CGM.getModule(), Type,
S->getAttrName()->getName(),
@@ -611,29 +609,56 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
}
llvm::Value *
-CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
- const clang::DeclaratorDecl *Decl,
- SemanticInfo &ActiveSemantic) {
-
- if (!ActiveSemantic.Semantic) {
- ActiveSemantic.Semantic = Decl->getAttr<HLSLSemanticAttr>();
- if (!ActiveSemantic.Semantic) {
- CGM.getDiags().Report(Decl->getInnerLocStart(),
- diag::err_hlsl_semantic_missing);
- return nullptr;
+CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD,
+ llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl) {
+
+ HLSLSemanticAttr *Semantic = nullptr;
+ for (HLSLSemanticAttr *Item : FD->specific_attrs<HLSLSemanticAttr>()) {
+ if (Item->getTargetDecl() == Decl) {
+ Semantic = Item;
+ break;
}
- ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
}
+ // Sema must create one attribute per scalar field.
+ assert(Semantic);
- return emitSystemSemanticLoad(B, Type, Decl, ActiveSemantic);
+ std::optional<unsigned> Index = std::nullopt;
+ if (Semantic->isSemanticIndexExplicit())
+ Index = Semantic->getSemanticIndex();
+ return emitSystemSemanticLoad(B, Type, Decl, Semantic, Index);
}
llvm::Value *
-CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, llvm::Type *Type,
- const clang::DeclaratorDecl *Decl,
- SemanticInfo &ActiveSemantic) {
- assert(!Type->isStructTy());
- return handleScalarSemanticLoad(B, Type, Decl, ActiveSemantic);
+CGHLSLRuntime::handleStructSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD,
+ llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl) {
+ const llvm::StructType *ST = cast<StructType>(Type);
+ const clang::RecordDecl *RD = Decl->getType()->getAsRecordDecl();
+
+ assert(std::distance(RD->field_begin(), RD->field_end()) ==
+ ST->getNumElements());
+
+ llvm::Value *Aggregate = llvm::PoisonValue::get(Type);
+ auto FieldDecl = RD->field_begin();
+ for (unsigned I = 0; I < ST->getNumElements(); ++I) {
+ llvm::Value *ChildValue =
+ handleSemanticLoad(B, FD, ST->getElementType(I), *FieldDecl);
+ assert(ChildValue);
+ Aggregate = B.CreateInsertValue(Aggregate, ChildValue, I);
+ ++FieldDecl;
+ }
+
+ return Aggregate;
+}
+
+llvm::Value *
+CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD,
+ llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl) {
+ if (Type->isStructTy())
+ return handleStructSemanticLoad(B, FD, Type, Decl);
+ return handleScalarSemanticLoad(B, FD, Type, Decl);
}
void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
@@ -680,8 +705,25 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
}
const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset);
- SemanticInfo ActiveSemantic = {nullptr, 0};
- Args.push_back(handleSemanticLoad(B, Param.getType(), PD, ActiveSemantic));
+ llvm::Value *SemanticValue = nullptr;
+ if ([[maybe_unused]] HLSLParamModifierAttr *MA =
+ PD->getAttr<HLSLParamModifierAttr>()) {
+ llvm_unreachable("Not handled yet");
+ } else {
+ llvm::Type *ParamType =
+ Param.hasByValAttr() ? Param.getParamByValType() : Param.getType();
+ SemanticValue = handleSemanticLoad(B, FD, ParamType, PD);
+ if (!SemanticValue)
+ return;
+ if (Param.hasByValAttr()) {
+ llvm::Value *Var = B.CreateAlloca(Param.getParamByValType());
+ B.CreateStore(SemanticValue, Var);
+ SemanticValue = Var;
+ }
+ }
+
+ assert(SemanticValue);
+ Args.push_back(SemanticValue);
}
CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index 103b4a9..d35df52 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -144,26 +144,24 @@ public:
protected:
CodeGenModule &CGM;
- void collectInputSemantic(llvm::IRBuilder<> &B, const DeclaratorDecl *D,
- llvm::Type *Type,
- SmallVectorImpl<llvm::Value *> &Inputs);
-
- struct SemanticInfo {
- clang::HLSLSemanticAttr *Semantic;
- uint32_t Index;
- };
-
llvm::Value *emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
const clang::DeclaratorDecl *Decl,
- SemanticInfo &ActiveSemantic);
-
- llvm::Value *handleScalarSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
- const clang::DeclaratorDecl *Decl,
- SemanticInfo &ActiveSemantic);
-
- llvm::Value *handleSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
- const clang::DeclaratorDecl *Decl,
- SemanticInfo &ActiveSemantic);
+ Attr *Semantic,
+ std::optional<unsigned> Index);
+
+ llvm::Value *handleScalarSemanticLoad(llvm::IRBuilder<> &B,
+ const FunctionDecl *FD,
+ llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl);
+
+ llvm::Value *handleStructSemanticLoad(llvm::IRBuilder<> &B,
+ const FunctionDecl *FD,
+ llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl);
+
+ llvm::Value *handleSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD,
+ llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl);
public:
CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {}
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 85b2404..66fea92 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -2713,14 +2713,6 @@ llvm::Value *CGOpenMPRuntime::emitMessageClause(CodeGenFunction &CGF,
}
llvm::Value *
-CGOpenMPRuntime::emitMessageClause(CodeGenFunction &CGF,
- const OMPMessageClause *MessageClause) {
- return emitMessageClause(
- CGF, MessageClause ? MessageClause->getMessageString() : nullptr,
- MessageClause->getBeginLoc());
-}
-
-llvm::Value *
CGOpenMPRuntime::emitSeverityClause(OpenMPSeverityClauseKind Severity,
SourceLocation Loc) {
// OpenMP 6.0, 10.4: "If no severity clause is specified then the effect is
@@ -2729,13 +2721,6 @@ CGOpenMPRuntime::emitSeverityClause(OpenMPSeverityClauseKind Severity,
Severity == OMPC_SEVERITY_warning ? 1 : 2);
}
-llvm::Value *
-CGOpenMPRuntime::emitSeverityClause(const OMPSeverityClause *SeverityClause) {
- return emitSeverityClause(SeverityClause ? SeverityClause->getSeverityKind()
- : OMPC_SEVERITY_unknown,
- SeverityClause->getBeginLoc());
-}
-
void CGOpenMPRuntime::emitNumThreadsClause(
CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc,
OpenMPNumThreadsClauseModifier Modifier, OpenMPSeverityClauseKind Severity,
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index ba76ba6b..6bfd7d6 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -1051,13 +1051,9 @@ public:
virtual llvm::Value *emitMessageClause(CodeGenFunction &CGF,
const Expr *Message,
SourceLocation Loc);
- virtual llvm::Value *emitMessageClause(CodeGenFunction &CGF,
- const OMPMessageClause *MessageClause);
virtual llvm::Value *emitSeverityClause(OpenMPSeverityClauseKind Severity,
SourceLocation Loc);
- virtual llvm::Value *
- emitSeverityClause(const OMPSeverityClause *SeverityClause);
/// Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
/// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 99400ac..727af69 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -949,6 +949,24 @@ bool tools::isTLSDESCEnabled(const ToolChain &TC,
return EnableTLSDESC;
}
+void tools::addDTLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) {
+ if (Arg *A = Args.getLastArg(options::OPT_fthinlto_distributor_EQ)) {
+ CmdArgs.push_back(
+ Args.MakeArgString("--thinlto-distributor=" + Twine(A->getValue())));
+ const Driver &D = ToolChain.getDriver();
+ CmdArgs.push_back(Args.MakeArgString("--thinlto-remote-compiler=" +
+ Twine(D.getClangProgramPath())));
+ if (auto *PA = D.getPrependArg())
+ CmdArgs.push_back(Args.MakeArgString(
+ "--thinlto-remote-compiler-prepend-arg=" + Twine(PA)));
+
+ for (const auto &A :
+ Args.getAllArgValues(options::OPT_Xthinlto_distributor_EQ))
+ CmdArgs.push_back(Args.MakeArgString("--thinlto-distributor-arg=" + A));
+ }
+}
+
void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
ArgStringList &CmdArgs, const InputInfo &Output,
const InputInfoList &Inputs, bool IsThinLTO) {
@@ -1350,16 +1368,7 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
CmdArgs.push_back(
Args.MakeArgString(Twine(PluginOptPrefix) + "-time-passes"));
- if (Arg *A = Args.getLastArg(options::OPT_fthinlto_distributor_EQ)) {
- CmdArgs.push_back(
- Args.MakeArgString("--thinlto-distributor=" + Twine(A->getValue())));
- CmdArgs.push_back(
- Args.MakeArgString("--thinlto-remote-compiler=" +
- Twine(ToolChain.getDriver().getClangProgramPath())));
-
- for (auto A : Args.getAllArgValues(options::OPT_Xthinlto_distributor_EQ))
- CmdArgs.push_back(Args.MakeArgString("--thinlto-distributor-arg=" + A));
- }
+ addDTLTOOptions(ToolChain, Args, CmdArgs);
}
void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp
index 61afc61..34ec65a 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp
@@ -344,16 +344,7 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// pass LTO options to ensure proper codegen, metadata production, etc if
// LTO indeed occurs.
- if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_distributor_EQ)) {
- CmdArgs.push_back(
- Args.MakeArgString("--thinlto-distributor=" + Twine(A->getValue())));
- CmdArgs.push_back(Args.MakeArgString("--thinlto-remote-compiler=" +
- Twine(D.getClangProgramPath())));
-
- for (const auto &A :
- Args.getAllArgValues(options::OPT_Xthinlto_distributor_EQ))
- CmdArgs.push_back(Args.MakeArgString("--thinlto-distributor-arg=" + A));
- }
+ tools::addDTLTOOptions(TC, Args, CmdArgs);
if (Args.hasFlag(options::OPT_funified_lto, options::OPT_fno_unified_lto,
true))
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index c97a9e8..1d0dfd0b 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4407,8 +4407,12 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
// breaking after it.
if (Right.is(TT_SelectorName))
return 0;
- if (Left.is(tok::colon) && Left.is(TT_ObjCMethodExpr))
- return Line.MightBeFunctionDecl ? 50 : 500;
+ if (Left.is(tok::colon)) {
+ if (Left.is(TT_ObjCMethodExpr))
+ return Line.MightBeFunctionDecl ? 50 : 500;
+ if (Left.is(TT_ObjCSelector))
+ return 500;
+ }
// In Objective-C type declarations, avoid breaking after the category's
// open paren (we'll prefer breaking after the protocol list's opening
@@ -6291,7 +6295,9 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
TT_BitFieldColon)) {
return false;
}
- if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) {
+ if (Left.is(tok::colon) && Left.isOneOf(TT_ObjCSelector, TT_ObjCMethodExpr))
+ return true;
+ if (Left.is(tok::colon) && Left.is(TT_DictLiteral)) {
if (Style.isProto()) {
if (!Style.AlwaysBreakBeforeMultilineStrings && Right.isStringLiteral())
return false;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 374138f..e3bf0ea 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -546,14 +546,11 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) {
assert(FileMgr && "Specific module cache path requires a FileManager");
- if (getHeaderSearchOpts().ModuleCachePath.empty())
- return "";
-
// Set up the module path, including the hash for the module-creation options.
SmallString<256> SpecificModuleCache;
normalizeModuleCachePath(*FileMgr, getHeaderSearchOpts().ModuleCachePath,
SpecificModuleCache);
- if (!getHeaderSearchOpts().DisableModuleHash)
+ if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)
llvm::sys::path::append(SpecificModuleCache, ModuleHash);
return std::string(SpecificModuleCache);
}
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 32a6be8..1858912 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -4,6 +4,9 @@
set(core_files
builtins.h
float.h
+ __float_float.h
+ __float_header_macro.h
+ __float_infinity_nan.h
inttypes.h
iso646.h
limits.h
diff --git a/clang/lib/Headers/__float_float.h b/clang/lib/Headers/__float_float.h
new file mode 100644
index 0000000..267c072
--- /dev/null
+++ b/clang/lib/Headers/__float_float.h
@@ -0,0 +1,176 @@
+/*===---- __float_float.h --------------------------------------------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __CLANG_FLOAT_FLOAT_H
+#define __CLANG_FLOAT_FLOAT_H
+
+#if (defined(__MINGW32__) || defined(_MSC_VER) || defined(_AIX)) && \
+ __STDC_HOSTED__
+
+/* Undefine anything that we'll be redefining below. */
+# undef FLT_EVAL_METHOD
+# undef FLT_ROUNDS
+# undef FLT_RADIX
+# undef FLT_MANT_DIG
+# undef DBL_MANT_DIG
+# undef LDBL_MANT_DIG
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ !defined(__STRICT_ANSI__) || \
+ (defined(__cplusplus) && __cplusplus >= 201103L) || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
+# undef DECIMAL_DIG
+# endif
+# undef FLT_DIG
+# undef DBL_DIG
+# undef LDBL_DIG
+# undef FLT_MIN_EXP
+# undef DBL_MIN_EXP
+# undef LDBL_MIN_EXP
+# undef FLT_MIN_10_EXP
+# undef DBL_MIN_10_EXP
+# undef LDBL_MIN_10_EXP
+# undef FLT_MAX_EXP
+# undef DBL_MAX_EXP
+# undef LDBL_MAX_EXP
+# undef FLT_MAX_10_EXP
+# undef DBL_MAX_10_EXP
+# undef LDBL_MAX_10_EXP
+# undef FLT_MAX
+# undef DBL_MAX
+# undef LDBL_MAX
+# undef FLT_EPSILON
+# undef DBL_EPSILON
+# undef LDBL_EPSILON
+# undef FLT_MIN
+# undef DBL_MIN
+# undef LDBL_MIN
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
+ !defined(__STRICT_ANSI__) || \
+ (defined(__cplusplus) && __cplusplus >= 201703L) || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
+# undef FLT_TRUE_MIN
+# undef DBL_TRUE_MIN
+# undef LDBL_TRUE_MIN
+# undef FLT_DECIMAL_DIG
+# undef DBL_DECIMAL_DIG
+# undef LDBL_DECIMAL_DIG
+# undef FLT_HAS_SUBNORM
+# undef DBL_HAS_SUBNORM
+# undef LDBL_HAS_SUBNORM
+# endif
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
+ !defined(__STRICT_ANSI__)
+# undef FLT_NORM_MAX
+# undef DBL_NORM_MAX
+# undef LDBL_NORM_MAX
+#endif
+#endif
+
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
+ !defined(__STRICT_ANSI__)
+# undef FLT_SNAN
+# undef DBL_SNAN
+# undef LDBL_SNAN
+#endif
+
+/* Characteristics of floating point types, C99 5.2.4.2.2 */
+
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ (defined(__cplusplus) && __cplusplus >= 201103L)
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#endif
+#define FLT_ROUNDS (__builtin_flt_rounds())
+#define FLT_RADIX __FLT_RADIX__
+
+#define FLT_MANT_DIG __FLT_MANT_DIG__
+#define DBL_MANT_DIG __DBL_MANT_DIG__
+#define LDBL_MANT_DIG __LDBL_MANT_DIG__
+
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ !defined(__STRICT_ANSI__) || \
+ (defined(__cplusplus) && __cplusplus >= 201103L) || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
+# define DECIMAL_DIG __DECIMAL_DIG__
+#endif
+
+#define FLT_DIG __FLT_DIG__
+#define DBL_DIG __DBL_DIG__
+#define LDBL_DIG __LDBL_DIG__
+
+#define FLT_MIN_EXP __FLT_MIN_EXP__
+#define DBL_MIN_EXP __DBL_MIN_EXP__
+#define LDBL_MIN_EXP __LDBL_MIN_EXP__
+
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
+
+#define FLT_MAX_EXP __FLT_MAX_EXP__
+#define DBL_MAX_EXP __DBL_MAX_EXP__
+#define LDBL_MAX_EXP __LDBL_MAX_EXP__
+
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
+
+#define FLT_MAX __FLT_MAX__
+#define DBL_MAX __DBL_MAX__
+#define LDBL_MAX __LDBL_MAX__
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+#define LDBL_EPSILON __LDBL_EPSILON__
+
+#define FLT_MIN __FLT_MIN__
+#define DBL_MIN __DBL_MIN__
+#define LDBL_MIN __LDBL_MIN__
+
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
+ !defined(__STRICT_ANSI__) || \
+ (defined(__cplusplus) && __cplusplus >= 201703L) || \
+ (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
+# define FLT_TRUE_MIN __FLT_DENORM_MIN__
+# define DBL_TRUE_MIN __DBL_DENORM_MIN__
+# define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
+# define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
+# define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
+# define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
+# define FLT_HAS_SUBNORM __FLT_HAS_DENORM__
+# define DBL_HAS_SUBNORM __DBL_HAS_DENORM__
+# define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
+#endif
+
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
+ !defined(__STRICT_ANSI__)
+ /* C23 5.2.5.3.2p28 */
+# define FLT_SNAN (__builtin_nansf(""))
+# define DBL_SNAN (__builtin_nans(""))
+# define LDBL_SNAN (__builtin_nansl(""))
+
+ /* C23 5.2.5.3.3p32 */
+# define FLT_NORM_MAX __FLT_NORM_MAX__
+# define DBL_NORM_MAX __DBL_NORM_MAX__
+# define LDBL_NORM_MAX __LDBL_NORM_MAX__
+#endif
+
+#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
+# define FLT16_MANT_DIG __FLT16_MANT_DIG__
+# define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__
+# define FLT16_DIG __FLT16_DIG__
+# define FLT16_MIN_EXP __FLT16_MIN_EXP__
+# define FLT16_MIN_10_EXP __FLT16_MIN_10_EXP__
+# define FLT16_MAX_EXP __FLT16_MAX_EXP__
+# define FLT16_MAX_10_EXP __FLT16_MAX_10_EXP__
+# define FLT16_MAX __FLT16_MAX__
+# define FLT16_EPSILON __FLT16_EPSILON__
+# define FLT16_MIN __FLT16_MIN__
+# define FLT16_TRUE_MIN __FLT16_TRUE_MIN__
+#endif /* __STDC_WANT_IEC_60559_TYPES_EXT__ */
+
+#endif /* __CLANG_FLOAT_FLOAT_H */
diff --git a/clang/lib/Headers/__float_header_macro.h b/clang/lib/Headers/__float_header_macro.h
new file mode 100644
index 0000000..11b270e
--- /dev/null
+++ b/clang/lib/Headers/__float_header_macro.h
@@ -0,0 +1,12 @@
+/*===---- __float_header_macro.h -------------------------------------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __CLANG_FLOAT_H
+#define __CLANG_FLOAT_H
+#endif /* __CLANG_FLOAT_H */
diff --git a/clang/lib/Headers/__float_infinity_nan.h b/clang/lib/Headers/__float_infinity_nan.h
new file mode 100644
index 0000000..7e253d0
--- /dev/null
+++ b/clang/lib/Headers/__float_infinity_nan.h
@@ -0,0 +1,20 @@
+/*===---- __float_infinity_nan.h -------------------------------------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __CLANG_FLOAT_INFINITY_NAN_H
+#define __CLANG_FLOAT_INFINITY_NAN_H
+
+/* C23 5.2.5.3.3p29-30 */
+#undef INFINITY
+#undef NAN
+
+#define INFINITY (__builtin_inff())
+#define NAN (__builtin_nanf(""))
+
+#endif /* __CLANG_FLOAT_INFINITY_NAN_H */
diff --git a/clang/lib/Headers/avx2intrin.h b/clang/lib/Headers/avx2intrin.h
index fdb825f..3cbaaec 100644
--- a/clang/lib/Headers/avx2intrin.h
+++ b/clang/lib/Headers/avx2intrin.h
@@ -1975,10 +1975,9 @@ _mm256_shuffle_epi8(__m256i __a, __m256i __b) {
/// \param __b
/// A 256-bit integer vector].
/// \returns A 256-bit integer vector containing the result.
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_sign_epi8(__m256i __a, __m256i __b)
-{
- return (__m256i)__builtin_ia32_psignb256((__v32qi)__a, (__v32qi)__b);
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_sign_epi8(__m256i __a, __m256i __b) {
+ return (__m256i)__builtin_ia32_psignb256((__v32qi)__a, (__v32qi)__b);
}
/// Sets each element of the result to the corresponding element of the
@@ -1996,10 +1995,9 @@ _mm256_sign_epi8(__m256i __a, __m256i __b)
/// \param __b
/// A 256-bit vector of [16 x i16].
/// \returns A 256-bit vector of [16 x i16] containing the result.
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_sign_epi16(__m256i __a, __m256i __b)
-{
- return (__m256i)__builtin_ia32_psignw256((__v16hi)__a, (__v16hi)__b);
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_sign_epi16(__m256i __a, __m256i __b) {
+ return (__m256i)__builtin_ia32_psignw256((__v16hi)__a, (__v16hi)__b);
}
/// Sets each element of the result to the corresponding element of the
@@ -2017,10 +2015,9 @@ _mm256_sign_epi16(__m256i __a, __m256i __b)
/// \param __b
/// A 256-bit vector of [8 x i32].
/// \returns A 256-bit vector of [8 x i32] containing the result.
-static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_sign_epi32(__m256i __a, __m256i __b)
-{
- return (__m256i)__builtin_ia32_psignd256((__v8si)__a, (__v8si)__b);
+static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+_mm256_sign_epi32(__m256i __a, __m256i __b) {
+ return (__m256i)__builtin_ia32_psignd256((__v8si)__a, (__v8si)__b);
}
/// Shifts each 128-bit half of the 256-bit integer vector \a a left by
diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h
index 30427c2..82974f6 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -7,13 +7,21 @@
*===-----------------------------------------------------------------------===
*/
-#ifndef __CLANG_FLOAT_H
-#define __CLANG_FLOAT_H
-
#if defined(__MVS__) && __has_include_next(<float.h>)
+#include <__float_header_macro.h>
#include_next <float.h>
#else
+#if !defined(__need_infinity_nan)
+#define __need_float_float
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
+ !defined(__STRICT_ANSI__)
+#define __need_infinity_nan
+#endif
+#include <__float_header_macro.h>
+#endif
+
+#ifdef __need_float_float
/* If we're on MinGW, fall back to the system's float.h, which might have
* additional definitions provided for Windows.
* For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx
@@ -26,171 +34,15 @@
# include_next <float.h>
-/* Undefine anything that we'll be redefining below. */
-# undef FLT_EVAL_METHOD
-# undef FLT_ROUNDS
-# undef FLT_RADIX
-# undef FLT_MANT_DIG
-# undef DBL_MANT_DIG
-# undef LDBL_MANT_DIG
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
- !defined(__STRICT_ANSI__) || \
- (defined(__cplusplus) && __cplusplus >= 201103L) || \
- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
-# undef DECIMAL_DIG
-# endif
-# undef FLT_DIG
-# undef DBL_DIG
-# undef LDBL_DIG
-# undef FLT_MIN_EXP
-# undef DBL_MIN_EXP
-# undef LDBL_MIN_EXP
-# undef FLT_MIN_10_EXP
-# undef DBL_MIN_10_EXP
-# undef LDBL_MIN_10_EXP
-# undef FLT_MAX_EXP
-# undef DBL_MAX_EXP
-# undef LDBL_MAX_EXP
-# undef FLT_MAX_10_EXP
-# undef DBL_MAX_10_EXP
-# undef LDBL_MAX_10_EXP
-# undef FLT_MAX
-# undef DBL_MAX
-# undef LDBL_MAX
-# undef FLT_EPSILON
-# undef DBL_EPSILON
-# undef LDBL_EPSILON
-# undef FLT_MIN
-# undef DBL_MIN
-# undef LDBL_MIN
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
- !defined(__STRICT_ANSI__) || \
- (defined(__cplusplus) && __cplusplus >= 201703L) || \
- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
-# undef FLT_TRUE_MIN
-# undef DBL_TRUE_MIN
-# undef LDBL_TRUE_MIN
-# undef FLT_DECIMAL_DIG
-# undef DBL_DECIMAL_DIG
-# undef LDBL_DECIMAL_DIG
-# undef FLT_HAS_SUBNORM
-# undef DBL_HAS_SUBNORM
-# undef LDBL_HAS_SUBNORM
-# endif
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
- !defined(__STRICT_ANSI__)
-# undef FLT_NORM_MAX
-# undef DBL_NORM_MAX
-# undef LDBL_NORM_MAX
-#endif
-#endif
-
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
- !defined(__STRICT_ANSI__)
-# undef INFINITY
-# undef NAN
-# undef FLT_SNAN
-# undef DBL_SNAN
-# undef LDBL_SNAN
-#endif
-
-/* Characteristics of floating point types, C99 5.2.4.2.2 */
-
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
- (defined(__cplusplus) && __cplusplus >= 201103L)
-#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
#endif
-#define FLT_ROUNDS (__builtin_flt_rounds())
-#define FLT_RADIX __FLT_RADIX__
-#define FLT_MANT_DIG __FLT_MANT_DIG__
-#define DBL_MANT_DIG __DBL_MANT_DIG__
-#define LDBL_MANT_DIG __LDBL_MANT_DIG__
-
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
- !defined(__STRICT_ANSI__) || \
- (defined(__cplusplus) && __cplusplus >= 201103L) || \
- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
-# define DECIMAL_DIG __DECIMAL_DIG__
-#endif
-
-#define FLT_DIG __FLT_DIG__
-#define DBL_DIG __DBL_DIG__
-#define LDBL_DIG __LDBL_DIG__
-
-#define FLT_MIN_EXP __FLT_MIN_EXP__
-#define DBL_MIN_EXP __DBL_MIN_EXP__
-#define LDBL_MIN_EXP __LDBL_MIN_EXP__
-
-#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
-#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
-#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
-
-#define FLT_MAX_EXP __FLT_MAX_EXP__
-#define DBL_MAX_EXP __DBL_MAX_EXP__
-#define LDBL_MAX_EXP __LDBL_MAX_EXP__
-
-#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
-#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
-#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
-
-#define FLT_MAX __FLT_MAX__
-#define DBL_MAX __DBL_MAX__
-#define LDBL_MAX __LDBL_MAX__
-
-#define FLT_EPSILON __FLT_EPSILON__
-#define DBL_EPSILON __DBL_EPSILON__
-#define LDBL_EPSILON __LDBL_EPSILON__
-
-#define FLT_MIN __FLT_MIN__
-#define DBL_MIN __DBL_MIN__
-#define LDBL_MIN __LDBL_MIN__
-
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
- !defined(__STRICT_ANSI__) || \
- (defined(__cplusplus) && __cplusplus >= 201703L) || \
- (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
-# define FLT_TRUE_MIN __FLT_DENORM_MIN__
-# define DBL_TRUE_MIN __DBL_DENORM_MIN__
-# define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
-# define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
-# define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
-# define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
-# define FLT_HAS_SUBNORM __FLT_HAS_DENORM__
-# define DBL_HAS_SUBNORM __DBL_HAS_DENORM__
-# define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
+#include <__float_float.h>
+#undef __need_float_float
#endif
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
- !defined(__STRICT_ANSI__)
- /* C23 5.2.5.3.2p28 */
-# define FLT_SNAN (__builtin_nansf(""))
-# define DBL_SNAN (__builtin_nans(""))
-# define LDBL_SNAN (__builtin_nansl(""))
-
- /* C23 5.2.5.3.3p29-30 */
-# define INFINITY (__builtin_inff())
-# define NAN (__builtin_nanf(""))
-
- /* C23 5.2.5.3.3p32 */
-# define FLT_NORM_MAX __FLT_NORM_MAX__
-# define DBL_NORM_MAX __DBL_NORM_MAX__
-# define LDBL_NORM_MAX __LDBL_NORM_MAX__
+#ifdef __need_infinity_nan
+#include <__float_infinity_nan.h>
+#undef __need_infinity_nan
#endif
-#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
-# define FLT16_MANT_DIG __FLT16_MANT_DIG__
-# define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__
-# define FLT16_DIG __FLT16_DIG__
-# define FLT16_MIN_EXP __FLT16_MIN_EXP__
-# define FLT16_MIN_10_EXP __FLT16_MIN_10_EXP__
-# define FLT16_MAX_EXP __FLT16_MAX_EXP__
-# define FLT16_MAX_10_EXP __FLT16_MAX_10_EXP__
-# define FLT16_MAX __FLT16_MAX__
-# define FLT16_EPSILON __FLT16_EPSILON__
-# define FLT16_MIN __FLT16_MIN__
-# define FLT16_TRUE_MIN __FLT16_TRUE_MIN__
-#endif /* __STDC_WANT_IEC_60559_TYPES_EXT__ */
-
#endif /* __MVS__ */
-#endif /* __CLANG_FLOAT_H */
diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap
index bdf5119..2e4d533 100644
--- a/clang/lib/Headers/module.modulemap
+++ b/clang/lib/Headers/module.modulemap
@@ -171,8 +171,22 @@ module _Builtin_intrinsics [system] [extern_c] {
// that module. The system float.h (if present) will be treated
// as a textual header in the sytem module.
module _Builtin_float [system] {
- header "float.h"
- export *
+ textual header "float.h"
+
+ explicit module float {
+ header "__float_float.h"
+ export *
+ }
+
+ explicit module header_macro {
+ header "__float_header_macro.h"
+ export *
+ }
+
+ explicit module infinity_nan {
+ header "__float_infinity_nan.h"
+ export *
+ }
}
module _Builtin_inttypes [system] {
diff --git a/clang/lib/Headers/tmmintrin.h b/clang/lib/Headers/tmmintrin.h
index 5d0f20f..cb4b36e 100644
--- a/clang/lib/Headers/tmmintrin.h
+++ b/clang/lib/Headers/tmmintrin.h
@@ -26,9 +26,6 @@
#define __zext128(x) \
(__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \
1, 2, 3)
-#define __anyext128(x) \
- (__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \
- 1, -1, -1)
#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
@@ -641,10 +638,9 @@ _mm_shuffle_pi8(__m64 __a, __m64 __b) {
/// A 128-bit integer vector containing control bytes corresponding to
/// positions in the destination.
/// \returns A 128-bit integer vector containing the resultant values.
-static __inline__ __m128i __DEFAULT_FN_ATTRS
-_mm_sign_epi8(__m128i __a, __m128i __b)
-{
- return (__m128i)__builtin_ia32_psignb128((__v16qi)__a, (__v16qi)__b);
+static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_sign_epi8(__m128i __a, __m128i __b) {
+ return (__m128i)__builtin_ia32_psignb128((__v16qi)__a, (__v16qi)__b);
}
/// For each 16-bit integer in the first source operand, perform one of
@@ -667,10 +663,9 @@ _mm_sign_epi8(__m128i __a, __m128i __b)
/// A 128-bit integer vector containing control words corresponding to
/// positions in the destination.
/// \returns A 128-bit integer vector containing the resultant values.
-static __inline__ __m128i __DEFAULT_FN_ATTRS
-_mm_sign_epi16(__m128i __a, __m128i __b)
-{
- return (__m128i)__builtin_ia32_psignw128((__v8hi)__a, (__v8hi)__b);
+static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_sign_epi16(__m128i __a, __m128i __b) {
+ return (__m128i)__builtin_ia32_psignw128((__v8hi)__a, (__v8hi)__b);
}
/// For each 32-bit integer in the first source operand, perform one of
@@ -693,10 +688,9 @@ _mm_sign_epi16(__m128i __a, __m128i __b)
/// A 128-bit integer vector containing control doublewords corresponding to
/// positions in the destination.
/// \returns A 128-bit integer vector containing the resultant values.
-static __inline__ __m128i __DEFAULT_FN_ATTRS
-_mm_sign_epi32(__m128i __a, __m128i __b)
-{
- return (__m128i)__builtin_ia32_psignd128((__v4si)__a, (__v4si)__b);
+static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_sign_epi32(__m128i __a, __m128i __b) {
+ return (__m128i)__builtin_ia32_psignd128((__v4si)__a, (__v4si)__b);
}
/// For each 8-bit integer in the first source operand, perform one of
@@ -719,11 +713,10 @@ _mm_sign_epi32(__m128i __a, __m128i __b)
/// A 64-bit integer vector containing control bytes corresponding to
/// positions in the destination.
/// \returns A 64-bit integer vector containing the resultant values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS
-_mm_sign_pi8(__m64 __a, __m64 __b)
-{
- return __trunc64(__builtin_ia32_psignb128((__v16qi)__anyext128(__a),
- (__v16qi)__anyext128(__b)));
+static __inline__ __m64 __DEFAULT_FN_ATTRS_CONSTEXPR _mm_sign_pi8(__m64 __a,
+ __m64 __b) {
+ return __trunc64(__builtin_ia32_psignb128((__v16qi)__zext128(__a),
+ (__v16qi)__zext128(__b)));
}
/// For each 16-bit integer in the first source operand, perform one of
@@ -746,11 +739,10 @@ _mm_sign_pi8(__m64 __a, __m64 __b)
/// A 64-bit integer vector containing control words corresponding to
/// positions in the destination.
/// \returns A 64-bit integer vector containing the resultant values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS
-_mm_sign_pi16(__m64 __a, __m64 __b)
-{
- return __trunc64(__builtin_ia32_psignw128((__v8hi)__anyext128(__a),
- (__v8hi)__anyext128(__b)));
+static __inline__ __m64 __DEFAULT_FN_ATTRS_CONSTEXPR _mm_sign_pi16(__m64 __a,
+ __m64 __b) {
+ return __trunc64(
+ __builtin_ia32_psignw128((__v8hi)__zext128(__a), (__v8hi)__zext128(__b)));
}
/// For each 32-bit integer in the first source operand, perform one of
@@ -773,14 +765,12 @@ _mm_sign_pi16(__m64 __a, __m64 __b)
/// A 64-bit integer vector containing two control doublewords corresponding
/// to positions in the destination.
/// \returns A 64-bit integer vector containing the resultant values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS
-_mm_sign_pi32(__m64 __a, __m64 __b)
-{
- return __trunc64(__builtin_ia32_psignd128((__v4si)__anyext128(__a),
- (__v4si)__anyext128(__b)));
+static __inline__ __m64 __DEFAULT_FN_ATTRS_CONSTEXPR _mm_sign_pi32(__m64 __a,
+ __m64 __b) {
+ return __trunc64(
+ __builtin_ia32_psignd128((__v4si)__zext128(__a), (__v4si)__zext128(__b)));
}
-#undef __anyext128
#undef __zext128
#undef __trunc64
#undef __DEFAULT_FN_ATTRS
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 238c5e2..65c324c 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -2186,6 +2186,8 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
void clang::normalizeModuleCachePath(FileManager &FileMgr, StringRef Path,
SmallVectorImpl<char> &NormalizedPath) {
NormalizedPath.assign(Path.begin(), Path.end());
- FileMgr.makeAbsolutePath(NormalizedPath);
- llvm::sys::path::remove_dots(NormalizedPath);
+ if (!NormalizedPath.empty()) {
+ FileMgr.makeAbsolutePath(NormalizedPath);
+ llvm::sys::path::remove_dots(NormalizedPath);
+ }
}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2990fd6..f99c01e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1498,6 +1498,24 @@ static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall) {
TheCall->setType(S.Context.getPointerType(RT));
}
+static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall) {
+ if (S.checkArgCountAtLeast(TheCall, 1))
+ return true;
+
+ for (Expr *Arg : TheCall->arguments()) {
+ // If argument is dependent on a template parameter, we can't resolve now.
+ if (Arg->isTypeDependent() || Arg->isValueDependent())
+ continue;
+ // Reject void types.
+ QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
+ if (ArgTy->isVoidType())
+ return S.Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
+ }
+
+ TheCall->setType(S.Context.UnsignedLongLongTy);
+ return false;
+}
+
namespace {
enum PointerAuthOpKind {
PAO_Strip,
@@ -2779,6 +2797,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
builtinAllocaAddrSpace(*this, TheCall);
}
break;
+ case Builtin::BI__builtin_infer_alloc_token:
+ if (checkBuiltinInferAllocToken(*this, TheCall))
+ return ExprError();
+ break;
case Builtin::BI__arithmetic_fence:
if (BuiltinArithmeticFence(TheCall))
return ExprError();
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 5b3e89f..2a485da 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -770,23 +770,81 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) {
}
}
-bool SemaHLSL::isSemanticValid(FunctionDecl *FD, DeclaratorDecl *D) {
- const auto *AnnotationAttr = D->getAttr<HLSLAnnotationAttr>();
- if (AnnotationAttr) {
- CheckSemanticAnnotation(FD, D, AnnotationAttr);
- return true;
+HLSLSemanticAttr *SemaHLSL::createSemantic(const SemanticInfo &Info,
+ DeclaratorDecl *TargetDecl) {
+ std::string SemanticName = Info.Semantic->getAttrName()->getName().upper();
+
+ if (SemanticName == "SV_DISPATCHTHREADID") {
+ return createSemanticAttr<HLSLSV_DispatchThreadIDAttr>(
+ *Info.Semantic, TargetDecl, Info.Index);
+ } else if (SemanticName == "SV_GROUPINDEX") {
+ return createSemanticAttr<HLSLSV_GroupIndexAttr>(*Info.Semantic, TargetDecl,
+ Info.Index);
+ } else if (SemanticName == "SV_GROUPTHREADID") {
+ return createSemanticAttr<HLSLSV_GroupThreadIDAttr>(*Info.Semantic,
+ TargetDecl, Info.Index);
+ } else if (SemanticName == "SV_GROUPID") {
+ return createSemanticAttr<HLSLSV_GroupIDAttr>(*Info.Semantic, TargetDecl,
+ Info.Index);
+ } else if (SemanticName == "SV_POSITION") {
+ return createSemanticAttr<HLSLSV_PositionAttr>(*Info.Semantic, TargetDecl,
+ Info.Index);
+ } else
+ Diag(Info.Semantic->getLoc(), diag::err_hlsl_unknown_semantic)
+ << *Info.Semantic;
+
+ return nullptr;
+}
+
+bool SemaHLSL::determineActiveSemanticOnScalar(FunctionDecl *FD,
+ DeclaratorDecl *D,
+ SemanticInfo &ActiveSemantic) {
+ if (ActiveSemantic.Semantic == nullptr) {
+ ActiveSemantic.Semantic = D->getAttr<HLSLSemanticAttr>();
+ if (ActiveSemantic.Semantic &&
+ ActiveSemantic.Semantic->isSemanticIndexExplicit())
+ ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
+ }
+
+ if (!ActiveSemantic.Semantic) {
+ Diag(D->getLocation(), diag::err_hlsl_missing_semantic_annotation);
+ return false;
+ }
+
+ auto *A = createSemantic(ActiveSemantic, D);
+ if (!A)
+ return false;
+
+ checkSemanticAnnotation(FD, D, A);
+ FD->addAttr(A);
+ return true;
+}
+
+bool SemaHLSL::determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *D,
+ SemanticInfo &ActiveSemantic) {
+ if (ActiveSemantic.Semantic == nullptr) {
+ ActiveSemantic.Semantic = D->getAttr<HLSLSemanticAttr>();
+ if (ActiveSemantic.Semantic &&
+ ActiveSemantic.Semantic->isSemanticIndexExplicit())
+ ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
}
const Type *T = D->getType()->getUnqualifiedDesugaredType();
const RecordType *RT = dyn_cast<RecordType>(T);
if (!RT)
- return false;
+ return determineActiveSemanticOnScalar(FD, D, ActiveSemantic);
const RecordDecl *RD = RT->getDecl();
for (FieldDecl *Field : RD->fields()) {
- if (!isSemanticValid(FD, Field))
+ SemanticInfo Info = ActiveSemantic;
+ if (!determineActiveSemantic(FD, Field, Info)) {
+ Diag(Field->getLocation(), diag::note_hlsl_semantic_used_here) << Field;
return false;
+ }
+ if (ActiveSemantic.Semantic)
+ ActiveSemantic = Info;
}
+
return true;
}
@@ -853,8 +911,11 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
}
for (ParmVarDecl *Param : FD->parameters()) {
- if (!isSemanticValid(FD, Param)) {
- Diag(FD->getLocation(), diag::err_hlsl_missing_semantic_annotation);
+ SemanticInfo ActiveSemantic;
+ ActiveSemantic.Semantic = nullptr;
+ ActiveSemantic.Index = std::nullopt;
+
+ if (!determineActiveSemantic(FD, Param, ActiveSemantic)) {
Diag(Param->getLocation(), diag::note_previous_decl) << Param;
FD->setInvalidDecl();
}
@@ -862,31 +923,31 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
// FIXME: Verify return type semantic annotation.
}
-void SemaHLSL::CheckSemanticAnnotation(
- FunctionDecl *EntryPoint, const Decl *Param,
- const HLSLAnnotationAttr *AnnotationAttr) {
+void SemaHLSL::checkSemanticAnnotation(FunctionDecl *EntryPoint,
+ const Decl *Param,
+ const HLSLSemanticAttr *SemanticAttr) {
auto *ShaderAttr = EntryPoint->getAttr<HLSLShaderAttr>();
assert(ShaderAttr && "Entry point has no shader attribute");
llvm::Triple::EnvironmentType ST = ShaderAttr->getType();
- switch (AnnotationAttr->getKind()) {
+ switch (SemanticAttr->getKind()) {
case attr::HLSLSV_DispatchThreadID:
case attr::HLSLSV_GroupIndex:
case attr::HLSLSV_GroupThreadID:
case attr::HLSLSV_GroupID:
if (ST == llvm::Triple::Compute)
return;
- DiagnoseAttrStageMismatch(AnnotationAttr, ST, {llvm::Triple::Compute});
+ DiagnoseAttrStageMismatch(SemanticAttr, ST, {llvm::Triple::Compute});
break;
case attr::HLSLSV_Position:
// TODO(#143523): allow use on other shader types & output once the overall
// semantic logic is implemented.
if (ST == llvm::Triple::Pixel)
return;
- DiagnoseAttrStageMismatch(AnnotationAttr, ST, {llvm::Triple::Pixel});
+ DiagnoseAttrStageMismatch(SemanticAttr, ST, {llvm::Triple::Pixel});
break;
default:
- llvm_unreachable("Unknown HLSLAnnotationAttr");
+ llvm_unreachable("Unknown SemanticAttr");
}
}
@@ -1661,28 +1722,30 @@ void SemaHLSL::diagnoseSystemSemanticAttr(Decl *D, const ParsedAttr &AL,
diagnoseInputIDType(ValueType, AL);
if (IsOutput)
Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
- Attribute = createSemanticAttr<HLSLSV_DispatchThreadIDAttr>(AL, Index);
+ Attribute =
+ createSemanticAttr<HLSLSV_DispatchThreadIDAttr>(AL, nullptr, Index);
} else if (SemanticName == "SV_GROUPINDEX") {
if (IsOutput)
Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
- Attribute = createSemanticAttr<HLSLSV_GroupIndexAttr>(AL, Index);
+ Attribute = createSemanticAttr<HLSLSV_GroupIndexAttr>(AL, nullptr, Index);
} else if (SemanticName == "SV_GROUPTHREADID") {
diagnoseInputIDType(ValueType, AL);
if (IsOutput)
Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
- Attribute = createSemanticAttr<HLSLSV_GroupThreadIDAttr>(AL, Index);
+ Attribute =
+ createSemanticAttr<HLSLSV_GroupThreadIDAttr>(AL, nullptr, Index);
} else if (SemanticName == "SV_GROUPID") {
diagnoseInputIDType(ValueType, AL);
if (IsOutput)
Diag(AL.getLoc(), diag::err_hlsl_semantic_output_not_supported) << AL;
- Attribute = createSemanticAttr<HLSLSV_GroupIDAttr>(AL, Index);
+ Attribute = createSemanticAttr<HLSLSV_GroupIDAttr>(AL, nullptr, Index);
} else if (SemanticName == "SV_POSITION") {
const auto *VT = ValueType->getAs<VectorType>();
if (!ValueType->hasFloatingRepresentation() ||
(VT && VT->getNumElements() > 4))
Diag(AL.getLoc(), diag::err_hlsl_attr_invalid_type)
<< AL << "float/float1/float2/float3/float4";
- Attribute = createSemanticAttr<HLSLSV_PositionAttr>(AL, Index);
+ Attribute = createSemanticAttr<HLSLSV_PositionAttr>(AL, nullptr, Index);
} else
Diag(AL.getLoc(), diag::err_hlsl_unknown_semantic) << AL;
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index ee9b2b3..f0f3832 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -3086,6 +3086,7 @@ bool SemaOpenACC::CreateReductionCombinerRecipe(
case OpenACCReductionOperator::Invalid:
llvm_unreachable("Invalid should have been caught above");
}
+ llvm_unreachable("Unhandled case");
};
auto tryCombiner = [&, this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE,
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 5b5b1b6..6d5cb0f 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -7246,7 +7246,9 @@ void SemaOpenMP::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
FunctionDecl *UDecl = nullptr;
if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
- if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
+ // FIXME: Should this compare the template parameter lists on all levels?
+ if (SemaRef.Context.isSameTemplateParameterList(
+ FTD->getTemplateParameters(), TemplateParamLists.back()))
UDecl = FTD->getTemplatedDecl();
} else if (!IsTemplated)
UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp
index 05d5669..42f52d0 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp
@@ -524,13 +524,12 @@ bool initializeScanCompilerInstance(
// Use the dependency scanning optimized file system if requested to do so.
if (DepFS) {
DepFS->resetBypassedPathPrefix();
- if (!ScanInstance.getHeaderSearchOpts().ModuleCachePath.empty()) {
- SmallString<256> ModulesCachePath;
- normalizeModuleCachePath(
- ScanInstance.getFileManager(),
- ScanInstance.getHeaderSearchOpts().ModuleCachePath, ModulesCachePath);
+ SmallString<256> ModulesCachePath;
+ normalizeModuleCachePath(ScanInstance.getFileManager(),
+ ScanInstance.getHeaderSearchOpts().ModuleCachePath,
+ ModulesCachePath);
+ if (!ModulesCachePath.empty())
DepFS->setBypassedPathPrefix(ModulesCachePath);
- }
ScanInstance.setDependencyDirectivesGetter(
std::make_unique<ScanningDependencyDirectivesGetter>(
diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp
index 48cf811..00218ba 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -1162,6 +1162,19 @@ namespace IndirectFieldInit {
static_assert(s2.x == 1 && s2.y == 2 && s2.a == 3 && s2.b == 4);
#endif
+
+
+ struct B {
+ struct {
+ union {
+ int x = 3;
+ };
+ int y = this->x;
+ };
+
+ constexpr B() {}
+ };
+ static_assert(B().y == 3, "");
}
namespace InheritedConstructor {
@@ -1840,3 +1853,11 @@ namespace DiamondDowncast {
constexpr Middle2 &fail = (Middle2&)top1; // both-error {{must be initialized by a constant expression}} \
// both-note {{cannot cast object of dynamic type 'const Bottom' to type 'Middle2'}}
}
+
+namespace PrimitiveInitializedByInitList {
+ constexpr struct {
+ int a;
+ int b{this->a};
+ } c{ 17 };
+ static_assert(c.b == 17, "");
+}
diff --git a/clang/test/CIR/CodeGen/builtin_prefetech.c b/clang/test/CIR/CodeGen/builtin_prefetech.c
new file mode 100644
index 0000000..cfe85b9
--- /dev/null
+++ b/clang/test/CIR/CodeGen/builtin_prefetech.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=OGCG
+
+void foo(void *a) {
+ __builtin_prefetch(a); // rw=0, locality=3
+ __builtin_prefetch(a, 0); // rw=0, locality=3
+ __builtin_prefetch(a, 1); // rw=1, locality=3
+ __builtin_prefetch(a, 1, 1); // rw=1, locality=1
+}
+
+// CIR-LABEL: cir.func dso_local @foo(
+// CIR: %[[ALLOCA:.*]] = cir.alloca !cir.ptr<!void>
+// CIR: cir.store %arg0, %[[ALLOCA]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
+// CIR: %[[P1:.*]] = cir.load{{.*}} %[[ALLOCA]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CIR: cir.prefetch read locality(3) %[[P1]] : !cir.ptr<!void>
+// CIR: %[[P2:.*]] = cir.load{{.*}} %[[ALLOCA]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CIR: cir.prefetch read locality(3) %[[P2]] : !cir.ptr<!void>
+// CIR: %[[P3:.*]] = cir.load{{.*}} %[[ALLOCA]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CIR: cir.prefetch write locality(3) %[[P3]] : !cir.ptr<!void>
+// CIR: %[[P4:.*]] = cir.load{{.*}} %[[ALLOCA]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CIR: cir.prefetch write locality(1) %[[P4]] : !cir.ptr<!void>
+// CIR: cir.return
+
+// LLVM-LABEL: define dso_local void @foo(
+// LLVM: [[ALLOCA:%.*]] = alloca ptr, i64 1
+// LLVM: store ptr {{.*}}, ptr [[ALLOCA]]
+// LLVM: [[LP1:%.*]] = load ptr, ptr [[ALLOCA]]
+// LLVM: call void @llvm.prefetch.p0(ptr [[LP1]], i32 0, i32 3, i32 1)
+// LLVM: [[LP2:%.*]] = load ptr, ptr [[ALLOCA]]
+// LLVM: call void @llvm.prefetch.p0(ptr [[LP2]], i32 0, i32 3, i32 1)
+// LLVM: [[LP3:%.*]] = load ptr, ptr [[ALLOCA]]
+// LLVM: call void @llvm.prefetch.p0(ptr [[LP3]], i32 1, i32 3, i32 1)
+// LLVM: [[LP4:%.*]] = load ptr, ptr [[ALLOCA]]
+// LLVM: call void @llvm.prefetch.p0(ptr [[LP4]], i32 1, i32 1, i32 1)
+// LLVM: ret void
+
+// OGCG-LABEL: define dso_local void @foo(ptr
+// OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1)
+// OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1)
+// OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1)
+// OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 1, i32 1)
+// OGCG: ret void
diff --git a/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp b/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp
index e3b8533..9ddb68f 100644
--- a/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp
+++ b/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp
@@ -172,3 +172,37 @@ B *offset_cast(A *a) {
// OGCG-NEXT: br label %[[LABEL_END]]
// OGCG: [[LABEL_END]]:
// OGCG-NEXT: phi ptr [ %[[RESULT]], %[[LABEL_NOTNULL]] ], [ null, %[[LABEL_NULL]] ]
+
+Derived *ptr_cast_always_fail(Base2 *ptr) {
+ return dynamic_cast<Derived *>(ptr);
+ }
+
+// CIR: cir.func {{.*}} @_Z20ptr_cast_always_failP5Base2
+// CIR: %{{.+}} = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!rec_Base2>>, !cir.ptr<!rec_Base2>
+// CIR-NEXT: %[[RESULT:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!rec_Derived>
+// CIR-NEXT: cir.store %[[RESULT]], %{{.*}} : !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>
+
+// LLVM: define {{.*}} ptr @_Z20ptr_cast_always_failP5Base2
+// LLVM-NEXT: ret ptr null
+
+// OGCG: define {{.*}} ptr @_Z20ptr_cast_always_failP5Base2
+// OGCG-NEXT: entry:
+// OGCG-NEXT: ret ptr null
+
+Derived &ref_cast_always_fail(Base2 &ref) {
+ return dynamic_cast<Derived &>(ref);
+}
+
+// CIR: cir.func {{.*}} @_Z20ref_cast_always_failR5Base2
+// CIR: %{{.+}} = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!rec_Base2>>, !cir.ptr<!rec_Base2>
+// CIR-NEXT: cir.call @__cxa_bad_cast() : () -> ()
+// CIR-NEXT: cir.unreachable
+
+// LLVM: define {{.*}} ptr @_Z20ref_cast_always_failR5Base2
+// LLVM-NEXT: tail call void @__cxa_bad_cast()
+// LLVM-NEXT: unreachable
+
+// OGCG: define {{.*}} ptr @_Z20ref_cast_always_failR5Base2
+// OGCG-NEXT: entry:
+// OGCG-NEXT: tail call void @__cxa_bad_cast()
+// OGCG-NEXT: unreachable
diff --git a/clang/test/CIR/CodeGen/try-catch.cpp b/clang/test/CIR/CodeGen/try-catch.cpp
index 5a50310..1e4d2a6 100644
--- a/clang/test/CIR/CodeGen/try-catch.cpp
+++ b/clang/test/CIR/CodeGen/try-catch.cpp
@@ -117,3 +117,50 @@ void try_catch_with_empty_catch_all_2() {
// OGCG: %[[RESULT:.*]] = add nsw i32 %[[TMP_A]], 1
// OGCG: store i32 %[[RESULT]], ptr %[[A_ADDR]], align 4
// OGCG: ret void
+
+void try_catch_with_alloca() {
+ try {
+ int a;
+ int b;
+ int c = a + b;
+ } catch (...) {
+ }
+}
+
+// CIR: cir.scope {
+// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"]
+// CIR: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b"]
+// CIR: %[[C_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c", init]
+// CIR: cir.try {
+// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[RESULT:.*]] = cir.binop(add, %[[TMP_A]], %[[TMP_B]]) nsw : !s32i
+// CIR: cir.store{{.*}} %[[RESULT]], %[[C_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR: cir.yield
+// CIR: }
+// CIR: }
+
+// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[C_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: br label %[[LABEL_1:.*]]
+// LLVM: [[LABEL_1]]:
+// LLVM: br label %[[LABEL_2:.*]]
+// LLVM: [[LABEL_2]]:
+// LLVM: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// LLVM: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// LLVM: %[[RESULT:.*]] = add nsw i32 %[[TMP_A]], %[[TMP_B]]
+// LLVM: store i32 %[[RESULT]], ptr %[[C_ADDR]], align 4
+// LLVM: br label %[[LABEL_3:.*]]
+// LLVM: [[LABEL_3]]:
+// LLVM: br label %[[LABEL_4:.*]]
+// LLVM: [[LABEL_4]]:
+// LLVM: ret void
+
+// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[C_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// OGCG: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// OGCG: %[[RESULT:.*]] = add nsw i32 %[[TMP_A]], %[[TMP_B]]
+// OGCG: store i32 %[[RESULT]], ptr %[[C_ADDR]], align 4
diff --git a/clang/test/CIR/CodeGenOpenACC/atomic-write.cpp b/clang/test/CIR/CodeGenOpenACC/atomic-write.cpp
new file mode 100644
index 0000000..1685534
--- /dev/null
+++ b/clang/test/CIR/CodeGenOpenACC/atomic-write.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fopenacc -triple x86_64-linux-gnu -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir -triple x86_64-linux-pc %s -o - | FileCheck %s
+
+extern "C" bool condition(int x, unsigned int y, float f);
+extern "C" double do_thing(float f);
+
+struct ConvertsToScalar {
+ operator float();
+};
+
+void use(int x, unsigned int y, float f, ConvertsToScalar cts) {
+ // CHECK: cir.func{{.*}}(%[[X_ARG:.*]]: !s32i{{.*}}, %[[Y_ARG:.*]]: !u32i{{.*}}, %[[F_ARG:.*]]: !cir.float{{.*}}){{.*}}, %[[CTS_ARG:.*]]: !rec_ConvertsToScalar{{.*}}) {
+ // CHECK-NEXT: %[[X_ALLOC:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
+ // CHECK-NEXT: %[[Y_ALLOC:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["y", init]
+ // CHECK-NEXT: %[[F_ALLOC:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["f", init]
+ // CHECK-NEXT: %[[CTS_ALLOC:.*]] = cir.alloca !rec_ConvertsToScalar, !cir.ptr<!rec_ConvertsToScalar>, ["cts", init]
+ //
+ // CHECK-NEXT: cir.store %[[X_ARG]], %[[X_ALLOC]] : !s32i, !cir.ptr<!s32i>
+ // CHECK-NEXT: cir.store %[[Y_ARG]], %[[Y_ALLOC]] : !u32i, !cir.ptr<!u32i>
+ // CHECK-NEXT: cir.store %[[F_ARG]], %[[F_ALLOC]] : !cir.float, !cir.ptr<!cir.float>
+ // CHECK-NEXT: cir.store %[[CTS_ARG]], %[[CTS_ALLOC]] : !rec_ConvertsToScalar, !cir.ptr<!rec_ConvertsToScalar>
+
+ // CHECK-NEXT: %[[Y_LOAD:.*]] = cir.load {{.*}}%[[Y_ALLOC]] : !cir.ptr<!u32i>, !u32i
+ // CHECK-NEXT: %[[Y_TO_FLOAT:.*]] = cir.cast int_to_float %[[Y_LOAD]] : !u32i -> !cir.float
+ // CHECK-NEXT: %[[F_LOAD:.*]] = cir.load {{.*}}%[[F_ALLOC]] : !cir.ptr<!cir.float>, !cir.float
+ // CHECK-NEXT: %[[MUL:.*]] = cir.binop(mul, %[[Y_TO_FLOAT]], %[[F_LOAD]]) : !cir.float
+ // CHECK-NEXT: %[[RHS_CAST:.*]] = cir.cast float_to_int %[[MUL]] : !cir.float -> !s32i
+ // CHECK-NEXT: acc.atomic.write %[[X_ALLOC]] = %[[RHS_CAST]] : !cir.ptr<!s32i>, !s32i
+#pragma acc atomic write
+ x = y * f;
+
+ // CHECK-NEXT: %[[F_LOAD:.*]] = cir.load {{.*}}%[[F_ALLOC]] : !cir.ptr<!cir.float>, !cir.float
+ // CHECK-NEXT: %[[CALL:.*]] = cir.call @do_thing(%[[F_LOAD]]) : (!cir.float) -> !cir.double
+ // CHECK-NEXT: %[[CALL_CAST:.*]] = cir.cast float_to_int %[[CALL]] : !cir.double -> !u32i
+ // CHECK-NEXT: acc.atomic.write %[[Y_ALLOC]] = %[[CALL_CAST]] : !cir.ptr<!u32i>, !u32i
+#pragma acc atomic write
+ y = do_thing(f);
+
+ // CHECK-NEXT: %[[X_LOAD:.*]] = cir.load {{.*}}%[[X_ALLOC]] : !cir.ptr<!s32i>, !s32i
+ // CHECK-NEXT: %[[X_CAST:.*]] = cir.cast int_to_float %[[X_LOAD]] : !s32i -> !cir.float
+ // CHECK-NEXT: %[[THING_CALL:.*]] = cir.call @do_thing(%[[X_CAST]]) : (!cir.float) -> !cir.double
+ // CHECK-NEXT: %[[THING_CAST:.*]] = cir.cast floating %[[THING_CALL]] : !cir.double -> !cir.float
+ // CHECK-NEXT: %[[X_LOAD:.*]] = cir.load {{.*}}%[[X_ALLOC]] : !cir.ptr<!s32i>, !s32i
+ // CHECK-NEXT: %[[Y_LOAD:.*]] = cir.load {{.*}}%[[Y_ALLOC]] : !cir.ptr<!u32i>, !u32i
+ // CHECK-NEXT: %[[F_LOAD:.*]] = cir.load {{.*}}%[[F_ALLOC]] : !cir.ptr<!cir.float>, !cir.float
+ // CHECK-NEXT: %[[COND_CALL:.*]] = cir.call @condition(%[[X_LOAD]], %[[Y_LOAD]], %[[F_LOAD]]) : (!s32i, !u32i, !cir.float) -> !cir.bool
+ // CHECK-NEXT: %[[COND_CAST:.*]] = builtin.unrealized_conversion_cast %[[COND_CALL]] : !cir.bool to i1
+ // CHECK-NEXT: acc.atomic.write if(%[[COND_CAST]]) %[[F_ALLOC]] = %[[THING_CAST]] : !cir.ptr<!cir.float>, !cir.float
+#pragma acc atomic write if (condition(x, y, f))
+ f = do_thing(x);
+
+ // CHECK-NEXT: %[[CTS_CONV_CALL:.*]] = cir.call @{{.*}}(%[[CTS_ALLOC]]) : (!cir.ptr<!rec_ConvertsToScalar>) -> !cir.float
+ // CHECK-NEXT: acc.atomic.write %[[F_ALLOC]] = %[[CTS_CONV_CALL]] : !cir.ptr<!cir.float>, !cir.float
+#pragma acc atomic write
+ f = cts;
+}
diff --git a/clang/test/CodeGen/X86/avx2-builtins.c b/clang/test/CodeGen/X86/avx2-builtins.c
index 03b1bde..5c52d84 100644
--- a/clang/test/CodeGen/X86/avx2-builtins.c
+++ b/clang/test/CodeGen/X86/avx2-builtins.c
@@ -1155,23 +1155,30 @@ __m256i test_mm256_shufflelo_epi16(__m256i a) {
return _mm256_shufflelo_epi16(a, 83);
}
TEST_CONSTEXPR(match_v16hi(_mm256_shufflelo_epi16(((__m256i)(__v16hi){ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}), 83), 3,0,1,1, 4,5,6,7, 11,8,9,9, 12,13,14,15) );
+
__m256i test_mm256_sign_epi8(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_sign_epi8
// CHECK: call <32 x i8> @llvm.x86.avx2.psign.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}})
return _mm256_sign_epi8(a, b);
}
+TEST_CONSTEXPR(match_v32qi(_mm256_sign_epi8(
+ (__m256i)(__v32qs){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
+ (__m256i)(__v32qs){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1}),
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1));
__m256i test_mm256_sign_epi16(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_sign_epi16
// CHECK: call <16 x i16> @llvm.x86.avx2.psign.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
return _mm256_sign_epi16(a, b);
}
+TEST_CONSTEXPR(match_v16hi(_mm256_sign_epi16((__m256i)(__v16hi){0x77,0x77,0xbe,0xbe, -0x9,-0x9,-0x8,-0x8, 0,0,0,0, 0,0,0,0}, (__m256i)(__v16hi){-1,-256,1,256, -512,-1028,512,1028, -2048,-4096,0,0, 0,0,0,0}), -0x77,-0x77,0xbe,0xbe, 0x9,0x9,-0x8,-0x8, 0,0,0,0, 0,0,0,0));
__m256i test_mm256_sign_epi32(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_sign_epi32
// CHECK: call <8 x i32> @llvm.x86.avx2.psign.d(<8 x i32> %{{.*}}, <8 x i32> %{{.*}})
return _mm256_sign_epi32(a, b);
}
+TEST_CONSTEXPR(match_v8si(_mm256_sign_epi32((__m256i)(__v8si){0xbeef,0xfeed,0xbead,0xdeed, -1,2,-3,4}, (__m256i)(__v8si){0,0,0,0,-1,-1,-1,-1}), 0,0,0,0, 1,-2,3,-4));
__m256i test_mm256_slli_epi16(__m256i a) {
// CHECK-LABEL: test_mm256_slli_epi16
diff --git a/clang/test/CodeGen/X86/mmx-builtins.c b/clang/test/CodeGen/X86/mmx-builtins.c
index 7674255..2731380 100644
--- a/clang/test/CodeGen/X86/mmx-builtins.c
+++ b/clang/test/CodeGen/X86/mmx-builtins.c
@@ -602,23 +602,28 @@ __m64 test_mm_shuffle_pi16(__m64 a) {
return _mm_shuffle_pi16(a, 3);
}
TEST_CONSTEXPR(match_v4hi(_mm_shuffle_pi16(((__m64)(__v4hi){0,1,2,3}), 3), 3,0,0,0));
+
__m64 test_mm_sign_pi8(__m64 a, __m64 b) {
// CHECK-LABEL: test_mm_sign_pi8
// CHECK: call <16 x i8> @llvm.x86.ssse3.psign.b.128(
return _mm_sign_pi8(a, b);
}
+TEST_CONSTEXPR(match_v8qi(_mm_sign_pi8((__m64)(__v8qi){0,0,0,0, 0,0,0,0}, (__m64)(__v8qi){0,0,0,0, 0,0,0,0}), 0,0,0,0, 0,0,0,0));
+TEST_CONSTEXPR(match_v8qi(_mm_sign_pi8((__m64)(__v8qi){6,7,6,7, 6,7,6,7}, (__m64)(__v8qi){1,1,1,1, 0,0,0,0}), 6,7,6,7, 0,0,0,0));
__m64 test_mm_sign_pi16(__m64 a, __m64 b) {
// CHECK-LABEL: test_mm_sign_pi16
// CHECK: call <8 x i16> @llvm.x86.ssse3.psign.w.128(
return _mm_sign_pi16(a, b);
}
+TEST_CONSTEXPR(match_v4hi(_mm_sign_pi16((__m64)(__v4hi){-1,0,1,0}, (__m64)(__v4hi){1,0,-1,0}), -1,0,-1,0));
__m64 test_mm_sign_pi32(__m64 a, __m64 b) {
// CHECK-LABEL: test_mm_sign_pi32
// CHECK: call <4 x i32> @llvm.x86.ssse3.psign.d.128(
return _mm_sign_pi32(a, b);
}
+TEST_CONSTEXPR(match_v2si(_mm_sign_pi32((__m64)(__v2si){0x7FFF, -1}, (__m64)(__v2si){-1, 0x7FFF}), -0x7FFF, -1));
__m64 test_mm_sll_pi16(__m64 a, __m64 b) {
// CHECK-LABEL: test_mm_sll_pi16
diff --git a/clang/test/CodeGen/X86/ssse3-builtins.c b/clang/test/CodeGen/X86/ssse3-builtins.c
index f70afc0..b7a4a2f 100644
--- a/clang/test/CodeGen/X86/ssse3-builtins.c
+++ b/clang/test/CodeGen/X86/ssse3-builtins.c
@@ -125,15 +125,18 @@ __m128i test_mm_sign_epi8(__m128i a, __m128i b) {
// CHECK: call <16 x i8> @llvm.x86.ssse3.psign.b.128(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
return _mm_sign_epi8(a, b);
}
+TEST_CONSTEXPR(match_v16qi(_mm_sign_epi8((__m128i)(__v16qs){11,0,13,14, 0,16,17,18, 19,20,21,22, 23,24,25,26}, (__m128i)(__v16qs){0,1,0,1, -1,1,0,0, 0,0,1,1, -1,0,-1,0}), 0,0,0,14, 0,16,0,0, 0,0,21,22, -23,0,-25,0));
__m128i test_mm_sign_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_sign_epi16
// CHECK: call <8 x i16> @llvm.x86.ssse3.psign.w.128(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
return _mm_sign_epi16(a, b);
}
+TEST_CONSTEXPR(match_v8hi(_mm_sign_epi16((__m128i)(__v8hi){0,-2,0,-4,0,-6,0,-8}, (__m128i)(__v8hi){-1,-2,-3,-4,-5,-6,7,-8}), 0,2,0,4,0,6,0,8));
__m128i test_mm_sign_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_sign_epi32
// CHECK: call <4 x i32> @llvm.x86.ssse3.psign.d.128(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
return _mm_sign_epi32(a, b);
}
+TEST_CONSTEXPR(match_v4si(_mm_sign_epi32((__m128i)(__v4si){-1,-2,-3,-4}, (__m128i)(__v4si){-4,-3,-2,-1}), 1,2,3,4));
diff --git a/clang/test/CodeGenHLSL/semantics/semantic-struct-1.hlsl b/clang/test/CodeGenHLSL/semantics/semantic-struct-1.hlsl
new file mode 100644
index 0000000..ddd0bae
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic-struct-1.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+
+
+struct Input {
+ uint Idx : SV_DispatchThreadID;
+
+};
+
+// Make sure SV_DispatchThreadID translated into dx.thread.id.
+
+// CHECK: define void @foo()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#TMP:]] = insertvalue %struct.Input poison, i32 %[[#ID]], 0
+// CHECK: %[[#VAR:]] = alloca %struct.Input, align 8
+// CHECK: store %struct.Input %[[#TMP]], ptr %[[#VAR]], align 4
+// CHECK-DXIL: call void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+// CHECK-SPIRV: call spir_func void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(Input input) {}
+
diff --git a/clang/test/CodeGenHLSL/semantics/semantic-struct-2.hlsl b/clang/test/CodeGenHLSL/semantics/semantic-struct-2.hlsl
new file mode 100644
index 0000000..0d9c91e
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic-struct-2.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+
+
+struct Input {
+ uint Idx : SV_DispatchThreadID;
+ uint Gid : SV_GroupID;
+};
+
+// Make sure SV_DispatchThreadID translated into dx.thread.id.
+
+// CHECK: define void @foo()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#TMP1:]] = insertvalue %struct.Input poison, i32 %[[#ID]], 0
+// CHECK-DXIL: %[[#GID:]] = call i32 @llvm.[[TARGET]].group.id(i32 0)
+// CHECK-SPIRV:%[[#GID:]] = call i32 @llvm.[[TARGET]].group.id.i32(i32 0)
+// CHECK: %[[#TMP2:]] = insertvalue %struct.Input %[[#TMP1]], i32 %[[#GID]], 1
+// CHECK: %[[#VAR:]] = alloca %struct.Input, align 8
+// CHECK: store %struct.Input %[[#TMP2]], ptr %[[#VAR]], align 4
+// CHECK-DXIL: call void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+// CHECK-SPIRV: call spir_func void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(Input input) {}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic-struct-nested-inherit.hlsl b/clang/test/CodeGenHLSL/semantics/semantic-struct-nested-inherit.hlsl
new file mode 100644
index 0000000..f4c4d86
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic-struct-nested-inherit.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+
+
+struct Inner {
+ uint Gid;
+};
+
+struct Input {
+ uint Idx : SV_DispatchThreadID;
+ Inner inner : SV_GroupIndex;
+};
+
+// Make sure SV_DispatchThreadID translated into dx.thread.id.
+
+// CHECK: define void @foo()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#TMP1:]] = insertvalue %struct.Input poison, i32 %[[#ID]], 0
+// CHECK-DXIL: %[[#GID:]] = call i32 @llvm.dx.flattened.thread.id.in.group()
+// CHECK-SPIRV:%[[#GID:]] = call i32 @llvm.spv.flattened.thread.id.in.group()
+// CHECK: %[[#TMP2:]] = insertvalue %struct.Inner poison, i32 %[[#GID]], 0
+// CHECK: %[[#TMP3:]] = insertvalue %struct.Input %[[#TMP1]], %struct.Inner %[[#TMP2]], 1
+// CHECK: %[[#VAR:]] = alloca %struct.Input, align 8
+// CHECK: store %struct.Input %[[#TMP3]], ptr %[[#VAR]], align 4
+// CHECK-DXIL: call void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+// CHECK-SPIRV: call spir_func void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(Input input) {}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic-struct-nested-shadow.hlsl b/clang/test/CodeGenHLSL/semantics/semantic-struct-nested-shadow.hlsl
new file mode 100644
index 0000000..e1344dd
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic-struct-nested-shadow.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+
+
+struct Inner {
+ uint Gid : SV_GroupID;
+};
+
+struct Input {
+ uint Idx : SV_DispatchThreadID;
+ Inner inner : SV_GroupIndex;
+};
+
+// Make sure SV_DispatchThreadID translated into dx.thread.id.
+
+// CHECK: define void @foo()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#TMP1:]] = insertvalue %struct.Input poison, i32 %[[#ID]], 0
+// CHECK-DXIL: %[[#GID:]] = call i32 @llvm.dx.flattened.thread.id.in.group()
+// CHECK-SPIRV:%[[#GID:]] = call i32 @llvm.spv.flattened.thread.id.in.group()
+// CHECK: %[[#TMP2:]] = insertvalue %struct.Inner poison, i32 %[[#GID]], 0
+// CHECK: %[[#TMP3:]] = insertvalue %struct.Input %[[#TMP1]], %struct.Inner %[[#TMP2]], 1
+// CHECK: %[[#VAR:]] = alloca %struct.Input, align 8
+// CHECK: store %struct.Input %[[#TMP3]], ptr %[[#VAR]], align 4
+// CHECK-DXIL: call void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+// CHECK-SPIRV: call spir_func void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(Input input) {}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic-struct-nested.hlsl b/clang/test/CodeGenHLSL/semantics/semantic-struct-nested.hlsl
new file mode 100644
index 0000000..cd6f946
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic-struct-nested.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
+// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv
+
+
+struct Inner {
+ uint Gid : SV_GroupID;
+};
+
+struct Input {
+ uint Idx : SV_DispatchThreadID;
+ Inner inner;
+};
+
+// Make sure SV_DispatchThreadID translated into dx.thread.id.
+
+// CHECK: define void @foo()
+// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
+// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0)
+// CHECK: %[[#TMP1:]] = insertvalue %struct.Input poison, i32 %[[#ID]], 0
+// CHECK-DXIL: %[[#GID:]] = call i32 @llvm.[[TARGET]].group.id(i32 0)
+// CHECK-SPIRV:%[[#GID:]] = call i32 @llvm.[[TARGET]].group.id.i32(i32 0)
+// CHECK: %[[#TMP2:]] = insertvalue %struct.Inner poison, i32 %[[#GID]], 0
+// CHECK: %[[#TMP3:]] = insertvalue %struct.Input %[[#TMP1]], %struct.Inner %[[#TMP2]], 1
+// CHECK: %[[#VAR:]] = alloca %struct.Input, align 8
+// CHECK: store %struct.Input %[[#TMP3]], ptr %[[#VAR]], align 4
+// CHECK-DXIL: call void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+// CHECK-SPIRV: call spir_func void @{{.*}}foo{{.*}}(ptr %[[#VAR]])
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(Input input) {}
diff --git a/clang/test/Driver/DTLTO/Inputs/dtlto-helper.py b/clang/test/Driver/DTLTO/Inputs/dtlto-helper.py
new file mode 100644
index 0000000..6eb9f68
--- /dev/null
+++ b/clang/test/Driver/DTLTO/Inputs/dtlto-helper.py
@@ -0,0 +1,11 @@
+from pathlib import Path
+import sys
+
+# Arg 1: "clang" path.
+p = Path(sys.argv[1])
+print(f"clang-name:{p.resolve().name}")
+# Arg 2: Non-zero for LLVM driver.
+if sys.argv[2] != "0":
+ print(f'prepend-arg:"--thinlto-remote-compiler-prepend-arg={p.name}"')
+else:
+ print("prepend-arg: ")
diff --git a/clang/test/Driver/DTLTO/dtlto.c b/clang/test/Driver/DTLTO/dtlto.c
index f31b635..5fbf788 100644
--- a/clang/test/Driver/DTLTO/dtlto.c
+++ b/clang/test/Driver/DTLTO/dtlto.c
@@ -3,16 +3,18 @@
/// Check DTLTO options are forwarded to the linker.
/// Check that options are forwarded as expected with --thinlto-distributor=.
-// RUN: %python %S/filename.py %clang > %t_forward.log
+// RUN: %python %S/Inputs/dtlto-helper.py %clang %llvm-driver > %t_forward.log
// RUN: %clang -flto=thin %s -### -fuse-ld=lld --target=x86_64-linux-gnu \
// RUN: -Xthinlto-distributor=a1 -Xthinlto-distributor=a2,a3 \
// RUN: -fthinlto-distributor=d.exe -Werror >>%t_forward.log 2>&1
// RUN: FileCheck %s --input-file=%t_forward.log --check-prefix=FORWARD
-// FORWARD: filename.py:[[CLANG:.*]]
-// FORWARD: ld.lld
+// FORWARD: clang-name:[[CLANG:.*]]
+// FORWARD-NEXT: prepend-arg:[[PREPEND_ARG:.*]]
+// FORWARD: ld.lld
// FORWARD-SAME: "--thinlto-distributor=d.exe"
// FORWARD-SAME: "--thinlto-remote-compiler={{[^"]*}}[[CLANG]]"
+// FORWARD-SAME: [[PREPEND_ARG]]
// FORWARD-SAME: "--thinlto-distributor-arg=a1"
// FORWARD-SAME: "--thinlto-distributor-arg=a2"
// FORWARD-SAME: "--thinlto-distributor-arg=a3"
@@ -30,24 +32,25 @@
/// Check the expected arguments are forwarded by default with only
/// --thinlto-distributor=.
-// RUN: %python %S/filename.py %clang > %t_default.log
+// RUN: %python %S/Inputs/dtlto-helper.py %clang %llvm-driver > %t_default.log
// RUN: %clang -flto=thin %s -### -fuse-ld=lld --target=x86_64-linux-gnu \
// RUN: -fthinlto-distributor=d.exe -Werror >>%t_default.log 2>&1
// RUN: FileCheck %s --input-file=%t_default.log --check-prefix=DEFAULT \
// RUN: --implicit-check-not=distributor --implicit-check-not=remote-compiler
-// DEFAULT: filename.py:[[CLANG:.*]]
-// DEFAULT: ld.lld
+// DEFAULT: clang-name:[[CLANG:.*]]
+// DEFAULT-NEXT: prepend-arg:[[PREPEND_ARG:.*]]
+// DEFAULT: ld.lld
// DEFAULT-SAME: "--thinlto-distributor=d.exe"
// DEFAULT-SAME: "--thinlto-remote-compiler={{[^"]*}}[[CLANG]]"
+// DEFAULT-SAME: [[PREPEND_ARG]]
/// Check that nothing is forwarded when the compiler is not in LTO mode, and that
/// appropriate unused option warnings are issued.
-// RUN: %python %S/filename.py %clang > %t_noflto.log
// RUN: %clang %s -### -fuse-ld=lld --target=x86_64-linux-gnu \
-// RUN: -fthinlto-distributor=d.exe >>%t_noflto.log 2>&1
-// RUN: FileCheck %s --input-file=%t_noflto.log --check-prefix=NOFLTO \
-// RUN: --implicit-check-not=distributor --implicit-check-not=remote-compiler
+// RUN: -fthinlto-distributor=d.exe 2>&1 | \
+// RUN: FileCheck %s --check-prefix=NOFLTO --implicit-check-not=distributor \
+// RUN: --implicit-check-not=remote-compiler
// NOFLTO: warning: argument unused during compilation: '-fthinlto-distributor=d.exe'
// NOFLTO: ld.lld
diff --git a/clang/test/Driver/DTLTO/filename.py b/clang/test/Driver/DTLTO/filename.py
deleted file mode 100644
index df1aeb6..0000000
--- a/clang/test/Driver/DTLTO/filename.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from pathlib import Path
-import sys
-
-print(f"filename.py:{Path(sys.argv[1]).resolve().name}")
diff --git a/clang/test/Driver/DTLTO/lit.local.cfg b/clang/test/Driver/DTLTO/lit.local.cfg
new file mode 100644
index 0000000..0756c5c
--- /dev/null
+++ b/clang/test/Driver/DTLTO/lit.local.cfg
@@ -0,0 +1,3 @@
+from lit.llvm import llvm_config
+
+config.substitutions.append(("%llvm-driver", "1" if "llvm-driver" in config.available_features else "0"))
diff --git a/clang/test/Driver/DTLTO/ps5-dtlto.c b/clang/test/Driver/DTLTO/ps5-dtlto.c
index 4c10a02..b59fb48 100644
--- a/clang/test/Driver/DTLTO/ps5-dtlto.c
+++ b/clang/test/Driver/DTLTO/ps5-dtlto.c
@@ -3,16 +3,18 @@
/// Check DTLTO options are forwarded to the linker.
/// Check that options are forwarded as expected with --thinlto-distributor=.
-// RUN: %python %S/filename.py %clang > %t_forward.log
+// RUN: %python %S/Inputs/dtlto-helper.py %clang %llvm-driver > %t_forward.log
// RUN: %clang -flto=thin %s -### --target=x86_64-sie-ps5 \
// RUN: -Xthinlto-distributor=a1 -Xthinlto-distributor=a2,a3 \
// RUN: -fthinlto-distributor=d.exe -Werror >>%t_forward.log 2>&1
// RUN: FileCheck %s --input-file=%t_forward.log --check-prefix=FORWARD
-// FORWARD: filename.py:[[CLANG:.*]]
-// FORWARD: prospero-lld
+// FORWARD: clang-name:[[CLANG:.*]]
+// FORWARD-NEXT: prepend-arg:[[PREPEND_ARG:.*]]
+// FORWARD: prospero-lld
// FORWARD-SAME: "--thinlto-distributor=d.exe"
// FORWARD-SAME: "--thinlto-remote-compiler={{[^"]*}}[[CLANG]]"
+// FORWARD-SAME: [[PREPEND_ARG]]
// FORWARD-SAME: "--thinlto-distributor-arg=a1"
// FORWARD-SAME: "--thinlto-distributor-arg=a2"
// FORWARD-SAME: "--thinlto-distributor-arg=a3"
@@ -30,20 +32,22 @@
/// Check the expected arguments are forwarded by default with only
/// --thinlto-distributor=.
-// RUN: %python %S/filename.py %clang > %t_default.log
+// RUN: %python %S/Inputs/dtlto-helper.py %clang %llvm-driver > %t_default.log
// RUN: %clang -flto=thin %s -### --target=x86_64-sie-ps5 \
// RUN: -fthinlto-distributor=d.exe -Werror >>%t_default.log 2>&1
// RUN: FileCheck %s --input-file=%t_default.log --check-prefix=DEFAULT \
// RUN: --implicit-check-not=distributor --implicit-check-not=remote-compiler
-// DEFAULT: filename.py:[[CLANG:.*]]
-// DEFAULT: prospero-lld
+// DEFAULT: clang-name:[[CLANG:.*]]
+// DEFAULT-NEXT: prepend-arg:[[PREPEND_ARG:.*]]
+// DEFAULT: prospero-lld
// DEFAULT-SAME: "--thinlto-distributor=d.exe"
// DEFAULT-SAME: "--thinlto-remote-compiler={{[^"]*}}[[CLANG]]"
+// DEFAULT-SAME: [[PREPEND_ARG]]
/// Check that the arguments are forwarded unconditionally even when the
/// compiler is not in LTO mode.
-// RUN: %python %S/filename.py %clang > %t_noflto.log
+// RUN: %python %S/Inputs/dtlto-helper.py %clang %llvm-driver > %t_noflto.log
// RUN: %clang %s -### --target=x86_64-sie-ps5 \
// RUN: -fthinlto-distributor=d.exe -Werror >>%t_noflto.log 2>&1
// RUN: FileCheck %s --input-file=%t_noflto.log --check-prefix=DEFAULT \
diff --git a/clang/test/Headers/floatneeds.c b/clang/test/Headers/floatneeds.c
new file mode 100644
index 0000000..e544b41
--- /dev/null
+++ b/clang/test/Headers/floatneeds.c
@@ -0,0 +1,41 @@
+// RUN: rm -fR %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %t/floatneeds0.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %t/floatneeds1.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %t/floatneeds0.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %t/floatneeds1.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %t/floatneeds0.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %t/floatneeds1.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %t/floatneeds0.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %t/floatneeds1.c
+
+// Use C99 to verify that __need_ can be used to get types that wouldn't normally be available.
+
+//--- floatneeds0.c
+float infinity0 = INFINITY; // c99-error{{undeclared identifier 'INFINITY'}} c23-error{{undeclared identifier 'INFINITY'}} \
+ c99-modules-error{{undeclared identifier 'INFINITY'}} c23-modules-error{{undeclared identifier 'INFINITY'}}
+float nan0 = NAN; // c99-error{{undeclared identifier 'NAN'}} c23-error{{undeclared identifier 'NAN'}} \
+ c99-modules-error{{undeclared identifier 'NAN'}} c23-modules-error{{undeclared identifier 'NAN'}}
+float max0 = FLT_MAX; // c99-error{{undeclared identifier 'FLT_MAX'}} c23-error{{undeclared identifier 'FLT_MAX'}} \
+ c99-modules-error{{undeclared identifier 'FLT_MAX'}} c23-modules-error{{undeclared identifier 'FLT_MAX'}}
+
+#define __need_infinity_nan
+#include <float.h>
+float infinity1 = INFINITY;
+float nan1 = NAN;
+float max1 = FLT_MAX; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \
+ c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}}
+
+#include <float.h>
+float infinity2 = INFINITY;
+float nan2 = NAN;
+float max2 = FLT_MAX;
+
+//--- floatneeds1.c
+// c23-no-diagnostics
+// c23-modules-no-diagnostics
+
+#include <float.h>
+float infinity0 = INFINITY; // c99-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}}
+float nan0 = NAN; // c99-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}}
+float max0 = FLT_MAX;
diff --git a/clang/test/Modules/explicit-build-cwd.c b/clang/test/Modules/explicit-build-cwd.c
new file mode 100644
index 0000000..af8b743
--- /dev/null
+++ b/clang/test/Modules/explicit-build-cwd.c
@@ -0,0 +1,17 @@
+// This test checks that explicitly building the same module from different
+// working directories results in the same PCM contents.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: mkdir %t/one
+// RUN: mkdir %t/two
+
+//--- module.modulemap
+module M { header "M.h" }
+
+//--- M.h
+
+// RUN: cd %t/one && %clang_cc1 -fmodules -emit-module %t/module.modulemap -fmodule-name=M -o %t/M_one.pcm
+// RUN: cd %t/two && %clang_cc1 -fmodules -emit-module %t/module.modulemap -fmodule-name=M -o %t/M_two.pcm
+
+// RUN: diff %t/M_one.pcm %t/M_two.pcm
diff --git a/clang/test/Modules/relative-resource-dir.m b/clang/test/Modules/relative-resource-dir.m
index 96f2d8e..1183184 100644
--- a/clang/test/Modules/relative-resource-dir.m
+++ b/clang/test/Modules/relative-resource-dir.m
@@ -8,5 +8,6 @@
// RUN: -fimplicit-module-maps -fmodules-cache-path=%t.mcp \
// RUN: -fbuiltin-headers-in-system-modules \
// RUN: -resource-dir resource-dir \
+// RUN: -internal-isystem resource-dir/include \
// RUN: -emit-module %S/Inputs/builtin-headers/module.modulemap \
// RUN: -fmodule-name=ModuleWithBuiltinHeader -o %t.pcm
diff --git a/clang/test/Preprocessor/cxx_oper_comma.cpp b/clang/test/Preprocessor/cxx_oper_comma.cpp
new file mode 100644
index 0000000..5db803a
--- /dev/null
+++ b/clang/test/Preprocessor/cxx_oper_comma.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++98
+// RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++11
+// RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++14
+// RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++17
+// RUN: %clang_cc1 -E -pedantic-errors %s -verify -std=c++20
+// RUN: %clang_cc1 -E -pedantic-errors %s -verify=expected,since-cxx23 -std=c++23 -Wno-c23-extensions
+// RUN: %clang_cc1 -E -pedantic-errors %s -verify=expected,since-cxx23 -std=c++2c -Wno-c23-extensions
+
+// Test 1: Top-level comma
+// expected-error@+1 {{expected end of line in preprocessor expression}}
+#if 1, 2
+#endif
+
+// Test 2: Comma in conditional expression(CWG3017)
+// Per CWG 3017, this exact case highlights the specification gap
+// where C++ lacks explicit prohibition of comma operators in #if
+// expected-error@+1 {{comma operator in operand of #if}}
+#if 1 ? 1, 0 : 3
+#endif
+
+// Test 3: Parenthesized comma
+// expected-error@+1 {{comma operator in operand of #if}}
+#if (1, 2)
+#endif
+
+// Test 4: Multiple commas
+// expected-error@+1 {{expected end of line in preprocessor expression}}
+#if 1, 2, 3
+#endif
+
+// Test 5: Comma in #elif
+#if 0
+#elif (1, 2) // expected-error {{comma operator in operand of #if}}
+#endif
+
+// Test 6: Leading comma (syntax error)
+// expected-error@+1 {{invalid token at start of a preprocessor expression}}
+#if ,
+#endif
+
+// Test 7: Comma in #embed limit parameter (C++23+)
+#if __cplusplus >= 202302L
+// since-cxx23-error@+1 {{expected ')'}}
+#embed "jk.txt" limit(1, 2)
+#endif
diff --git a/clang/test/SemaCXX/alloc-token.cpp b/clang/test/SemaCXX/alloc-token.cpp
new file mode 100644
index 0000000..be7acb7
--- /dev/null
+++ b/clang/test/SemaCXX/alloc-token.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -falloc-token-mode=typehash -DMODE_TYPEHASH
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -verify %s -falloc-token-max=2 -DTOKEN_MAX=2
+
+#if !__has_builtin(__builtin_infer_alloc_token)
+#error "missing __builtin_infer_alloc_token"
+#endif
+
+struct NoPtr {
+ int x;
+ long y;
+};
+
+struct WithPtr {
+ int a;
+ char *buf;
+};
+
+// Check specific known values; these are guaranteed to be stable.
+#ifdef MODE_TYPEHASH
+static_assert(__builtin_infer_alloc_token(sizeof(int)) == 2689373973731826898ULL);
+static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 2250492667400517147ULL);
+static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 7465259095297095368ULL);
+static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 11898882936532569145ULL);
+#elif defined(TOKEN_MAX)
+# if TOKEN_MAX == 2
+static_assert(__builtin_infer_alloc_token(sizeof(int)) == 0);
+static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 1);
+static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 0);
+static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 1);
+# else
+# error "unhandled TOKEN_MAX case"
+# endif
+#else
+static_assert(__builtin_infer_alloc_token(sizeof(int)) == 2689373973731826898ULL);
+static_assert(__builtin_infer_alloc_token(sizeof(char*)) == 11473864704255292954ULL);
+static_assert(__builtin_infer_alloc_token(sizeof(NoPtr)) == 7465259095297095368ULL);
+static_assert(__builtin_infer_alloc_token(sizeof(WithPtr)) == 11898882936532569145ULL);
+#endif
+
+// Template function.
+template <typename T>
+constexpr unsigned long get_token() {
+ return __builtin_infer_alloc_token(sizeof(T));
+}
+static_assert(__builtin_infer_alloc_token(sizeof(int)) == get_token<int>());
+
+// Test complex expressions.
+static_assert(__builtin_constant_p(__builtin_infer_alloc_token(sizeof(int))));
+static_assert(__builtin_infer_alloc_token(sizeof(NoPtr) * 2, 1) == get_token<NoPtr>());
+static_assert(__builtin_infer_alloc_token(1, 4 + sizeof(NoPtr)) == get_token<NoPtr>());
+static_assert(__builtin_infer_alloc_token(sizeof(NoPtr) << 8) == get_token<NoPtr>());
+
+// Test usable as a template param.
+template <unsigned long ID, typename T>
+struct token_for_type {
+ static_assert(ID == get_token<T>());
+ static constexpr unsigned long value = ID;
+};
+static_assert(token_for_type<__builtin_infer_alloc_token(sizeof(int)), int>::value == get_token<int>());
+
+template <typename T = void>
+void template_test() {
+ __builtin_infer_alloc_token(T()); // no error if not instantiated
+}
+
+template <typename T>
+void negative_template_test() {
+ __builtin_infer_alloc_token(T()); // expected-error {{argument may not have 'void' type}}
+}
+
+void negative_tests() {
+ __builtin_infer_alloc_token(); // expected-error {{too few arguments to function call}}
+ __builtin_infer_alloc_token((void)0); // expected-error {{argument may not have 'void' type}}
+ negative_template_test<void>(); // expected-note {{in instantiation of function template specialization 'negative_template_test<void>' requested here}}
+ constexpr auto inference_fail = __builtin_infer_alloc_token(123); // expected-error {{must be initialized by a constant expression}} \
+ // expected-note {{could not infer allocation type for __builtin_infer_alloc_token}}
+}
diff --git a/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl b/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl
index 393d730..bcc94f0 100644
--- a/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl
+++ b/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl
@@ -11,4 +11,9 @@ void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV
// CHECK-NEXT: HLSLSV_GroupIDAttr
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:96 GThreadID 'uint'
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr
+
+// CHECK: HLSLSV_GroupIndexAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'GI' 'int' 0
+// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'ID' 'uint':'unsigned int' 0
+// CHECK-NEXT: HLSLSV_GroupIDAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'GID' 'uint':'unsigned int' 0
+// CHECK-NEXT: HLSLSV_GroupThreadIDAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'GThreadID' 'uint':'unsigned int' 0
}
diff --git a/clang/test/SemaHLSL/Semantics/position.ps.hlsl b/clang/test/SemaHLSL/Semantics/position.ps.hlsl
index 32bc5f5..27a8e4a 100644
--- a/clang/test/SemaHLSL/Semantics/position.ps.hlsl
+++ b/clang/test/SemaHLSL/Semantics/position.ps.hlsl
@@ -1,7 +1,10 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-pixel -x hlsl -finclude-default-header -o - %s -ast-dump | FileCheck %s
-float4 main(float4 a : SV_Position) {
+// FIXME(Keenuts): add mandatory output semantic once those are implemented.
+float4 main(float4 a : SV_Position2) {
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:8 main 'float4 (float4)'
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:20 a 'float4':'vector<float, 4>'
// CHECK-NEXT: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}>
+
+// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> ParmVar 0x{{[0-9a-fA-F]+}} 'a' 'float4':'vector<float, 4>' 2 SemanticExplicitIndex
}
diff --git a/clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl b/clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl
new file mode 100644
index 0000000..9f57231
--- /dev/null
+++ b/clang/test/SemaHLSL/Semantics/position.ps.struct.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-pixel -x hlsl -finclude-default-header -o - %s -ast-dump | FileCheck %s
+
+struct S {
+ float4 f0 : SV_Position;
+// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:10 f0 'float4':'vector<float, 4>'
+// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <col:15> <<<NULL>>> 0
+ float4 f1 : SV_Position3;
+// CHECK: FieldDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:10 f1 'float4':'vector<float, 4>'
+// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <col:15> <<<NULL>>> 3 SemanticExplicitIndex
+};
+
+// FIXME(Keenuts): add mandatory output semantic once those are implemented.
+float4 main(S s) {
+// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:8 main 'float4 (S)'
+// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:15 s 'S'
+
+// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> Field 0x{{[0-9a-fA-F]+}} 'f0' 'float4':'vector<float, 4>' 0
+// CHECK: HLSLSV_PositionAttr 0x{{[0-9a-fA-F]+}} <{{.*}}> Field 0x{{[0-9a-fA-F]+}} 'f1' 'float4':'vector<float, 4>' 3 SemanticExplicitIndex
+}
diff --git a/clang/test/SemaHLSL/Semantics/struct_input.hlsl b/clang/test/SemaHLSL/Semantics/struct_input.hlsl
new file mode 100644
index 0000000..66cab95
--- /dev/null
+++ b/clang/test/SemaHLSL/Semantics/struct_input.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -o - %s -verify
+
+struct S {
+ float4 f0 : SV_Position;
+// expected-error@+2 {{semantic annotations must be present for all parameters of an entry function or patch constant function}}
+// expected-note@+1 {{'f1' used here}}
+ float4 f1;
+};
+
+[shader("pixel")]
+// expected-note@+1 {{'s' declared here}}
+void main(S s) {
+}
+
+[shader("pixel")]
+// expected-error@+2 {{semantic annotations must be present for all parameters of an entry function or patch constant function}}
+// expected-note@+1 {{'f' declared here}}
+void main2(float4 p : SV_POSITION, float4 f)
+{ }
diff --git a/clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp b/clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp
new file mode 100644
index 0000000..ded8f58
--- /dev/null
+++ b/clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64 -fopenmp -verify %s
+
+// FIXME: Is this supposed to work?
+
+#pragma omp begin declare variant match(implementation={extension(allow_templates)})
+template <class T> void f(T) {}
+// expected-note@-1 {{explicit instantiation refers here}}
+#pragma end
+template <int> struct A {};
+template <bool B> A<B> f() = delete;
+template void f<float>(float);
+// expected-error@-1 {{explicit instantiation of undefined function template 'f'}}
diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
index 4bb09d3..425beb9 100644
--- a/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/UncheckedStatusOrAccessModelTestFixture.cpp
@@ -2871,6 +2871,110 @@ TEST_P(UncheckedStatusOrAccessModelTest, EqualityCheck) {
)cc");
}
+TEST_P(UncheckedStatusOrAccessModelTest, PointerEqualityCheck) {
+ ExpectDiagnosticsFor(
+ R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT* x, STATUSOR_INT* y) {
+ if (x->ok()) {
+ if (x == y)
+ y->value();
+ else
+ y->value(); // [[unsafe]]
+ }
+ }
+ )cc");
+ ExpectDiagnosticsFor(
+ R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUSOR_INT* x, STATUSOR_INT* y) {
+ if (x->ok()) {
+ if (x != y)
+ y->value(); // [[unsafe]]
+ else
+ y->value();
+ }
+ }
+ )cc");
+ ExpectDiagnosticsFor(
+ R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUS* x, STATUS* y) {
+ auto sor = Make<STATUSOR_INT>();
+ if (x->ok()) {
+ if (x == y && sor.status() == *y)
+ sor.value();
+ else
+ sor.value(); // [[unsafe]]
+ }
+ }
+ )cc");
+ ExpectDiagnosticsFor(
+ R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(STATUS* x, STATUS* y) {
+ auto sor = Make<STATUSOR_INT>();
+ if (x->ok()) {
+ if (x != y)
+ sor.value(); // [[unsafe]]
+ else if (sor.status() == *y)
+ sor.value();
+ }
+ }
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, Emplace) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ struct Foo {
+ Foo(int);
+ };
+
+ void target(absl::StatusOr<Foo> sor, int value) {
+ sor.emplace(value);
+ sor.value();
+ }
+ )cc");
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ struct Foo {
+ Foo(std::initializer_list<int>, int);
+ };
+
+ void target(absl::StatusOr<Foo> sor, int value) {
+ sor.emplace({1, 2, 3}, value);
+ sor.value();
+ }
+ )cc");
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target() {
+ STATUSOR_INT sor;
+ bool sor_ok = sor.ok();
+ if (!sor_ok)
+ sor.emplace(42);
+ sor.value();
+ }
+ )cc");
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_access_test_defs.h"
+
+ void target(bool b) {
+ STATUSOR_INT sor;
+ if (b) sor.emplace(42);
+ if (b) sor.value();
+ }
+ )cc");
+}
+
} // namespace
std::string
diff --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp
index 700d7cf8..cf8143a 100644
--- a/clang/unittests/Format/FormatTestObjC.cpp
+++ b/clang/unittests/Format/FormatTestObjC.cpp
@@ -949,6 +949,12 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
"[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
" aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
" aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+ verifyFormat("[objectName\n"
+ " respondsToSelector:\n"
+ " @selector(\n"
+ " somelonglonglonglongnameeeeeeee:\n"
+ " loooooooooanotherlonglonglonglongnametopush:\n"
+ " otherlongnameforlimit:)];");
Style = getChromiumStyle(FormatStyle::LK_ObjC);
Style.ColumnLimit = 80;
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 1342e1a..183952a 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3078,6 +3078,17 @@ static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS,
OS << " {\n";
+ // The generator puts the arguments for each attribute in the child class,
+ // even if those are set in the inherited attribute class (in the TD
+ // file). This means I cannot access those from the parent class, and have
+ // to do this weirdness. Maybe the generator should be changed to
+ // arguments are put in the class they are declared in inside the TD file?
+ if (HLSLSemantic) {
+ OS << " if (SemanticExplicitIndex)\n";
+ OS << " setSemanticIndex(SemanticIndex);\n";
+ OS << " setTargetDecl(Target);\n";
+ }
+
for (auto const &ai : Args) {
if (!shouldEmitArg(ai))
continue;