[clang] [Clang] Separate implicit int conversion on negation sign to new diagnostic group (PR #139429)
https://github.com/cor3ntin edited https://github.com/llvm/llvm-project/pull/139429 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Separate implicit int conversion on negation sign to new diagnostic group (PR #139429)
@@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -verify -Wimplicit-int-conversion +// RUN: %clang_cc1 %s -verify -Wimplicit-int-conversion -Wno-implicit-int-conversion-on-negation -DNO_DIAG + +#ifdef NO_DIAG +unsigned char test_no_diag(unsigned char x) { +return -x; // expected-no-diagnostics +} +#else +unsigned char test_diag(unsigned char x) { +return -x; // expected-warning {{implicit conversion loses integer precision: 'int' to 'unsigned char' on negation}} +} +#endif cor3ntin wrote: ```suggestion // RUN: %clang_cc1 %s -verify=nowarn -Wimplicit-int-conversion // RUN: %clang_cc1 %s -verify -Wimplicit-int-conversion -Wno-implicit-int-conversion-on-negation -DNO_DIAG // nowarn-no-diagnostics unsigned char test_no_diag(unsigned char x) { return -x; // expected-warning {{implicit conversion loses integer precision: 'int' to 'unsigned char' on negation}} } ``` https://github.com/llvm/llvm-project/pull/139429 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Separate implicit int conversion on negation sign to new diagnostic group (PR #139429)
@@ -12091,6 +12091,11 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, if (SourceMgr.isInSystemMacro(CC)) return; +if (const auto *UO = dyn_cast(E)) { + return DiagnoseImpCast(*this, E, T, CC, + diag::warn_impcast_integer_precision_on_negation); +} + cor3ntin wrote: We should check which operator it is. Did you try to add tests with ``` unsigned char test_diag(unsigned char x) { return +x; }``` https://github.com/llvm/llvm-project/pull/139429 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [CLANGD] [NFC] Fix proposed by sanitizer. (PR #140116)
https://github.com/carlosgalvezp approved this pull request. LGTM. In the future, please provide more details about exactly which tool you are using, which you call "sanitizer". For example, what is the name of the tool? "sanitizers" are tools to detect issues at runtime; here you are using a static analyzer. https://github.com/llvm/llvm-project/pull/140116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Separate implicit int conversion on negation sign to new diagnostic group (PR #139429)
https://github.com/cor3ntin commented: The direction looks good. Can you add more tests, with different integer types? Thanks https://github.com/llvm/llvm-project/pull/139429 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix constexpr-unknown handling of self-references. (PR #132990)
https://github.com/cor3ntin approved this pull request. LGTM modulo nit https://github.com/llvm/llvm-project/pull/132990 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix constexpr-unknown handling of self-references. (PR #132990)
@@ -3629,17 +3644,17 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, Result = VD->getEvaluatedValue(); - // C++23 [expr.const]p8 - // ... For such an object that is not usable in constant expressions, the - // dynamic type of the object is constexpr-unknown. For such a reference that - // is not usable in constant expressions, the reference is treated as binding - // to an unspecified object of the referenced type whose lifetime and that of - // all subobjects includes the entire constant evaluation and whose dynamic - // type is constexpr-unknown. - if (AllowConstexprUnknown) { -if (!Result) + if (!Result) { +if (AllowConstexprUnknown) { Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD, Base); +} else { + return false; +} cor3ntin wrote: ping https://github.com/llvm/llvm-project/pull/132990 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix constexpr-unknown handling of self-references. (PR #132990)
https://github.com/cor3ntin edited https://github.com/llvm/llvm-project/pull/132990 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Sycl builtin kernel name (PR #140230)
https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/140230 None >From eeea84b4989b4497cc804f403258b986c09cf5ab Mon Sep 17 00:00:00 2001 From: Elizabeth Andrews Date: Thu, 8 Aug 2024 18:05:48 -0700 Subject: [PATCH 1/5] [SYCL] Add support for __builtin_sycl_kernel_name The builtin takes the kernel name type as it's argument and returns the mangled name for the kernel caller function. --- clang/include/clang/Basic/Builtins.h | 1 + clang/include/clang/Basic/Builtins.td | 7 +++ .../clang/Basic/DiagnosticSemaKinds.td| 3 + clang/lib/Basic/Builtins.cpp | 3 + clang/lib/CodeGen/CGBuiltin.cpp | 20 +++ clang/lib/Sema/SemaChecking.cpp | 33 ++ .../CodeGenSYCL/builtin-sycl-kernel-name.cpp | 60 +++ .../SemaSYCL/builtin-sycl-kernel-name.cpp | 44 ++ 8 files changed, 171 insertions(+) create mode 100644 clang/test/CodeGenSYCL/builtin-sycl-kernel-name.cpp create mode 100644 clang/test/SemaSYCL/builtin-sycl-kernel-name.cpp diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 3a5e31de2bc50..0bea100b7e6de 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -45,6 +45,7 @@ enum LanguageID : uint16_t { ALL_OCL_LANGUAGES = 0x800, // builtin for OCL languages. HLSL_LANG = 0x1000,// builtin requires HLSL. C23_LANG = 0x2000, // builtin requires C23 or later. + SYCL_LANG = 0x2000,// builtin requires SYCL. ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages. ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode. ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode. diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 11b1e247237a7..13e02898e55aa 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4794,6 +4794,13 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> { let Prototype = "char const*(...)"; } +// SYCL +def SYCLKernelName : LangBuiltin<"SYCL_LANG"> { + let Spellings = ["__builtin_sycl_kernel_name"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "char const*(...)"; +} + // HLSL def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_adduint64"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6e940a318b61d..d9f7487f2596e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12789,6 +12789,9 @@ def err_sycl_entry_point_deduced_return_type : Error< def warn_cuda_maxclusterrank_sm_90 : Warning< "maxclusterrank requires sm_90 or higher, CUDA arch provided: %0, ignoring " "%1 attribute">, InGroup; +def err_builtin_invalid_argument_count : Error<"builtin requires exactly 1 argument">; +def err_builtin_invalid_argument : Error<"invalid argument; argument must be a class or struct type" + " with a member type alias named 'type'">; // VTable pointer authentication errors def err_non_polymorphic_vtable_pointer_auth : Error< diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 885abdc152e3a..f8275656c5d0c 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -185,6 +185,9 @@ static bool builtinIsSupported(const llvm::StringTable &Strings, /* CUDA Unsupported */ if (!LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG) return false; + /* SYCL Unsupported */ + if (!LangOpts.isSYCL() && BuiltinInfo.Langs == SYCL_LANG) +return false; /* CPlusPlus Unsupported */ if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG) return false; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 4fdf2113cb9dc..b7638ed0b27f1 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -29,6 +29,7 @@ #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Basic/IdentifierTable.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" @@ -6219,6 +6220,25 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, auto Str = CGM.GetAddrOfConstantCString(Name, ""); return RValue::get(Str.getPointer()); } + case Builtin::BI__builtin_sycl_kernel_name: { +ASTContext &Ctx = getContext(); +// Argument to the builtin is a kernel_id_t type trait which is used +// to retrieve the kernel name type. +RecordDecl *RD = E->getArg(0)->getType()->castAs()->getDecl(); +IdentifierTable &IdentTable = Ctx.Idents; +auto Name = DeclarationName(&(IdentTab
[clang] [clang][NFC] Clean up Expr::isTemporaryObject() (PR #140229)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/140229 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Sycl builtin kernel name (PR #140230)
https://github.com/Fznamznon closed https://github.com/llvm/llvm-project/pull/140230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Sycl builtin kernel name (PR #140230)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- clang/test/CodeGenSYCL/builtin-sycl-kernel-name.cpp clang/test/SemaSYCL/builtin-sycl-kernel-name.cpp clang/test/SemaSYCL/builtin-sycl-kernel-param-count.cpp clang/include/clang/Basic/Builtins.h clang/lib/AST/ExprConstant.cpp clang/lib/Basic/Builtins.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/lib/CodeGen/CodeGenSYCL.cpp clang/lib/Sema/SemaChecking.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 555a488b0..975dee423 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -51,8 +51,8 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/DiagnosticSema.h" -#include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/APFixedPoint.h" #include "llvm/ADT/Sequence.h" diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 71a7b4155..e7836eb08 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -26,10 +26,10 @@ #include "TargetInfo.h" #include "clang/AST/OSLog.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "clang/Basic/IdentifierTable.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" @@ -2566,7 +2566,7 @@ EmitKernelNameGlobal(CodeGenModule &CGM, ASTContext &Ctx, const CallExpr *E) { SmallString<256> KernelNameSymbol; llvm::raw_svector_ostream Out(KernelNameSymbol); - //llvm::raw_string_ostream Out(KernelNameSymbol); + // llvm::raw_string_ostream Out(KernelNameSymbol); MC->mangleCanonicalTypeName(KernelNameType, Out); llvm::GlobalVariable *GV = new llvm::GlobalVariable( diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 0a1356a38..4b6b769a2 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2226,7 +2226,7 @@ static bool CheckBuiltinSyclKernelName(Sema &S, CallExpr *TheCall) { QualType ArgTy = TheCall->getArg(0)->getType(); const auto *RT = ArgTy->getAs(); - if(!RT) + if (!RT) return true; RecordDecl *RD = RT->getDecl(); `` https://github.com/llvm/llvm-project/pull/140230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] add -floop-interchange and enable it with opt levels (PR #140182)
@@ -421,7 +421,8 @@ static void CheckSubscripts( static void CheckSubscripts( semantics::SemanticsContext &context, CoarrayRef &ref) { - const Symbol &coarraySymbol{ref.GetBase().GetLastSymbol()}; + const auto &base = ref.GetBase(); + const Symbol &coarraySymbol{base.GetLastSymbol()}; kiranchandramohan wrote: Nit: Is this an unrelated change? https://github.com/llvm/llvm-project/pull/140182 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] add -floop-interchange and enable it with opt levels (PR #140182)
https://github.com/kiranchandramohan commented: Thanks for this PR. Do you have any compilation time and performance data? https://github.com/llvm/llvm-project/pull/140182 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Cygwin][MinGW] Internal class in explicitly-instantiation-declarated template should be instantiated (PR #140145)
https://github.com/kikairoya updated https://github.com/llvm/llvm-project/pull/140145 >From 827e89b8148e7eaa69bbae342cfb2a59d1b09133 Mon Sep 17 00:00:00 2001 From: kikairoya Date: Mon, 21 Apr 2025 23:30:13 +0900 Subject: [PATCH 1/2] [Cygwin][MinGW] Internal class in explicitly-instantiation-declarated template should be instantiated In-code comment says "explicit instantiation decl of the outer class doesn't affect the inner class" but this behavior seems MSVC specific, MinGW-GCC and Cygwin-GCC does not. Clang should honor gcc's behavior. This change fixes std::string compatibilty and resolves strange link error (statically linked), strange crash (dynamically linked) using libstdc++ on Cygwin. --- clang/lib/Sema/SemaTemplateInstantiate.cpp| 1 + .../CodeGenCXX/mingw-template-dllexport.cpp | 109 +++--- 2 files changed, 93 insertions(+), 17 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index d028eea4f8f3e..b7c27b3795f5d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -4247,6 +4247,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, continue; if (Context.getTargetInfo().getTriple().isOSWindows() && + !Context.getTargetInfo().getTriple().isOSCygMing() && TSK == TSK_ExplicitInstantiationDeclaration) { // On Windows, explicit instantiation decl of the outer class doesn't // affect the inner class. Typically extern template declarations are diff --git a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp index de112d6da53db..a6047b5955e96 100644 --- a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp +++ b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp @@ -6,46 +6,121 @@ #define JOIN2(x, y) x##y #define JOIN(x, y) JOIN2(x, y) #define UNIQ(name) JOIN(name, __LINE__) -#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; } +#define USEMEMFUNC(class, func) auto UNIQ(use) = &class::func; template class c { + // MinGW-GCC does not apply 'dllexport' to inline member function in dll-exported template but clang does from long ago. void f() {} + void g(); + inline static int u = 0; + static int v; }; +template void c::g() {} +template int c::v = 0; +// #1 template class __declspec(dllexport) c; -// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv - +// #2 extern template class __declspec(dllexport) c; template class c; -// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv - +// #3 extern template class c; -template class __declspec(dllexport) c; +template class __declspec(dllexport) c; // expected-warning {{ 'dllexport' attribute ignored on explicit instantiation definition }} -// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv template struct outer { - void f(); + void f() {} + void g(); + inline static int u = 0; + static int v; + // MinGW-GCC and Clang does not apply 'dllexport' to inner type and its sub-elements in template class. struct inner { -void f(); +void f() {} +void g(); +inline static int u = 0; +static int v; }; }; -template void outer::f() {} -template void outer::inner::f() {} +template void outer::g() {} +template void outer::inner::g() {} +template int outer::v = 0; +template int outer::inner::v = 0; -template class __declspec(dllexport) outer; +// #4 +template struct __declspec(dllexport) outer; -// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv -// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv - -extern template class __declspec(dllimport) outer; +// #5 +extern template struct __declspec(dllimport) outer; USEMEMFUNC(outer, f) +USEMEMFUNC(outer, g) +USEMEMFUNC(outer, u) +USEMEMFUNC(outer, v) USEMEMFUNC(outer::inner, f) +USEMEMFUNC(outer::inner, g) +USEMEMFUNC(outer::inner, u) +USEMEMFUNC(outer::inner, v) + + +// #1 variables +// CHECK: @_ZN1cIiE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN1cIiE1vE = {{.*}} dllexport {{.*}} + +// #2 variables +// CHECK: @_ZN1cIcE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN1cIcE1vE = {{.*}} dllexport {{.*}} + +// #3 variables +// CHECK: @_ZN1cIdE1uE = {{.*}} +// CHECK-NOT: @_ZN1cIcE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN1cIdE1vE = {{.*}} +// CHECK-NOT: @_ZN1cIcE1vE = {{.*}} dllexport {{.*}} + +// #4 variables +// CHECK: @_ZN5outerIiE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN5outerIiE1vE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN5outerIiE5inner1uE = {{.*}} +// CHECK-NOT: @_ZN5outerIiE5inner1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN5outerIiE5inner1vE = {{.*}} +// CHECK-NOT: @_ZN5outerIiE5inner1vE = {{.*}} dllexport {{.*}} + +// #5 variables +// CHECK: @_ZN5outerIcE1uE = external dllimport {{.*}} +// CHECK: @_ZN5outerIcE1vE = external dllimport {{.*}} +// CHECK-NOT: @_ZN5outerIcE5inner1uE = dllimport {{.*}} +// CHECK-N
[clang] [llvm] [clang][DebugInfo] Add symbol for debugger with VTable information. (PR #130255)
CarlosAlbertoEnciso wrote: > Got measurements on debug info size growth or any other metrics we should be > considering? I will prepare some measurements on debug info size. https://github.com/llvm/llvm-project/pull/130255 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] add -floop-interchange and enable it with opt levels (PR #140182)
https://github.com/kiranchandramohan edited https://github.com/llvm/llvm-project/pull/140182 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Add macro to suppress -Wunnecessary-virtual-specifier (PR #139614)
https://github.com/AaronBallman approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/139614 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Cygwin][MinGW] Internal class in explicitly-instantiation-declarated template should be instantiated (PR #140145)
https://github.com/kikairoya updated https://github.com/llvm/llvm-project/pull/140145 >From 827e89b8148e7eaa69bbae342cfb2a59d1b09133 Mon Sep 17 00:00:00 2001 From: kikairoya Date: Mon, 21 Apr 2025 23:30:13 +0900 Subject: [PATCH 1/3] [Cygwin][MinGW] Internal class in explicitly-instantiation-declarated template should be instantiated In-code comment says "explicit instantiation decl of the outer class doesn't affect the inner class" but this behavior seems MSVC specific, MinGW-GCC and Cygwin-GCC does not. Clang should honor gcc's behavior. This change fixes std::string compatibilty and resolves strange link error (statically linked), strange crash (dynamically linked) using libstdc++ on Cygwin. --- clang/lib/Sema/SemaTemplateInstantiate.cpp| 1 + .../CodeGenCXX/mingw-template-dllexport.cpp | 109 +++--- 2 files changed, 93 insertions(+), 17 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index d028eea4f8f3e..b7c27b3795f5d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -4247,6 +4247,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, continue; if (Context.getTargetInfo().getTriple().isOSWindows() && + !Context.getTargetInfo().getTriple().isOSCygMing() && TSK == TSK_ExplicitInstantiationDeclaration) { // On Windows, explicit instantiation decl of the outer class doesn't // affect the inner class. Typically extern template declarations are diff --git a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp index de112d6da53db..a6047b5955e96 100644 --- a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp +++ b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp @@ -6,46 +6,121 @@ #define JOIN2(x, y) x##y #define JOIN(x, y) JOIN2(x, y) #define UNIQ(name) JOIN(name, __LINE__) -#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; } +#define USEMEMFUNC(class, func) auto UNIQ(use) = &class::func; template class c { + // MinGW-GCC does not apply 'dllexport' to inline member function in dll-exported template but clang does from long ago. void f() {} + void g(); + inline static int u = 0; + static int v; }; +template void c::g() {} +template int c::v = 0; +// #1 template class __declspec(dllexport) c; -// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv - +// #2 extern template class __declspec(dllexport) c; template class c; -// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv - +// #3 extern template class c; -template class __declspec(dllexport) c; +template class __declspec(dllexport) c; // expected-warning {{ 'dllexport' attribute ignored on explicit instantiation definition }} -// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv template struct outer { - void f(); + void f() {} + void g(); + inline static int u = 0; + static int v; + // MinGW-GCC and Clang does not apply 'dllexport' to inner type and its sub-elements in template class. struct inner { -void f(); +void f() {} +void g(); +inline static int u = 0; +static int v; }; }; -template void outer::f() {} -template void outer::inner::f() {} +template void outer::g() {} +template void outer::inner::g() {} +template int outer::v = 0; +template int outer::inner::v = 0; -template class __declspec(dllexport) outer; +// #4 +template struct __declspec(dllexport) outer; -// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv -// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv - -extern template class __declspec(dllimport) outer; +// #5 +extern template struct __declspec(dllimport) outer; USEMEMFUNC(outer, f) +USEMEMFUNC(outer, g) +USEMEMFUNC(outer, u) +USEMEMFUNC(outer, v) USEMEMFUNC(outer::inner, f) +USEMEMFUNC(outer::inner, g) +USEMEMFUNC(outer::inner, u) +USEMEMFUNC(outer::inner, v) + + +// #1 variables +// CHECK: @_ZN1cIiE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN1cIiE1vE = {{.*}} dllexport {{.*}} + +// #2 variables +// CHECK: @_ZN1cIcE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN1cIcE1vE = {{.*}} dllexport {{.*}} + +// #3 variables +// CHECK: @_ZN1cIdE1uE = {{.*}} +// CHECK-NOT: @_ZN1cIcE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN1cIdE1vE = {{.*}} +// CHECK-NOT: @_ZN1cIcE1vE = {{.*}} dllexport {{.*}} + +// #4 variables +// CHECK: @_ZN5outerIiE1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN5outerIiE1vE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN5outerIiE5inner1uE = {{.*}} +// CHECK-NOT: @_ZN5outerIiE5inner1uE = {{.*}} dllexport {{.*}} +// CHECK: @_ZN5outerIiE5inner1vE = {{.*}} +// CHECK-NOT: @_ZN5outerIiE5inner1vE = {{.*}} dllexport {{.*}} + +// #5 variables +// CHECK: @_ZN5outerIcE1uE = external dllimport {{.*}} +// CHECK: @_ZN5outerIcE1vE = external dllimport {{.*}} +// CHECK-NOT: @_ZN5outerIcE5inner1uE = dllimport {{.*}} +// CHECK-N
[clang] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks (PR #139859)
Rajveer100 wrote: Moving the checks does work for these limited cases, but now that we don't have them there, one of the old tests now doesn't show up the diagnosis: ```c++ void f() { throw; } void g() { try { f(); } catch (...) { } } ``` Since there is a separate call: ```c++ return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers); ``` and debugging under lldb breakpoints don't reach (i.e exit) the transform calls. https://github.com/llvm/llvm-project/pull/139859 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix assertion failure in constexpr union deserialization (PR #140179)
https://github.com/alexfh updated https://github.com/llvm/llvm-project/pull/140179 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Separate implicit int conversion on negation sign to new diagnostic group (PR #139429)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions c,cpp -- clang/test/Sema/implicit-int-conversion-on-int.c clang/lib/Sema/SemaChecking.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 203c9ad28..d7435fe8c 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12310,8 +12310,8 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, if (const auto *UO = dyn_cast(E)) { if (UO->getOpcode() == UO_Minus) -return DiagnoseImpCast(*this, E, T, CC, - diag::warn_impcast_integer_precision_on_negation); +return DiagnoseImpCast( +*this, E, T, CC, diag::warn_impcast_integer_precision_on_negation); } if (TargetRange.Width == 32 && Context.getIntWidth(E->getType()) == 64) `` https://github.com/llvm/llvm-project/pull/139429 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Separate implicit int conversion on negation sign to new diagnostic group (PR #139429)
https://github.com/YutongZhuu updated https://github.com/llvm/llvm-project/pull/139429 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang] Adopt simplified `getTrailingObjects` in Expr.cpp/h (PR #140102)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Rahul Joshi (jurahul) Changes Adopt non-templated and array-ref returning forms of `getTrailingObjects` in Expr.cpp/.h. Use ArrayRef forms to eliminate manual asserting for OOB index. Use llvm::copy() instead of std::copy() in some instances. --- Full diff: https://github.com/llvm/llvm-project/pull/140102.diff 3 Files Affected: - (modified) clang/include/clang/AST/Expr.h (+36-63) - (modified) clang/lib/AST/Expr.cpp (+29-35) - (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+2-2) ``diff diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 1e6749dda71fe..e9c3c16c87598 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2023,7 +2023,7 @@ class PredefinedExpr final void setFunctionName(StringLiteral *SL) { assert(hasFunctionName() && "This PredefinedExpr has no storage for a function name!"); -*getTrailingObjects() = SL; +*getTrailingObjects() = SL; } public: @@ -2050,13 +2050,13 @@ class PredefinedExpr final StringLiteral *getFunctionName() { return hasFunctionName() - ? static_cast(*getTrailingObjects()) + ? static_cast(*getTrailingObjects()) : nullptr; } const StringLiteral *getFunctionName() const { return hasFunctionName() - ? static_cast(*getTrailingObjects()) + ? static_cast(*getTrailingObjects()) : nullptr; } @@ -2078,13 +2078,11 @@ class PredefinedExpr final // Iterators child_range children() { -return child_range(getTrailingObjects(), - getTrailingObjects() + hasFunctionName()); +return child_range(getTrailingObjects(hasFunctionName())); } const_child_range children() const { -return const_child_range(getTrailingObjects(), - getTrailingObjects() + hasFunctionName()); +return const_child_range(getTrailingObjects(hasFunctionName())); } }; @@ -2248,18 +2246,14 @@ class UnaryOperator final private llvm::TrailingObjects { Stmt *Val; - size_t numTrailingObjects(OverloadToken) const { -return UnaryOperatorBits.HasFPFeatures ? 1 : 0; - } - FPOptionsOverride &getTrailingFPFeatures() { assert(UnaryOperatorBits.HasFPFeatures); -return *getTrailingObjects(); +return *getTrailingObjects(); } const FPOptionsOverride &getTrailingFPFeatures() const { assert(UnaryOperatorBits.HasFPFeatures); -return *getTrailingObjects(); +return *getTrailingObjects(); } public: @@ -2580,13 +2574,11 @@ class OffsetOfExpr final } const OffsetOfNode &getComponent(unsigned Idx) const { -assert(Idx < NumComps && "Subscript out of range"); -return getTrailingObjects()[Idx]; +return getTrailingObjects(NumComps)[Idx]; } void setComponent(unsigned Idx, OffsetOfNode ON) { -assert(Idx < NumComps && "Subscript out of range"); -getTrailingObjects()[Idx] = ON; +getTrailingObjects(NumComps)[Idx] = ON; } unsigned getNumComponents() const { @@ -2594,18 +2586,15 @@ class OffsetOfExpr final } Expr* getIndexExpr(unsigned Idx) { -assert(Idx < NumExprs && "Subscript out of range"); -return getTrailingObjects()[Idx]; +return getTrailingObjects(NumExprs)[Idx]; } const Expr *getIndexExpr(unsigned Idx) const { -assert(Idx < NumExprs && "Subscript out of range"); -return getTrailingObjects()[Idx]; +return getTrailingObjects(NumExprs)[Idx]; } void setIndexExpr(unsigned Idx, Expr* E) { -assert(Idx < NumComps && "Subscript out of range"); -getTrailingObjects()[Idx] = E; +getTrailingObjects(NumComps)[Idx] = E; } unsigned getNumExpressions() const { @@ -4619,12 +4608,12 @@ class ConvertVectorExpr final FPOptionsOverride &getTrailingFPFeatures() { assert(ConvertVectorExprBits.HasFPFeatures); -return *getTrailingObjects(); +return *getTrailingObjects(); } const FPOptionsOverride &getTrailingFPFeatures() const { assert(ConvertVectorExprBits.HasFPFeatures); -return *getTrailingObjects(); +return *getTrailingObjects(); } public: @@ -5705,13 +5694,11 @@ class DesignatedInitExpr final unsigned getNumSubExprs() const { return NumSubExprs; } Expr *getSubExpr(unsigned Idx) const { -assert(Idx < NumSubExprs && "Subscript out of range"); -return cast(getTrailingObjects()[Idx]); +return cast(getTrailingObjects(NumSubExprs)[Idx]); } void setSubExpr(unsigned Idx, Expr *E) { -assert(Idx < NumSubExprs && "Subscript out of range"); -getTrailingObjects()[Idx] = E; +getTrailingObjects(NumSubExprs)[Idx] = E; } /// Replaces the designator at index @p Idx with the series @@ -5730,11 +5717,11 @@ class DesignatedInitExpr final // Iterators child_range children() { -Stmt **begin = getTrailingObjects(); +Stmt **begin = getTrailing
[clang] [NFC][Clang] Adopt simplified `getTrailingObjects` in Expr.cpp/h (PR #140102)
https://github.com/jurahul ready_for_review https://github.com/llvm/llvm-project/pull/140102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [WIP][analyzer] Refactor `ExplodedGraph::trim()` (PR #139939)
NagyDonat wrote: I started a measurement on open source projects to see the effect of this change on the (total) analysis runtime. I don't expect much but if this turns out to be non-negligible, then I will prioritize this direction. https://github.com/llvm/llvm-project/pull/139939 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] dd32ad1 - [Clang][Lex][NFC] Assert getExternalSource() in updateOutOfDateIdentifier (#140137)
Author: Shafik Yaghmour Date: 2025-05-16T06:26:56-07:00 New Revision: dd32ad1c3787c51e72d496c03ab7948c98f93e06 URL: https://github.com/llvm/llvm-project/commit/dd32ad1c3787c51e72d496c03ab7948c98f93e06 DIFF: https://github.com/llvm/llvm-project/commit/dd32ad1c3787c51e72d496c03ab7948c98f93e06.diff LOG: [Clang][Lex][NFC] Assert getExternalSource() in updateOutOfDateIdentifier (#140137) Static analysis flagged the unconditional access of getExternalSource(). We don't initialize ExternalSource during construction but via setExternalSource(). If this is not set it will violate the invariant covered by the assert. Added: Modified: clang/lib/Lex/Preprocessor.cpp Removed: diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 9ea7b95622c76..4c2dbbe881b48 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -759,6 +759,8 @@ void Preprocessor::HandlePoisonedIdentifier(Token & Identifier) { void Preprocessor::updateOutOfDateIdentifier(const IdentifierInfo &II) const { assert(II.isOutOfDate() && "not out of date"); + assert(getExternalSource() && + "getExternalSource() should not return nullptr"); getExternalSource()->updateOutOfDateIdentifier(II); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [openmp] [OpenMP 6.0 ]Codegen for Reduction over private variables with reduction clause (PR #134709)
@@ -4898,6 +4898,274 @@ void CGOpenMPRuntime::emitSingleReductionCombiner(CodeGenFunction &CGF, } } +void CGOpenMPRuntime::emitPrivateReduction( +CodeGenFunction &CGF, SourceLocation Loc, const Expr *Privates, +const Expr *LHSExprs, const Expr *RHSExprs, const Expr *ReductionOps) { + + // Create a shared global variable (__shared_reduction_var) to accumulate the + // final result. + // + // Call __kmpc_barrier to synchronize threads before initialization. + // + // The master thread (thread_id == 0) initializes __shared_reduction_var + //with the identity value or initializer. + // + // Call __kmpc_barrier to synchronize before combining. + // For each i: + //- Thread enters critical section. + //- Reads its private value from LHSExprs[i]. + //- Updates __shared_reduction_var[i] = RedOp_i(__shared_reduction_var[i], + //LHSExprs[i]). + //- Exits critical section. + // + // Call __kmpc_barrier after combining. + // + // Each thread copies __shared_reduction_var[i] back to LHSExprs[i]. + // + // Final __kmpc_barrier to synchronize after broadcasting + QualType PrivateType = Privates->getType(); + llvm::Type *LLVMType = CGF.ConvertTypeForMem(PrivateType); + + llvm::Constant *InitVal = nullptr; + const OMPDeclareReductionDecl *UDR = getReductionInit(ReductionOps); + // Determine the initial value for the shared reduction variable + if (!UDR) { +InitVal = llvm::Constant::getNullValue(LLVMType); +if (const auto *DRE = dyn_cast(Privates)) { + if (const auto *VD = dyn_cast(DRE->getDecl())) { +const Expr *InitExpr = VD->getInit(); +if (InitExpr) { + Expr::EvalResult Result; + if (InitExpr->EvaluateAsRValue(Result, CGF.getContext())) { +APValue &InitValue = Result.Val; +if (InitValue.isInt()) + InitVal = llvm::ConstantInt::get(LLVMType, InitValue.getInt()); +else if (InitValue.isFloat()) + InitVal = llvm::ConstantFP::get(LLVMType, InitValue.getFloat()); +else if (InitValue.isComplexInt()) { + // For complex int: create struct { real, imag } + llvm::Constant *Real = llvm::ConstantInt::get( + cast(LLVMType)->getElementType(0), + InitValue.getComplexIntReal()); + llvm::Constant *Imag = llvm::ConstantInt::get( + cast(LLVMType)->getElementType(1), + InitValue.getComplexIntImag()); + InitVal = llvm::ConstantStruct::get( + cast(LLVMType), {Real, Imag}); +} else if (InitValue.isComplexFloat()) { + llvm::Constant *Real = llvm::ConstantFP::get( + cast(LLVMType)->getElementType(0), + InitValue.getComplexFloatReal()); + llvm::Constant *Imag = llvm::ConstantFP::get( + cast(LLVMType)->getElementType(1), + InitValue.getComplexFloatImag()); + InitVal = llvm::ConstantStruct::get( + cast(LLVMType), {Real, Imag}); +} + } +} + } +} + } else { +InitVal = llvm::Constant::getNullValue(LLVMType); + } + std::string ReductionVarNameStr; + if (const auto *DRE = dyn_cast(Privates->IgnoreParenCasts())) +ReductionVarNameStr = DRE->getDecl()->getNameAsString(); + else +ReductionVarNameStr = "unnamed_priv_var"; + + // Create an internal shared variable + std::string SharedName = + CGM.getOpenMPRuntime().getName({"internal_pivate_", ReductionVarNameStr}); + llvm::GlobalVariable *SharedVar = new llvm::GlobalVariable( + CGM.getModule(), LLVMType, false, llvm::GlobalValue::InternalLinkage, + InitVal, ".omp.reduction." + SharedName, nullptr, + llvm::GlobalVariable::NotThreadLocal); + + SharedVar->setAlignment( + llvm::MaybeAlign(CGF.getContext().getTypeAlign(PrivateType) / 8)); + + Address SharedResult(SharedVar, SharedVar->getValueType(), + CGF.getContext().getTypeAlignInChars(PrivateType)); + + llvm::Value *ThreadId = getThreadID(CGF, Loc); + llvm::Value *BarrierLoc = emitUpdateLocation(CGF, Loc, OMP_ATOMIC_REDUCE); + llvm::Value *BarrierArgs[] = {BarrierLoc, ThreadId}; + + llvm::BasicBlock *InitBB = CGF.createBasicBlock("init"); + llvm::BasicBlock *InitEndBB = CGF.createBasicBlock("init.end"); + + llvm::Value *IsWorker = CGF.Builder.CreateICmpEQ( + ThreadId, llvm::ConstantInt::get(ThreadId->getType(), 0)); + CGF.Builder.CreateCondBr(IsWorker, InitBB, InitEndBB); + + CGF.EmitBlock(InitBB); + + auto EmitSharedInit = [&]() { +if (UDR) { // Check if it's a User-Defined Reduction + if (const Expr *UDRInitExpr = UDR->getInitializer()) { +std::pair FnPair = +getUserDefinedReduction(UDR); +llvm::Function *InitializerFn = FnPair.second; +if (InitializerFn) { + if (const auto *CE = + dyn_cas
[clang] [OpenCL] No need to check array of struct for kernel arguments (PR #138894)
https://github.com/jiefwo updated https://github.com/llvm/llvm-project/pull/138894 >From 78e6da1b9f49e23afe77878b81a0aafde8108976 Mon Sep 17 00:00:00 2001 From: Jiefeng Wang Date: Wed, 7 May 2025 23:02:03 +0800 Subject: [PATCH] [OpenCL] No need to check array of struct for kernel arguments Since arrays decay into pointers, no need to check them for arguments. This commit reverts part of the changes from the commit "[OpenCL] Check for invalid kernel arguments in array types" 3b238ed6626983beb238b95eada4172184fb2d29. --- clang/lib/Sema/SemaDecl.cpp | 16 ++-- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6b561d7bfc6e7..364fb064ccc2d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9717,14 +9717,10 @@ static void checkIsValidOpenCLKernelParameter( SmallVector HistoryStack; HistoryStack.push_back(nullptr); - // At this point we already handled everything except of a RecordType or - // an ArrayType of a RecordType. - assert((PT->isArrayType() || PT->isRecordType()) && "Unexpected type."); - const RecordType *RecTy = - PT->getPointeeOrArrayElementType()->getAs(); - const RecordDecl *OrigRecDecl = RecTy->getDecl(); - - VisitStack.push_back(RecTy->getDecl()); + // At this point we already handled everything except of a RecordType. + assert(PT->isRecordType() && "Unexpected type."); + const RecordDecl *PD = PT->castAs()->getDecl(); + VisitStack.push_back(PD); assert(VisitStack.back() && "First decl null?"); do { @@ -9789,8 +9785,8 @@ static void checkIsValidOpenCLKernelParameter( S.Diag(Param->getLocation(), diag::err_bad_kernel_param_type) << PT; } - S.Diag(OrigRecDecl->getLocation(), diag::note_within_field_of_type) - << OrigRecDecl->getDeclName(); + S.Diag(PD->getLocation(), diag::note_within_field_of_type) + << PD->getDeclName(); // We have an error, now let's go back up through history and show where // the offending field came from ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [openmp] [OpenMP 6.0 ]Codegen for Reduction over private variables with reduction clause (PR #134709)
@@ -4898,6 +4898,274 @@ void CGOpenMPRuntime::emitSingleReductionCombiner(CodeGenFunction &CGF, } } +void CGOpenMPRuntime::emitPrivateReduction( +CodeGenFunction &CGF, SourceLocation Loc, const Expr *Privates, +const Expr *LHSExprs, const Expr *RHSExprs, const Expr *ReductionOps) { + + // Create a shared global variable (__shared_reduction_var) to accumulate the + // final result. + // + // Call __kmpc_barrier to synchronize threads before initialization. + // + // The master thread (thread_id == 0) initializes __shared_reduction_var + //with the identity value or initializer. + // + // Call __kmpc_barrier to synchronize before combining. + // For each i: + //- Thread enters critical section. + //- Reads its private value from LHSExprs[i]. + //- Updates __shared_reduction_var[i] = RedOp_i(__shared_reduction_var[i], + //LHSExprs[i]). + //- Exits critical section. + // + // Call __kmpc_barrier after combining. + // + // Each thread copies __shared_reduction_var[i] back to LHSExprs[i]. + // + // Final __kmpc_barrier to synchronize after broadcasting + QualType PrivateType = Privates->getType(); + llvm::Type *LLVMType = CGF.ConvertTypeForMem(PrivateType); + + llvm::Constant *InitVal = nullptr; + const OMPDeclareReductionDecl *UDR = getReductionInit(ReductionOps); + // Determine the initial value for the shared reduction variable + if (!UDR) { +InitVal = llvm::Constant::getNullValue(LLVMType); +if (const auto *DRE = dyn_cast(Privates)) { + if (const auto *VD = dyn_cast(DRE->getDecl())) { +const Expr *InitExpr = VD->getInit(); +if (InitExpr) { + Expr::EvalResult Result; + if (InitExpr->EvaluateAsRValue(Result, CGF.getContext())) { alexey-bataev wrote: Not sure this is correct. What if the init value is not a constant? You need to emit the initial value and then assign it. https://github.com/llvm/llvm-project/pull/134709 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -758,6 +758,10 @@ AMDGPU Support ^^ - Bump the default code object version to 6. ROCm 6.3 is required to run any program compiled with COV6. +- Introduced a new target specific builtin ``__builtin_amdgcn_processor_is``, + a late / deferred query for the current target processor +- Introduced a new target specific builtin ``__builtin_amdgcn_is_invocable``, + which enables fine-grained, per-builtin, feature availability erichkeane wrote: ```suggestion which enables fine-grained, per-builtin, feature availability. ``` https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -6653,6 +6654,22 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, if (Result.isInvalid()) return ExprError(); Fn = Result.get(); + // The __builtin_amdgcn_is_invocable builtin is special, and will be resolved + // later, when we check boolean conditions, for now we merely forward it + // without any additional checking. + if (Fn->getType() == Context.BuiltinFnTy && ArgExprs.size() == 1 && + ArgExprs[0]->getType() == Context.BuiltinFnTy) { +auto *FD = cast(Fn->getReferencedDeclOfCallee()); + +if (FD->getName() == "__builtin_amdgcn_is_invocable") { + auto FnPtrTy = Context.getPointerType(FD->getType()); erichkeane wrote: More 'auto' use. https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -758,6 +758,10 @@ AMDGPU Support ^^ - Bump the default code object version to 6. ROCm 6.3 is required to run any program compiled with COV6. +- Introduced a new target specific builtin ``__builtin_amdgcn_processor_is``, + a late / deferred query for the current target processor erichkeane wrote: ```suggestion a late / deferred query for the current target processor. ``` https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -366,4 +367,72 @@ void SemaAMDGPU::handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, addAMDGPUMaxNumWorkGroupsAttr(D, AL, AL.getArgAsExpr(0), YExpr, ZExpr); } +Expr *SemaAMDGPU::ExpandAMDGPUPredicateBI(CallExpr *CE) { + auto &Ctx = getASTContext(); erichkeane wrote: None of these are supposed to be 'auto' unless the type itself is on the RHS. Goes for most of this function. https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -64,6 +68,11 @@ class SemaAMDGPU : public SemaBase { void handleAMDGPUNumVGPRAttr(Decl *D, const ParsedAttr &AL); void handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, const ParsedAttr &AL); void handleAMDGPUFlatWorkGroupSizeAttr(Decl *D, const ParsedAttr &AL); + + /// Expand a valid use of the feature identification builtins into its + /// corresponding sequence of instructions. + Expr *ExpandAMDGPUPredicateBI(CallExpr *CE); erichkeane wrote: ```suggestion Expr *ExpandAMDGPUPredicateBuiltIn(CallExpr *CE); ``` https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -13338,4 +13338,23 @@ def err_acc_device_type_multiple_archs // AMDGCN builtins diagnostics def err_amdgcn_load_lds_size_invalid_value : Error<"invalid size value">; def note_amdgcn_load_lds_size_valid_value : Note<"size must be %select{1, 2, or 4|1, 2, 4, 12 or 16}0">; +def err_amdgcn_processor_is_arg_not_literal +: Error<"the argument to __builtin_amdgcn_processor_is must be a string " +"literal">; +def err_amdgcn_processor_is_arg_invalid_value +: Error<"the argument to __builtin_amdgcn_processor_is must be a valid " +"AMDGCN processor identifier; '%0' is not valid">; erichkeane wrote: Is there value/etc to printing the list like we do with -`march`? https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
https://github.com/erichkeane commented: First, please take a look at the LLVM coding standard re the use of 'auto'. Second: The use of a special type for these builtins is a little novel (though I see the predicate type already exists?), but I guess I'm ok with it. I have some concerns with how the conversions for it work, particularly being represented always as an `i1`, but the tests you have look about right. I would like to see a test that is effectively: ``` bool f() { return __builtin_amdgcn_processor_is(...); } ``` (and maybe one returning 'auto' to make sure it is deduced properly). https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -581,6 +581,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case BuiltinType::Id: \ return llvm::TargetExtType::get(getLLVMContext(), "amdgcn.named.barrier", \ {}, {Scope}); +#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \ + case BuiltinType::Id: \ +return llvm::IntegerType::getInt1Ty(getLLVMContext()); erichkeane wrote: Why an int-1 type instead of 'bool' type? Won't this cause problems if it is returned? Are we making sure we force casts correctly, else this is going to be a bug factory when emitting it. https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] add -floop-interchange and enable it with opt levels (PR #140182)
sebpop wrote: > Do you have any compilation time and performance data? @madhur13490 did several changes to loop interchange to optimize the overall compilation time with the pass. I believe Madhur has only looked at c/c++ benchmarks and not at how loop interchange would impact flang. I think that if compilation time is good for c/c++, it should also be good for fortran. On the perf side, I was looking if we can already catch swim from cpu2000, and that fails with not enough data to infer number of iterations. I will be working on adding assume (N < 1335) based on analyzing array decls and infer loop bounds. https://github.com/llvm/llvm-project/pull/140182 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks (PR #139859)
erichkeane wrote: > Moving the checks does work for these limited cases, but now that we don't > have them there, one of the old tests now doesn't show up the diagnosis: > > ```c++ > void f() { > throw; > } > > void g() { > try { > f(); > } catch (...) { > } > } > ``` > > Since there is a separate call: > > ```c++ > return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers); > ``` > > and debugging under lldb, breakpoints don't reach (i.e exit early) the > transform calls. Right, 'transform' only happens during template instantiation. So we need to find 'some place' (that is a seperate function) to do these diagnostics. I might suggest doing a new one, since there doesn't seem to be a sensible place to do so otherwise... perhaps something like: ``` void Sema::DiagnoseExceptionUse(bool isTry) { // do the checking + diagnostic here, but have it check the decl-context for dependence } ``` NOTE I had that return `void` instead of `bool`. (And is `Diagnose` instead of `Check`). I wonder if there is value to continuing (@AaronBallman??) and putting these in the AST anyway? The continued checking is perhaps valuable, and tooling might appreciate it in the AST anyway. https://github.com/llvm/llvm-project/pull/139859 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Lex][NFC] Assert getExternalSource() in updateOutOfDateIdentifier (PR #140137)
https://github.com/shafik closed https://github.com/llvm/llvm-project/pull/140137 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Add support for Windows Secure Hot-Patching (PR #138972)
@@ -0,0 +1,283 @@ +//===-- WindowsHotPatch.cpp - Support for Windows hotpatching -===// +// +// 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 +// +//===--===// +// +// Provides support for the Windows "Secure Hot-Patching" feature. +// +// Windows contains technology, called "Secure Hot-Patching" (SHP), for securely +// applying hot-patches to a running system. Hot-patches may be applied to the +// kernel, kernel-mode components, device drivers, user-mode system services, +// etc. +// +// SHP relies on integration between many tools, including compiler, linker, +// hot-patch generation tools, and the Windows kernel. This file implements that +// part of the workflow needed in compilers / code generators. +// +// SHP is not intended for productivity scenarios such as Edit-and-Continue or +// interactive development. SHP is intended to minimize downtime during +// installation of Windows OS patches. +// +// In order to work with SHP, LLVM must do all of the following: +// +// * On some architectures (X86, AMD64), the function prolog must begin with +// hot-patchable instructions. This is handled by the MSVC `/hotpatch` option +// and the equivalent `-fms-hotpatch` function. This is necessary because we +// generally cannot anticipate which functions will need to be patched in the +// future. This option ensures that a function can be hot-patched in the +// future, but does not actually generate any hot-patch for it. +// +// * For a selected set of functions that are being hot-patched (which are +// identified using command-line options), LLVM must generate the +// `S_HOTPATCHFUNC` CodeView record (symbol). This record indicates that a +// function was compiled with hot-patching enabled. +// +// This implementation uses the `MarkedForWindowsHotPatching` attribute to +// annotate those functions that were marked for hot-patching by command-line +// parameters. The attribute may be specified by a language front-end by +// setting an attribute when a function is created in LLVM IR, or it may be +// set by passing LLVM arguments. +// +// * For those functions that are hot-patched, LLVM must rewrite references to +// global variables so that they are indirected through a `__ref_*` pointer +// variable. For each global variable, that is accessed by a hot-patched +// function, e.g. `FOO`, a `__ref_FOO` global pointer variable is created and +// all references to the original `FOO` are rewritten as dereferences of the +// `__ref_FOO` pointer. +// +// Some globals do not need `__ref_*` indirection. The pointer indirection +// behavior can be disabled for these globals by marking them with the +// `AllowDirectAccessInHotPatchFunction`. +// +// References +// +// * "Hotpatching on Windows": +// https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541 +// +// * "Hotpatch for Windows client now available": +// https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808 +// +// * "Get hotpatching for Windows Server": +// https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/ +// +//===--===// + +#include "llvm/ADT/SmallSet.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/DIBuilder.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/LineIterator.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace llvm; + +#define DEBUG_TYPE "windows-secure-hot-patch" + +// A file containing list of mangled function names to mark for hot patching. +static cl::opt LLVMMSSecureHotPatchFunctionsFile( +"ms-secure-hotpatch-functions-file", cl::value_desc("filename"), +cl::desc("A file containing list of mangled function names to mark for " + "Windows Secure Hot-Patching")); + +// A list of mangled function names to mark for hot patching. +static cl::list LLVMMSSecureHotPatchFunctionsList( +"ms-secure-hotpatch-functions-list", cl::value_desc("list"), +cl::desc("A list of mangled function names to mark for Windows Secure " + "Hot-Patching"), +cl::CommaSeparated); + +namespace { + +class WindowsSecureHotPatching : public ModulePass { + struct GlobalVariableUse { +GlobalVariable *GV; +Instruction *User; +unsigned Op; + }; + +public: + static char ID; + + WindowsSecureHotPatching() : ModuleP
[clang] [Serialization] Fix lazy template loading (PR #133057)
zygoloid wrote: Conversion function templates might be a special case here because of how conversion function template specializations are found by deduction as part of class member name lookup. Maybe we're doing something different in that deduction in particular that means we're not properly lazily loading them? If this issue is indeed specific to conversion function templates, perhaps a path forward would be to disable some part of the lazy loading for only those templates to unblock this patch while the reason for the problem is being investigated? https://github.com/llvm/llvm-project/pull/133057 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [WIP][AMDGPU] Support for type inferring image load/store builtins for AMDGPU (PR #140210)
@@ -683,6 +683,30 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, return Builder.CreateInsertElement(I0, A, 1); } + case AMDGPU::BI__builtin_amdgcn_image_load_2d_f32_i32: { +llvm::Type *RetTy = llvm::Type::getFloatTy(Builder.getContext()); +llvm::Type *IntTy = llvm::IntegerType::get(Builder.getContext(), 32u); + +llvm::Value *imm0 = llvm::ConstantInt::get(IntTy, 1); +llvm::Value *arg0 = EmitScalarExpr(E->getArg(0)); +llvm::Value *arg1 = EmitScalarExpr(E->getArg(1)); +llvm::Value *arg2 = EmitScalarExpr(E->getArg(2)); +llvm::Value *imm1 = llvm::ConstantInt::get(IntTy, 0); +llvm::Value *imm2 = llvm::ConstantInt::get(IntTy, 0); shiltian wrote: variable names don't conform with LLVM coding standards https://github.com/llvm/llvm-project/pull/140210 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Add support for Windows Secure Hot-Patching (PR #138972)
@@ -0,0 +1,283 @@ +//===-- WindowsHotPatch.cpp - Support for Windows hotpatching -===// +// +// 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 +// +//===--===// +// +// Provides support for the Windows "Secure Hot-Patching" feature. +// +// Windows contains technology, called "Secure Hot-Patching" (SHP), for securely +// applying hot-patches to a running system. Hot-patches may be applied to the +// kernel, kernel-mode components, device drivers, user-mode system services, +// etc. +// +// SHP relies on integration between many tools, including compiler, linker, +// hot-patch generation tools, and the Windows kernel. This file implements that +// part of the workflow needed in compilers / code generators. +// +// SHP is not intended for productivity scenarios such as Edit-and-Continue or +// interactive development. SHP is intended to minimize downtime during +// installation of Windows OS patches. +// +// In order to work with SHP, LLVM must do all of the following: +// +// * On some architectures (X86, AMD64), the function prolog must begin with +// hot-patchable instructions. This is handled by the MSVC `/hotpatch` option +// and the equivalent `-fms-hotpatch` function. This is necessary because we +// generally cannot anticipate which functions will need to be patched in the +// future. This option ensures that a function can be hot-patched in the +// future, but does not actually generate any hot-patch for it. +// +// * For a selected set of functions that are being hot-patched (which are +// identified using command-line options), LLVM must generate the +// `S_HOTPATCHFUNC` CodeView record (symbol). This record indicates that a +// function was compiled with hot-patching enabled. +// +// This implementation uses the `MarkedForWindowsHotPatching` attribute to +// annotate those functions that were marked for hot-patching by command-line +// parameters. The attribute may be specified by a language front-end by +// setting an attribute when a function is created in LLVM IR, or it may be +// set by passing LLVM arguments. +// +// * For those functions that are hot-patched, LLVM must rewrite references to +// global variables so that they are indirected through a `__ref_*` pointer +// variable. For each global variable, that is accessed by a hot-patched +// function, e.g. `FOO`, a `__ref_FOO` global pointer variable is created and +// all references to the original `FOO` are rewritten as dereferences of the +// `__ref_FOO` pointer. +// +// Some globals do not need `__ref_*` indirection. The pointer indirection +// behavior can be disabled for these globals by marking them with the +// `AllowDirectAccessInHotPatchFunction`. +// +// References +// +// * "Hotpatching on Windows": +// https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541 +// +// * "Hotpatch for Windows client now available": +// https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808 +// +// * "Get hotpatching for Windows Server": +// https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/ +// +//===--===// + +#include "llvm/ADT/SmallSet.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/DIBuilder.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/LineIterator.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace llvm; + +#define DEBUG_TYPE "windows-secure-hot-patch" + +// A file containing list of mangled function names to mark for hot patching. +static cl::opt LLVMMSSecureHotPatchFunctionsFile( +"ms-secure-hotpatch-functions-file", cl::value_desc("filename"), +cl::desc("A file containing list of mangled function names to mark for " + "Windows Secure Hot-Patching")); + +// A list of mangled function names to mark for hot patching. +static cl::list LLVMMSSecureHotPatchFunctionsList( +"ms-secure-hotpatch-functions-list", cl::value_desc("list"), +cl::desc("A list of mangled function names to mark for Windows Secure " + "Hot-Patching"), +cl::CommaSeparated); + +namespace { + +class WindowsSecureHotPatching : public ModulePass { + struct GlobalVariableUse { +GlobalVariable *GV; +Instruction *User; +unsigned Op; + }; + +public: + static char ID; + + WindowsSecureHotPatching() : ModuleP
[clang] [PAuth] Use different discriminators for __int128_t / __uint128_t / _BitInt(n) (PR #140276)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Anton Korobeynikov (asl) Changes compared to other integer types when computing function pointer type discriminator. These parameter types have different parameter passing ABI as compared to ordinary integer types (e.g. require 2 registers instead of 1) and therefore this parameter passing difference could potentially be exploited should function pointer is substituted. --- Full diff: https://github.com/llvm/llvm-project/pull/140276.diff 2 Files Affected: - (modified) clang/lib/AST/ASTContext.cpp (+10-4) - (modified) clang/test/CodeGen/ptrauth-function-type-discriminator.c (+31) ``diff diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c58cd2c93fb60..bbaaff6bcda4e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3383,21 +3383,27 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, // Don't bother discriminating based on these types. case Type::Pipe: - case Type::BitInt: case Type::ConstantMatrix: OS << "?"; return; + case Type::BitInt: { +const auto *BtTy = T->castAs(); +OS << "D" << (BtTy->isUnsigned() ? "U" : "B") << BtTy->getNumBits() << "_"; +return; + } + case Type::Builtin: { const auto *BTy = T->castAs(); -switch (BTy->getKind()) { +const auto Kind = BTy->getKind(); +switch (Kind) { #define SIGNED_TYPE(Id, SingletonId) \ case BuiltinType::Id: \ -OS << "i"; \ +OS << (Kind == BuiltinType::Int128 ? "n" : "i"); \ return; #define UNSIGNED_TYPE(Id, SingletonId) \ case BuiltinType::Id: \ -OS << "i"; \ +OS << (Kind == BuiltinType::UInt128 ? "o" : "i"); \ return; #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: #define BUILTIN_TYPE(Id, SingletonId) diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c b/clang/test/CodeGen/ptrauth-function-type-discriminator.c index 0952c1abf6c07..9bf4a8874c3c3 100644 --- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c +++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c @@ -65,6 +65,37 @@ void (*fptr3)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 26) // CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4) void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, __builtin_ptrauth_blend_discriminator(&fptr4, 26)); +extern void external_function_int(int); +extern void external_function_char(char); +extern void external_function_i128(__int128_t); +extern void external_function_u128(__uint128_t); +extern void external_function_b128(_BitInt(128)); +extern void external_function_b8(_BitInt(8)); + +// Check discriminators of functions taking integer type arguments: + +// - Builtin integer types should be discriminated equally (so, pointer to +// function taking int argument should accept function taking char argument +// - _BitInt types are guaranteed distinct and therefore should be discriminated +// differently +// - __int128_t / __uint128_t are passed differently than char / int / long +// (require two registers instead of one) and therefore should be discriminated +// differently. + +// CHECK: @fptr5 = global ptr ptrauth (ptr @external_function_int, i32 0, i64 2712) +// CHECK: @fptr6 = global ptr ptrauth (ptr @external_function_char, i32 0, i64 2712) +void (*fptr5)(int) = external_function_int; +void (*fptr6)(char) = external_function_char; + +// CHECK: @fptr7 = global ptr ptrauth (ptr @external_function_i128, i32 0, i64 23141) +// CHECK: @fptr8 = global ptr ptrauth (ptr @external_function_u128, i32 0, i64 45743) +// CHECK: @fptr9 = global ptr ptrauth (ptr @external_function_b128, i32 0, i64 17854) +// CHECK: @fptr10 = global ptr ptrauth (ptr @external_function_b8, i32 0, i64 26383) +void (*fptr7)(__int128_t) = external_function_i128; +void (*fptr8)(__uint128_t) = external_function_u128; +void (*fptr9)(_BitInt(128)) = external_function_b128; +void (*fptr10)(_BitInt(8)) = external_function_b8; + // CHECK-LABEL: define{{.*}} void @test_call() void test_call() { // CHECK: [[T0:%.*]] = load ptr, ptr @fnptr, `` https://github.com/llvm/llvm-project/pull/140276 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for FlattenCFG switch and SwitchFlatOp (PR #139154)
https://github.com/andykaylor approved this pull request. lgtm https://github.com/llvm/llvm-project/pull/139154 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AArch64] Move initialization of ptrauth-* function attrs (PR #140277)
https://github.com/atrosinenko created https://github.com/llvm/llvm-project/pull/140277 Move the initialization of ptrauth-* function attributes near the initialization of branch protection attributes. The semantics of these groups of attributes partially overlaps, so initialize them both in getTrivialDefaultFunctionAttributes() function to prevent getting them out of sync. This fixes C++ TLS wrappers. >From 71d852614cecab901709977b4a5f134145c2ac62 Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko Date: Fri, 16 May 2025 16:32:42 +0300 Subject: [PATCH] [clang][AArch64] Move initialization of ptrauth-* function attrs Move the initialization of ptrauth-* function attributes near the initialization of branch protection attributes. The semantics of these groups of attributes partially overlaps, so initialize them both in getTrivialDefaultFunctionAttributes() function to prevent getting them out of sync. This fixes C++ TLS wrappers. --- clang/lib/CodeGen/CGCall.cpp | 2 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 13 - clang/lib/CodeGen/TargetInfo.cpp | 14 ++ clang/lib/CodeGen/TargetInfo.h| 4 clang/test/CodeGenCXX/arm64-generated-fn-attr.cpp | 13 ++--- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index bcd579454413e..8064c935de216 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2100,6 +2100,8 @@ static void getTrivialDefaultFunctionAttributes( TargetInfo::BranchProtectionInfo BPI(LangOpts); TargetCodeGenInfo::initBranchProtectionFnAttributes(BPI, FuncAttrs); + TargetCodeGenInfo::initPointerAuthFnAttributes(CodeGenOpts.PointerAuth, + FuncAttrs); } /// Merges `target-features` from \TargetOpts and \F, and sets the result in diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index ac40aab97820d..4e79cdf0ef089 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -890,19 +890,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) SanOpts.Mask &= ~SanitizerKind::Null; - // Add pointer authentication attributes. - const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts(); - if (CodeGenOpts.PointerAuth.ReturnAddresses) -Fn->addFnAttr("ptrauth-returns"); - if (CodeGenOpts.PointerAuth.FunctionPointers) -Fn->addFnAttr("ptrauth-calls"); - if (CodeGenOpts.PointerAuth.AuthTraps) -Fn->addFnAttr("ptrauth-auth-traps"); - if (CodeGenOpts.PointerAuth.IndirectGotos) -Fn->addFnAttr("ptrauth-indirect-gotos"); - if (CodeGenOpts.PointerAuth.AArch64JumpTableHardening) -Fn->addFnAttr("aarch64-jump-table-hardening"); - // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; if (const auto *XRayAttr = D ? D->getAttr() : nullptr) { diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 75a7d3c7c73f0..564413228e34a 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -258,6 +258,20 @@ void TargetCodeGenInfo::initBranchProtectionFnAttributes( FuncAttrs.addAttribute("guarded-control-stack"); } +void TargetCodeGenInfo::initPointerAuthFnAttributes( +const PointerAuthOptions &Opts, llvm::AttrBuilder &FuncAttrs) { + if (Opts.ReturnAddresses) +FuncAttrs.addAttribute("ptrauth-returns"); + if (Opts.FunctionPointers) +FuncAttrs.addAttribute("ptrauth-calls"); + if (Opts.AuthTraps) +FuncAttrs.addAttribute("ptrauth-auth-traps"); + if (Opts.IndirectGotos) +FuncAttrs.addAttribute("ptrauth-indirect-gotos"); + if (Opts.AArch64JumpTableHardening) +FuncAttrs.addAttribute("aarch64-jump-table-hardening"); +} + namespace { class DefaultTargetCodeGenInfo : public TargetCodeGenInfo { public: diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index dd5dc0c32bd71..7415747c4ffd7 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -455,6 +455,10 @@ class TargetCodeGenInfo { initBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs); + // Add the ptrauth-* Attributes to the FuncAttrs. + static void initPointerAuthFnAttributes(const PointerAuthOptions &Opts, + llvm::AttrBuilder &FuncAttrs); + protected: static std::string qualifyWindowsLibrary(StringRef Lib); diff --git a/clang/test/CodeGenCXX/arm64-generated-fn-attr.cpp b/clang/test/CodeGenCXX/arm64-generated-fn-attr.cpp index 18d9da40d469b..630b5edbbc1d7 100644 --- a/clang/test/CodeGenCXX/arm64-generated-fn-attr.cpp +++ b/clang/test/CodeGenCXX/arm64-generated-fn-attr.cpp @@ -1
[clang] [clang] Fixed Constant Evaluation don't Call Destructor (PR #140278)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Vincent (Mr-Anyone) Changes Within the condition statement of the for block, the destructor doesn't get when evaluating compile time constants. resolves #139818 --- Full diff: https://github.com/llvm/llvm-project/pull/140278.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/lib/AST/ExprConstant.cpp (+5-1) - (modified) clang/test/SemaCXX/static-assert-cxx26.cpp (+35) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0c12091a90add..76c139632b31c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -623,6 +623,7 @@ Bug Fixes in This Version - Fix crash due to unknown references and pointer implementation and handling of base classes. (GH139452) - Fixed an assertion failure in serialization of constexpr structs containing unions. (#GH140130) +- Fix constant evaluation in for loop not calling destructor (#GH139818) Bug Fixes to Compiler Builtins ^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index ca1fbdf7e652f..d8364977258a1 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5742,8 +5742,12 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, if (FS->getCond() && !EvaluateCond(Info, FS->getConditionVariable(), FS->getCond(), Continue)) return ESR_Failed; - if (!Continue) + + if (!Continue) { +if (!IterScope.destroy()) + return ESR_Failed; break; + } EvalStmtResult ESR = EvaluateLoopBody(Result, Info, FS->getBody()); if (ESR != ESR_Continue) { diff --git a/clang/test/SemaCXX/static-assert-cxx26.cpp b/clang/test/SemaCXX/static-assert-cxx26.cpp index b53c67ee67932..7a47f2784ceb3 100644 --- a/clang/test/SemaCXX/static-assert-cxx26.cpp +++ b/clang/test/SemaCXX/static-assert-cxx26.cpp @@ -416,3 +416,38 @@ static_assert( // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} ); } + +// taken from: https://github.com/llvm/llvm-project/issues/139818 +namespace GH139818{ +struct A { + constexpr ~A() { ref = false; } + constexpr operator bool() { +return b; + } + bool b; + bool& ref; +}; + +constexpr bool f1() { + bool ret = true; + for (bool b = false; A x{b, ret}; b = true) {} + return ret; +} + +static_assert(!f1()); + +struct Y { + constexpr ~Y() noexcept(false) { throw "oops"; } // expected-error {{cannot use 'throw' with exceptions disabled}} +// expected-note@-1 {{subexpression not valid in a constant expression}} + constexpr operator bool() { +return b; + } + bool b; +}; +constexpr bool f2() { + for (bool b = false; Y x = {b}; b = true) {} // expected-note {{in call to 'x.~Y()'}} + return true; +} +static_assert(f2()); // expected-error {{static assertion expression is not an integral constant expression}} + // expected-note@-1 {{in call to 'f2()'}} +}; `` https://github.com/llvm/llvm-project/pull/140278 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for FlattenCFG switch and SwitchFlatOp (PR #139154)
https://github.com/andykaylor closed https://github.com/llvm/llvm-project/pull/139154 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ec44c74 - [CIR] Upstream support for FlattenCFG switch and SwitchFlatOp (#139154)
Author: Andres-Salamanca Date: 2025-05-16T09:38:56-07:00 New Revision: ec44c74fe7444c521c82e1ebef0d6a4e7be33252 URL: https://github.com/llvm/llvm-project/commit/ec44c74fe7444c521c82e1ebef0d6a4e7be33252 DIFF: https://github.com/llvm/llvm-project/commit/ec44c74fe7444c521c82e1ebef0d6a4e7be33252.diff LOG: [CIR] Upstream support for FlattenCFG switch and SwitchFlatOp (#139154) This PR adds support for the `FlattenCFG` transformation on `switch` statements. It also introduces the `SwitchFlatOp`, which is necessary for subsequent lowering to LLVM. Added: clang/test/CIR/CodeGen/switch_flat_op.cpp clang/test/CIR/IR/switch-flat.cir clang/test/CIR/Transforms/switch.cir Modified: clang/include/clang/CIR/Dialect/IR/CIROps.td clang/lib/CIR/Dialect/IR/CIRDialect.cpp clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp clang/lib/CIR/Dialect/Transforms/FlattenCFG.cpp Removed: diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index e08f372450285..71b9a816669bc 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -971,6 +971,52 @@ def SwitchOp : CIR_Op<"switch", }]; } +//===--===// +// SwitchFlatOp +//===--===// + +def SwitchFlatOp : CIR_Op<"switch.flat", [AttrSizedOperandSegments, + Terminator]> { + + let description = [{ +The `cir.switch.flat` operation is a region-less and simplified +version of the `cir.switch`. +Its representation is closer to LLVM IR dialect +than the C/C++ language feature. + }]; + + let arguments = (ins +CIR_IntType:$condition, +Variadic:$defaultOperands, +VariadicOfVariadic:$caseOperands, +ArrayAttr:$caseValues, +DenseI32ArrayAttr:$case_operand_segments + ); + + let successors = (successor +AnySuccessor:$defaultDestination, +VariadicSuccessor:$caseDestinations + ); + + let assemblyFormat = [{ +$condition `:` type($condition) `,` +$defaultDestination (`(` $defaultOperands^ `:` type($defaultOperands) `)`)? +custom(ref(type($condition)), $caseValues, + $caseDestinations, $caseOperands, + type($caseOperands)) +attr-dict + }]; + + let builders = [ +OpBuilder<(ins "mlir::Value":$condition, + "mlir::Block *":$defaultDestination, + "mlir::ValueRange":$defaultOperands, + CArg<"llvm::ArrayRef", "{}">:$caseValues, + CArg<"mlir::BlockRange", "{}">:$caseDestinations, + CArg<"llvm::ArrayRef", "{}">:$caseOperands)> + ]; +} + //===--===// // BrOp //===--===// diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 779114e09d834..9c80c48fa4039 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -22,6 +22,7 @@ #include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc" #include "clang/CIR/Dialect/IR/CIROpsEnums.cpp.inc" #include "clang/CIR/MissingFeatures.h" +#include using namespace mlir; using namespace cir; @@ -962,6 +963,101 @@ bool cir::SwitchOp::isSimpleForm(llvm::SmallVectorImpl &cases) { }); } +//===--===// +// SwitchFlatOp +//===--===// + +void cir::SwitchFlatOp::build(OpBuilder &builder, OperationState &result, + Value value, Block *defaultDestination, + ValueRange defaultOperands, + ArrayRef caseValues, + BlockRange caseDestinations, + ArrayRef caseOperands) { + + std::vector caseValuesAttrs; + for (const APInt &val : caseValues) +caseValuesAttrs.push_back(cir::IntAttr::get(value.getType(), val)); + mlir::ArrayAttr attrs = ArrayAttr::get(builder.getContext(), caseValuesAttrs); + + build(builder, result, value, defaultOperands, caseOperands, attrs, +defaultDestination, caseDestinations); +} + +/// ::= `[` (case (`,` case )* )? `]` +/// ::= integer `:` bb-id (`(` ssa-use-and-type-list `)`)? +static ParseResult parseSwitchFlatOpCases( +OpAsmParser &parser, Type flagType, mlir::ArrayAttr &caseValues, +SmallVectorImpl &caseDestinations, +SmallVectorImpl> +&caseOperands, +SmallVectorImpl> &caseOperandTypes) { + if (failed(parser.parseLSquare())) +return failure(); + if (succeeded(parser.parseOptionalRSquare())) +return success(); + llvm::SmallVector values; + + auto
[clang] [PAuth] Use different discriminators for __int128_t / __uint128_t / _BitInt(n) (PR #140276)
https://github.com/asl created https://github.com/llvm/llvm-project/pull/140276 compared to other integer types when computing function pointer type discriminator. These parameter types have different parameter passing ABI as compared to ordinary integer types (e.g. require 2 registers instead of 1) and therefore this parameter passing difference could potentially be exploited should function pointer is substituted. >From 26e6ea21540d03c6aee6281059cd3b8e3e4b3ee7 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Fri, 16 May 2025 19:25:57 +0300 Subject: [PATCH] [PAuth] Use different discriminators for __int128_t / __uint128_t / _BitInt(n) compared to other integer types when computing function pointer type discriminator. These parameter types have different parameter passing ABI as compared to ordinary integer types (e.g. require 2 registers instead of 1) and therefore this parameter passing difference could potentially be exploited should function pointer is substituted. --- clang/lib/AST/ASTContext.cpp | 14 ++--- .../ptrauth-function-type-discriminator.c | 31 +++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c58cd2c93fb60..bbaaff6bcda4e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3383,21 +3383,27 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, // Don't bother discriminating based on these types. case Type::Pipe: - case Type::BitInt: case Type::ConstantMatrix: OS << "?"; return; + case Type::BitInt: { +const auto *BtTy = T->castAs(); +OS << "D" << (BtTy->isUnsigned() ? "U" : "B") << BtTy->getNumBits() << "_"; +return; + } + case Type::Builtin: { const auto *BTy = T->castAs(); -switch (BTy->getKind()) { +const auto Kind = BTy->getKind(); +switch (Kind) { #define SIGNED_TYPE(Id, SingletonId) \ case BuiltinType::Id: \ -OS << "i"; \ +OS << (Kind == BuiltinType::Int128 ? "n" : "i"); \ return; #define UNSIGNED_TYPE(Id, SingletonId) \ case BuiltinType::Id: \ -OS << "i"; \ +OS << (Kind == BuiltinType::UInt128 ? "o" : "i"); \ return; #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: #define BUILTIN_TYPE(Id, SingletonId) diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c b/clang/test/CodeGen/ptrauth-function-type-discriminator.c index 0952c1abf6c07..9bf4a8874c3c3 100644 --- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c +++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c @@ -65,6 +65,37 @@ void (*fptr3)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 26) // CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4) void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, __builtin_ptrauth_blend_discriminator(&fptr4, 26)); +extern void external_function_int(int); +extern void external_function_char(char); +extern void external_function_i128(__int128_t); +extern void external_function_u128(__uint128_t); +extern void external_function_b128(_BitInt(128)); +extern void external_function_b8(_BitInt(8)); + +// Check discriminators of functions taking integer type arguments: + +// - Builtin integer types should be discriminated equally (so, pointer to +// function taking int argument should accept function taking char argument +// - _BitInt types are guaranteed distinct and therefore should be discriminated +// differently +// - __int128_t / __uint128_t are passed differently than char / int / long +// (require two registers instead of one) and therefore should be discriminated +// differently. + +// CHECK: @fptr5 = global ptr ptrauth (ptr @external_function_int, i32 0, i64 2712) +// CHECK: @fptr6 = global ptr ptrauth (ptr @external_function_char, i32 0, i64 2712) +void (*fptr5)(int) = external_function_int; +void (*fptr6)(char) = external_function_char; + +// CHECK: @fptr7 = global ptr ptrauth (ptr @external_function_i128, i32 0, i64 23141) +// CHECK: @fptr8 = global ptr ptrauth (ptr @external_function_u128, i32 0, i64 45743) +// CHECK: @fptr9 = global ptr ptrauth (ptr @external_function_b128, i32 0, i64 17854) +// CHECK: @fptr10 = global ptr ptrauth (ptr @external_function_b8, i32 0, i64 26383) +void (*fptr7)(__int128_t) = external_function_i128; +void (*fptr8)(__uint128_t) = external_function_u128; +void (*fptr9)(_BitInt(128)) = external_function_b128; +void (*fptr10)(_BitInt(8)) = external_function_b8; + // CHECK-
[clang] [llvm] [NFCI][Sanitizer] Convert SpecialCaseList::Sections from StringMap to vector. (PR #140127)
https://github.com/qinkunbao updated https://github.com/llvm/llvm-project/pull/140127 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fixed Constant Evaluation don't Call Destructor (PR #140278)
https://github.com/Mr-Anyone created https://github.com/llvm/llvm-project/pull/140278 Within the condition statement of the for block, the destructor doesn't get when evaluating compile time constants. resolves #139818 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add new warning: not eliding copy on return (missed NRVO) (PR #139973)
grigorypas wrote: @mizvekov Could you please merge if it is good to go? I don't have write access. https://github.com/llvm/llvm-project/pull/139973 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFCI][cfi] Refactor into 'SanitizerInfoFromCFICheckKind' (PR #140117)
vitalybuka wrote: LGTM https://github.com/llvm/llvm-project/pull/140117 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [cfi] Enable -fsanitize-annotate-debug-info functionality for CFI checks (PR #139809)
https://github.com/vitalybuka approved this pull request. https://github.com/llvm/llvm-project/pull/139809 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CGRecordLayout] Remove dependency on isZeroSize (PR #96422)
rnk wrote: Sorry to hear about the issue. I think the way this is supposed to work is that the clang frontend target ABIInfo is supposed to carefully construct struct types that cause the backend to pass the C struct type correctly in registers and memory. See for example clang/lib/CodeGen/Targets/X86.cpp [classifyReturnType](https://github.com/llvm/llvm-project/blob/7674d6fa9e45c1748d0dd49430aa472028d44a2d/clang/lib/CodeGen/Targets/X86.cpp#L470), which has pretty extensive logic. The AMDGPU one ultimately passes the LLVM struct type directly: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/Targets/AMDGPU.cpp#L175 The AArch64.cpp backend insulates itself from the LLVM IR struct types that the frontend generates by creating arrays for HVAs: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/Targets/AArch64.cpp#L453 It seems like AMDGPU should be doing something similar. https://github.com/llvm/llvm-project/pull/96422 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SPIRV] Add PreLegalizer pattern matching for `faceforward` (PR #139959)
@@ -98,21 +110,98 @@ void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR = MI.getMF()->getSubtarget().getSPIRVGlobalRegistry(); - auto RemoveAllUses = [&](Register Reg) { -SmallVector UsesToErase( -llvm::make_pointer_range(MRI.use_instructions(Reg))); - -// calling eraseFromParent to early invalidates the iterator. -for (auto *MIToErase : UsesToErase) { - GR->invalidateMachineInstr(MIToErase); - MIToErase->eraseFromParent(); -} - }; - RemoveAllUses(SubDestReg); // remove all uses of FSUB Result + removeAllUses(SubDestReg, MRI, GR); // remove all uses of FSUB Result GR->invalidateMachineInstr(SubInstr); SubInstr->eraseFromParent(); // remove FSUB instruction } +/// This match is part of a combine that +/// rewrites select(fcmp(dot(I, Ng), 0), N, 0 - N) to faceforward(N, I, Ng) +/// (vXf32 (g_select +/// (g_fcmp +///(g_intrinsic dot(vXf32 I) (vXf32 Ng) +/// 0) +/// (vXf32 N) +/// (vXf32 g_fsub (0) (vXf32 N +/// -> +/// (vXf32 (g_intrinsic faceforward +/// (vXf32 N) (vXf32 I) (vXf32 Ng))) +/// +bool matchSelectToFaceForward(MachineInstr &MI, MachineRegisterInfo &MRI) { + if (MI.getOpcode() != TargetOpcode::G_SELECT) +return false; + + // Check if select's condition is a comparison between a dot product and 0. + Register CondReg = MI.getOperand(1).getReg(); + MachineInstr *CondInstr = MRI.getVRegDef(CondReg); + if (!CondInstr || CondInstr->getOpcode() != TargetOpcode::G_FCMP) +return false; + + Register DotReg = CondInstr->getOperand(2).getReg(); + MachineInstr *DotInstr = MRI.getVRegDef(DotReg); + if (DotInstr->getOpcode() != TargetOpcode::G_FMUL && + (DotInstr->getOpcode() != TargetOpcode::G_INTRINSIC || + cast(DotInstr)->getIntrinsicID() != Intrinsic::spv_fdot)) +return false; + + Register CondZeroReg = CondInstr->getOperand(3).getReg(); + MachineInstr *CondZeroInstr = MRI.getVRegDef(CondZeroReg); + if (CondZeroInstr->getOpcode() != TargetOpcode::G_FCONSTANT || + !CondZeroInstr->getOperand(1).getFPImm()->isZero()) +return false; + + // Check if select's false operand is the negation of the true operand. + Register TrueReg = MI.getOperand(2).getReg(); + Register FalseReg = MI.getOperand(3).getReg(); + MachineInstr *FalseInstr = MRI.getVRegDef(FalseReg); + if (FalseInstr->getOpcode() != TargetOpcode::G_FNEG) +return false; + if (TrueReg != FalseInstr->getOperand(1).getReg()) +return false; kmpeng wrote: Yeah, I was also wondering if this way of checking would be a problem since there's multiple ways to represent 2 operands being negations (another example being `G_FSUB`). I'm also still learning and have not been able to come up with a generic way to check this. @farzonl Do you have any thoughts? https://github.com/llvm/llvm-project/pull/139959 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DirectX][SPIRV] Fix the lowering of dot4add (PR #140315)
https://github.com/inbelic approved this pull request. https://github.com/llvm/llvm-project/pull/140315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add HTMLMustacheGenerator methods (PR #138061)
@@ -70,18 +70,116 @@ class MustacheTemplateFile : public Template { MustacheTemplateFile(StringRef TemplateStr) : Template(TemplateStr) {} }; +static std::unique_ptr NamespaceTemplate = nullptr; + +static std::unique_ptr RecordTemplate = nullptr; + +static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { + return Error::success(); +} + Error MustacheHTMLGenerator::generateDocs( StringRef RootDir, StringMap> Infos, const clang::doc::ClangDocContext &CDCtx) { + if (auto Err = setupTemplateFiles(CDCtx)) +return Err; + // Track which directories we already tried to create. + StringSet<> CreatedDirs; + // Collect all output by file name and create the necessary directories. + StringMap> FileToInfos; + for (const auto &Group : Infos) { +doc::Info *Info = Group.getValue().get(); + +SmallString<128> Path; +sys::path::native(RootDir, Path); +sys::path::append(Path, Info->getRelativeFilePath("")); +if (!CreatedDirs.contains(Path)) { + if (std::error_code EC = sys::fs::create_directories(Path)) +return createStringError(EC, "failed to create directory '%s'.", + Path.c_str()); ilovepi wrote: Ah, good catch. I had missed that. https://github.com/llvm/llvm-project/pull/138061 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenACC][CIR] Implement beginning of 'copy' lowering for compute con… (PR #140304)
https://github.com/bcardosolopes commented: A question in the comments but otherwise PR looks good: adds boilerplate and initial cases, deferring more work for incremental PRs, way to go. https://github.com/llvm/llvm-project/pull/140304 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Cygwin][MinGW] Internal class in explicitly-instantiation-declarated template should be instantiated (PR #140145)
jeremyd2019 wrote: They've failed linking things due to missing `std::istream::sentry` - I've started a new run https://github.com/jeremyd2019/llvm-mingw/actions/runs/15078849158 with ``` #if defined(__MINGW32__) || defined(__CYGWIN__) extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream::sentry; #endif ``` rather than explicitly listing the member(s). https://github.com/llvm/llvm-project/pull/140145 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DirectX][SPIRV] Fix the lowering of dot4add (PR #140315)
@@ -1,17 +1,19 @@ -// RUN: %clang_cc1 -finclude-default-header -triple \ -// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ -// RUN: FileCheck %s -DTARGET=dx -// RUN: %clang_cc1 -finclude-default-header -triple \ -// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ -// RUN: FileCheck %s -DTARGET=spv +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - | FileCheck %s -DTARGET=dx inbelic wrote: ```suggestion // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.4-compute %s -emit-llvm -o - | FileCheck %s -DTARGET=dx ``` Should this error on the lower version at this point as well, or, is it fine to rely on the error generated when lowering further? https://github.com/llvm/llvm-project/pull/140315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add HTMLMustacheGenerator methods (PR #138061)
@@ -70,18 +70,116 @@ class MustacheTemplateFile : public Template { MustacheTemplateFile(StringRef TemplateStr) : Template(TemplateStr) {} }; +static std::unique_ptr NamespaceTemplate = nullptr; + +static std::unique_ptr RecordTemplate = nullptr; + +static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { + return Error::success(); +} + Error MustacheHTMLGenerator::generateDocs( StringRef RootDir, StringMap> Infos, const clang::doc::ClangDocContext &CDCtx) { + if (auto Err = setupTemplateFiles(CDCtx)) +return Err; + // Track which directories we already tried to create. + StringSet<> CreatedDirs; + // Collect all output by file name and create the necessary directories. + StringMap> FileToInfos; + for (const auto &Group : Infos) { +doc::Info *Info = Group.getValue().get(); + +SmallString<128> Path; +sys::path::native(RootDir, Path); +sys::path::append(Path, Info->getRelativeFilePath("")); +if (!CreatedDirs.contains(Path)) { + if (std::error_code EC = sys::fs::create_directories(Path)) +return createStringError(EC, "failed to create directory '%s'.", + Path.c_str()); ilovepi wrote: ah, no dice. We hit a static assert in Format.h ``` error: static assertion failed due to requirement 'std::is_scalar_v': format can't be used with non fundamental / non pointer type 85 | static_assert(std::is_scalar_v ``` https://github.com/llvm/llvm-project/pull/138061 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Add tweak to override pure virtuals (PR #139348)
https://github.com/marcogmaia edited https://github.com/llvm/llvm-project/pull/139348 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] suggest headers on undeclared errors (PR #140247)
https://github.com/jongmyeong-choi edited https://github.com/llvm/llvm-project/pull/140247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] allow single element access of vector object to be constant expression (PR #101126)
ziqingluo-90 wrote: ``` typedef __attribute__((__ext_vector_type__(2))) float float2; struct vec2 { float2 _v; public: constexpr vec2(float x, float y) { _v.x = x; _v.y = y; } }; constexpr struct vec2 f() { return vec2(1.0, 1.0); } int main() { vec2 S = f(); } ``` Clang crashes: https://godbolt.org/z/sx74s1bqd https://github.com/llvm/llvm-project/pull/101126 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SPIRV] Add PreLegalizer pattern matching for `faceforward` (PR #139959)
https://github.com/kmpeng updated https://github.com/llvm/llvm-project/pull/139959 >From be7df595c1df0f310a1941da3d3ac3529270241e Mon Sep 17 00:00:00 2001 From: kmpeng Date: Tue, 29 Apr 2025 16:46:08 -0700 Subject: [PATCH 1/5] WIP - debug `matchSelectToFaceForward` --- .../lib/Headers/hlsl/hlsl_intrinsic_helpers.h | 9 +- llvm/lib/Target/SPIRV/SPIRVCombine.td | 9 +- .../SPIRV/SPIRVPreLegalizerCombiner.cpp | 100 ++ ...egalizercombiner-select-to-faceforward.mir | 33 ++ .../SPIRV/hlsl-intrinsics/faceforward.ll | 44 ++-- 5 files changed, 153 insertions(+), 42 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-select-to-faceforward.mir diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h index 4eb7b8f45c85a..68dc6d96f89c1 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h @@ -127,11 +127,12 @@ template constexpr vector lit_impl(T NDotL, T NDotH, T M) { } template constexpr T faceforward_impl(T N, T I, T Ng) { -#if (__has_builtin(__builtin_spirv_faceforward)) - return __builtin_spirv_faceforward(N, I, Ng); -#else +// #if (__has_builtin(__builtin_spirv_faceforward)) +// return __builtin_spirv_faceforward(N, I, Ng); +// #else +// return select(dot(I, Ng) < 0, N, -N); +// #endif return select(dot(I, Ng) < 0, N, -N); -#endif } template constexpr T ldexp_impl(T X, T Exp) { diff --git a/llvm/lib/Target/SPIRV/SPIRVCombine.td b/llvm/lib/Target/SPIRV/SPIRVCombine.td index 6f726e024de52..78a57146e61d2 100644 --- a/llvm/lib/Target/SPIRV/SPIRVCombine.td +++ b/llvm/lib/Target/SPIRV/SPIRVCombine.td @@ -15,8 +15,15 @@ def vector_length_sub_to_distance_lowering : GICombineRule < (apply [{ applySPIRVDistance(*${root}, MRI, B); }]) >; +def vector_select_to_faceforward_lowering : GICombineRule < + (defs root:$root), + (match (wip_match_opcode G_SELECT):$root, + [{ return matchSelectToFaceForward(*${root}, MRI); }]), + (apply [{ applySPIRVFaceForward(*${root}, MRI, B); }]) +>; + def SPIRVPreLegalizerCombiner : GICombiner<"SPIRVPreLegalizerCombinerImpl", - [vector_length_sub_to_distance_lowering]> { + [vector_length_sub_to_distance_lowering, vector_select_to_faceforward_lowering]> { let CombineAllMethodName = "tryCombineAllImpl"; } diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp index c96ee6b02491a..d323453e68828 100644 --- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp @@ -113,6 +113,106 @@ void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI, SubInstr->eraseFromParent(); // remove FSUB instruction } +/// This match is part of a combine that +/// rewrites select(fcmp(dot(I, Ng), 0), N, 0 - N) to faceforward(N, I, Ng) +/// (vXf32 (g_select +/// (g_fcmp +///(g_intrinsic dot(vXf32 I) (vXf32 Ng) +/// 0) +/// (vXf32 N) +/// (vXf32 g_fsub (0) (vXf32 N +/// -> +/// (vXf32 (g_intrinsic faceforward +/// (vXf32 N) (vXf32 I) (vXf32 Ng))) +/// +bool matchSelectToFaceForward(MachineInstr &MI, MachineRegisterInfo &MRI) { + if (MI.getOpcode() != TargetOpcode::G_SELECT) +return false; + + // Check if the condition is a comparison between a dot product and zero + Register CondReg = MI.getOperand(1).getReg(); + MachineInstr *CondInstr = MRI.getVRegDef(CondReg); + if (!CondInstr || CondInstr->getOpcode() != TargetOpcode::G_FCMP) +return false; + + if (!CondInstr->getOperand(2).getReg()) +return false; + Register DotReg = CondInstr->getOperand(2).getReg(); + MachineInstr *DotInstr = MRI.getVRegDef(DotReg); + // fmul? + if (DotInstr->getOpcode() != TargetOpcode::G_INTRINSIC || cast(DotInstr)->getIntrinsicID() != Intrinsic::spv_fdot) +return false; + // // is using getImm() correct? + // if (!CondInstr->getOperand(3).isImm() || + // CondInstr->getOperand(3).getImm() != 0) + // return false; + + // // Check if the false operand is the negation of the true operand + // Register TrueReg = MI.getOperand(2).getReg(); + // Register FalseReg = MI.getOperand(3).getReg(); + // MachineInstr *FalseInstr = MRI.getVRegDef(FalseReg); + // // getImm() correct? + // if (FalseInstr->getOpcode() != TargetOpcode::G_FSUB || + // FalseInstr->getOperand(1).getImm() != 0 || + // FalseInstr->getOperand(2).getReg() != TrueReg) + // return false; + + return true; +} +void applySPIRVFaceForward(MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilder &B) { + + // Extract the operands for N, I, and Ng from the match criteria. + Register CondReg = MI.getOperand(1).getReg(); + MachineInstr *CondInstr = MRI.getVRegDef(CondReg); + Register DotReg = Co
[clang] [llvm] [SPIRV] Add PreLegalizer pattern matching for `faceforward` (PR #139959)
@@ -98,21 +110,98 @@ void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR = MI.getMF()->getSubtarget().getSPIRVGlobalRegistry(); - auto RemoveAllUses = [&](Register Reg) { -SmallVector UsesToErase( -llvm::make_pointer_range(MRI.use_instructions(Reg))); - -// calling eraseFromParent to early invalidates the iterator. -for (auto *MIToErase : UsesToErase) { - GR->invalidateMachineInstr(MIToErase); - MIToErase->eraseFromParent(); -} - }; - RemoveAllUses(SubDestReg); // remove all uses of FSUB Result + removeAllUses(SubDestReg, MRI, GR); // remove all uses of FSUB Result GR->invalidateMachineInstr(SubInstr); SubInstr->eraseFromParent(); // remove FSUB instruction } +/// This match is part of a combine that +/// rewrites select(fcmp(dot(I, Ng), 0), N, 0 - N) to faceforward(N, I, Ng) +/// (vXf32 (g_select +/// (g_fcmp +///(g_intrinsic dot(vXf32 I) (vXf32 Ng) +/// 0) +/// (vXf32 N) +/// (vXf32 g_fsub (0) (vXf32 N +/// -> +/// (vXf32 (g_intrinsic faceforward +/// (vXf32 N) (vXf32 I) (vXf32 Ng))) +/// +bool matchSelectToFaceForward(MachineInstr &MI, MachineRegisterInfo &MRI) { + if (MI.getOpcode() != TargetOpcode::G_SELECT) +return false; + + // Check if select's condition is a comparison between a dot product and 0. + Register CondReg = MI.getOperand(1).getReg(); + MachineInstr *CondInstr = MRI.getVRegDef(CondReg); + if (!CondInstr || CondInstr->getOpcode() != TargetOpcode::G_FCMP) +return false; + + Register DotReg = CondInstr->getOperand(2).getReg(); + MachineInstr *DotInstr = MRI.getVRegDef(DotReg); + if (DotInstr->getOpcode() != TargetOpcode::G_FMUL && kmpeng wrote: You're right, this would pose a problem. Made an update to check that the dot operands are not vectors. Let me know if that looks good. https://github.com/llvm/llvm-project/pull/139959 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] libcxx: std::ostream::sentry should be exported (PR #140169)
https://github.com/jeremyd2019 closed https://github.com/llvm/llvm-project/pull/140169 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] libcxx: std::ostream::sentry should be exported (PR #140169)
https://github.com/jeremyd2019 reopened https://github.com/llvm/llvm-project/pull/140169 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DirectX][SPIRV] Fix the lowering of dot4add (PR #140315)
@@ -1,17 +1,19 @@ -// RUN: %clang_cc1 -finclude-default-header -triple \ -// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ -// RUN: FileCheck %s -DTARGET=dx -// RUN: %clang_cc1 -finclude-default-header -triple \ -// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ -// RUN: FileCheck %s -DTARGET=spv +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - | FileCheck %s -DTARGET=dx bogner wrote: Yes, this should error. However, the definitions are already marked with `_HLSL_AVAILABILITY(shadermodel, 6.4)` so I'm not sure why this *isn't* erroring. I'll look into this. https://github.com/llvm/llvm-project/pull/140315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add HTMLMustacheGenerator methods (PR #138061)
https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/138061 >From de0222f0459bb6c5832ccdbe70b19f5ea8b0cd98 Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Wed, 30 Apr 2025 08:09:41 -0700 Subject: [PATCH] [clang-doc] Add HTMLMustacheGenerator methods Split from #133161. This patch fills in the implementation for a number of the MustacheHTMLGenerator methods. Many of these APIs are just stubbed out, and will have their implementation filled in by later patches. Co-authored-by: Peter Chou --- .../clang-doc/HTMLMustacheGenerator.cpp | 95 +++ .../unittests/clang-doc/CMakeLists.txt| 1 + .../clang-doc/HTMLMustacheGeneratorTest.cpp | 37 +++- 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp index 6ba0325685599..366deb55b77b9 100644 --- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp @@ -70,18 +70,113 @@ class MustacheTemplateFile : public Template { MustacheTemplateFile(StringRef TemplateStr) : Template(TemplateStr) {} }; +static std::unique_ptr NamespaceTemplate = nullptr; + +static std::unique_ptr RecordTemplate = nullptr; + +static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { + return Error::success(); +} + Error MustacheHTMLGenerator::generateDocs( StringRef RootDir, StringMap> Infos, const clang::doc::ClangDocContext &CDCtx) { + if (auto Err = setupTemplateFiles(CDCtx)) +return Err; + // Track which directories we already tried to create. + StringSet<> CreatedDirs; + // Collect all output by file name and create the necessary directories. + StringMap> FileToInfos; + for (const auto &Group : Infos) { +doc::Info *Info = Group.getValue().get(); + +SmallString<128> Path; +sys::path::native(RootDir, Path); +sys::path::append(Path, Info->getRelativeFilePath("")); +if (!CreatedDirs.contains(Path)) { + if (std::error_code EC = sys::fs::create_directories(Path)) +return createStringError(EC, "failed to create directory '%s'.", + Path.c_str()); + CreatedDirs.insert(Path); +} + +sys::path::append(Path, Info->getFileBaseName() + ".html"); +FileToInfos[Path].push_back(Info); + } + + for (const auto &Group : FileToInfos) { +std::error_code FileErr; +raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None); +if (FileErr) + return createFileOpenError(Group.getKey(), FileErr); + +for (const auto &Info : Group.getValue()) + if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) +return Err; + } return Error::success(); } +static json::Value extractValue(const NamespaceInfo &I, +const ClangDocContext &CDCtx) { + Object NamespaceValue = Object(); + return NamespaceValue; +} + +static json::Value extractValue(const RecordInfo &I, +const ClangDocContext &CDCtx) { + Object RecordValue = Object(); + return RecordValue; +} + +static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V, +Info *I) { + return createStringError(inconvertibleErrorCode(), + "setupTemplateValue is unimplemented"); +} + Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS, const ClangDocContext &CDCtx) { + switch (I->IT) { + case InfoType::IT_namespace: { +json::Value V = +extractValue(*static_cast(I), CDCtx); +if (auto Err = setupTemplateValue(CDCtx, V, I)) + return Err; +NamespaceTemplate->render(V, OS); +break; + } + case InfoType::IT_record: { +json::Value V = +extractValue(*static_cast(I), CDCtx); +if (auto Err = setupTemplateValue(CDCtx, V, I)) + return Err; +// Serialize the JSON value to the output stream in a readable format. +RecordTemplate->render(V, OS); +break; + } + case InfoType::IT_enum: +OS << "IT_enum\n"; +break; + case InfoType::IT_function: +OS << "IT_Function\n"; +break; + case InfoType::IT_typedef: +OS << "IT_typedef\n"; +break; + case InfoType::IT_default: +return createStringError(inconvertibleErrorCode(), "unexpected InfoType"); + } return Error::success(); } Error MustacheHTMLGenerator::createResources(ClangDocContext &CDCtx) { + for (const auto &FilePath : CDCtx.UserStylesheets) +if (Error Err = copyFile(FilePath, CDCtx.OutDirectory)) + return Err; + for (const auto &FilePath : CDCtx.JsScripts) +if (Error Err = copyFile(FilePath, CDCtx.OutDirectory)) + return Err; return Error::success(); } diff --git a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt index 81c18e6014072..fd14d85c63485 10
[clang] [llvm] [SPIRV] Add PreLegalizer pattern matching for `faceforward` (PR #139959)
https://github.com/kmpeng edited https://github.com/llvm/llvm-project/pull/139959 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SPIRV] Add PreLegalizer pattern matching for `faceforward` (PR #139959)
https://github.com/kmpeng edited https://github.com/llvm/llvm-project/pull/139959 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
https://github.com/andykaylor created https://github.com/llvm/llvm-project/pull/140322 There was a problem introduced today where sometimes the CIR for functions with no arguments would be generated with phantom arguments. This was causing intermittent test failures. The problem appears to have been that we were using two different Profile implementations to generate the FoldingSetNodeID for CIRGenFunctionInfo so occaissionally when we tried to look for a pre-existing entry for a function with no arguments it would incorrectly match a CIRGenFunctionInfo entry that had arguments. To prevent this from happening again, I rewrote one of the two Profile functions to call the other. >From 303469f78c951eb25d57b1309ad00e9670a7d475 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Fri, 16 May 2025 17:07:16 -0700 Subject: [PATCH] [CIR] Fix problem with phantom function arguments There was a problem introduced today where sometimes the CIR for functions with no arguments would be generated with phantom arguments. This was causing intermittent test failures. The problem appears to have been that we were using two different Profile implementations to generate the FoldingSetNodeID for CIRGenFunctionInfo so occaissionally when we tried to look for a pre-existing entry for a function with no arguments it would incorrectly match a CIRGenFunctionInfo entry that had arguments. To prevent this from happening again, I rewrote one of the two Profile functions to call the other. --- clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h index 1e06599575fbd..b74460b09a44e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h @@ -112,8 +112,16 @@ class CIRGenFunctionInfo final // NOLINTNEXTLINE(readability-identifier-naming) void Profile(llvm::FoldingSetNodeID &id) { -id.AddBoolean(required.getOpaqueData()); -getReturnType().Profile(id); +// It's unfortunate that we are looping over the arguments twice (here and +// in the static Profile function we call from here), but if the Profile +// functions get out of sync, we can end up with incorrect function +// signatures, and we don't have the argument types in the format that the +// static Profile function requires. +llvm::SmallVector argTypes; +for (const ArgInfo &argInfo : arguments()) + argTypes.push_back(argInfo.type); + +Profile(id, required, getReturnType(), argTypes); } llvm::ArrayRef arguments() const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
llvmbot wrote: @llvm/pr-subscribers-clangir Author: Andy Kaylor (andykaylor) Changes There was a problem introduced today where sometimes the CIR for functions with no arguments would be generated with phantom arguments. This was causing intermittent test failures. The problem appears to have been that we were using two different Profile implementations to generate the FoldingSetNodeID for CIRGenFunctionInfo so occaissionally when we tried to look for a pre-existing entry for a function with no arguments it would incorrectly match a CIRGenFunctionInfo entry that had arguments. To prevent this from happening again, I rewrote one of the two Profile functions to call the other. --- Full diff: https://github.com/llvm/llvm-project/pull/140322.diff 1 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (+10-2) ``diff diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h index 1e06599575fbd..b74460b09a44e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h @@ -112,8 +112,16 @@ class CIRGenFunctionInfo final // NOLINTNEXTLINE(readability-identifier-naming) void Profile(llvm::FoldingSetNodeID &id) { -id.AddBoolean(required.getOpaqueData()); -getReturnType().Profile(id); +// It's unfortunate that we are looping over the arguments twice (here and +// in the static Profile function we call from here), but if the Profile +// functions get out of sync, we can end up with incorrect function +// signatures, and we don't have the argument types in the format that the +// static Profile function requires. +llvm::SmallVector argTypes; +for (const ArgInfo &argInfo : arguments()) + argTypes.push_back(argInfo.type); + +Profile(id, required, getReturnType(), argTypes); } llvm::ArrayRef arguments() const { `` https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Andy Kaylor (andykaylor) Changes There was a problem introduced today where sometimes the CIR for functions with no arguments would be generated with phantom arguments. This was causing intermittent test failures. The problem appears to have been that we were using two different Profile implementations to generate the FoldingSetNodeID for CIRGenFunctionInfo so occaissionally when we tried to look for a pre-existing entry for a function with no arguments it would incorrectly match a CIRGenFunctionInfo entry that had arguments. To prevent this from happening again, I rewrote one of the two Profile functions to call the other. --- Full diff: https://github.com/llvm/llvm-project/pull/140322.diff 1 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (+10-2) ``diff diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h index 1e06599575fbd..b74460b09a44e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h @@ -112,8 +112,16 @@ class CIRGenFunctionInfo final // NOLINTNEXTLINE(readability-identifier-naming) void Profile(llvm::FoldingSetNodeID &id) { -id.AddBoolean(required.getOpaqueData()); -getReturnType().Profile(id); +// It's unfortunate that we are looping over the arguments twice (here and +// in the static Profile function we call from here), but if the Profile +// functions get out of sync, we can end up with incorrect function +// signatures, and we don't have the argument types in the format that the +// static Profile function requires. +llvm::SmallVector argTypes; +for (const ArgInfo &argInfo : arguments()) + argTypes.push_back(argInfo.type); + +Profile(id, required, getReturnType(), argTypes); } llvm::ArrayRef arguments() const { `` https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
@@ -112,8 +112,16 @@ class CIRGenFunctionInfo final // NOLINTNEXTLINE(readability-identifier-naming) void Profile(llvm::FoldingSetNodeID &id) { -id.AddBoolean(required.getOpaqueData()); -getReturnType().Profile(id); +// It's unfortunate that we are looping over the arguments twice (here and +// in the static Profile function we call from here), but if the Profile +// functions get out of sync, we can end up with incorrect function +// signatures, and we don't have the argument types in the format that the andykaylor wrote: This problem will be fixed when I refactor the code to eliminate the ArgInfo class, which now contains only the type. https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add HTMLMustacheGenerator methods (PR #138061)
ilovepi wrote: ### Merge activity * **May 16, 8:28 PM EDT**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/138061). https://github.com/llvm/llvm-project/pull/138061 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
https://github.com/bcardosolopes approved this pull request. LGTM. Is there an easy to add a test for this? I understand sometimes it's hard, but just double checking. https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add HTMLMustacheGenerator methods (PR #138061)
https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/138061 >From 187b130d43c4470768b3885cb9c333b9edfb3897 Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Wed, 30 Apr 2025 08:09:41 -0700 Subject: [PATCH] [clang-doc] Add HTMLMustacheGenerator methods Split from #133161. This patch fills in the implementation for a number of the MustacheHTMLGenerator methods. Many of these APIs are just stubbed out, and will have their implementation filled in by later patches. Co-authored-by: Peter Chou --- .../clang-doc/HTMLMustacheGenerator.cpp | 95 +++ .../unittests/clang-doc/CMakeLists.txt| 1 + .../clang-doc/HTMLMustacheGeneratorTest.cpp | 37 +++- 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp index 6ba0325685599..366deb55b77b9 100644 --- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp @@ -70,18 +70,113 @@ class MustacheTemplateFile : public Template { MustacheTemplateFile(StringRef TemplateStr) : Template(TemplateStr) {} }; +static std::unique_ptr NamespaceTemplate = nullptr; + +static std::unique_ptr RecordTemplate = nullptr; + +static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { + return Error::success(); +} + Error MustacheHTMLGenerator::generateDocs( StringRef RootDir, StringMap> Infos, const clang::doc::ClangDocContext &CDCtx) { + if (auto Err = setupTemplateFiles(CDCtx)) +return Err; + // Track which directories we already tried to create. + StringSet<> CreatedDirs; + // Collect all output by file name and create the necessary directories. + StringMap> FileToInfos; + for (const auto &Group : Infos) { +doc::Info *Info = Group.getValue().get(); + +SmallString<128> Path; +sys::path::native(RootDir, Path); +sys::path::append(Path, Info->getRelativeFilePath("")); +if (!CreatedDirs.contains(Path)) { + if (std::error_code EC = sys::fs::create_directories(Path)) +return createStringError(EC, "failed to create directory '%s'.", + Path.c_str()); + CreatedDirs.insert(Path); +} + +sys::path::append(Path, Info->getFileBaseName() + ".html"); +FileToInfos[Path].push_back(Info); + } + + for (const auto &Group : FileToInfos) { +std::error_code FileErr; +raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None); +if (FileErr) + return createFileOpenError(Group.getKey(), FileErr); + +for (const auto &Info : Group.getValue()) + if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) +return Err; + } return Error::success(); } +static json::Value extractValue(const NamespaceInfo &I, +const ClangDocContext &CDCtx) { + Object NamespaceValue = Object(); + return NamespaceValue; +} + +static json::Value extractValue(const RecordInfo &I, +const ClangDocContext &CDCtx) { + Object RecordValue = Object(); + return RecordValue; +} + +static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V, +Info *I) { + return createStringError(inconvertibleErrorCode(), + "setupTemplateValue is unimplemented"); +} + Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS, const ClangDocContext &CDCtx) { + switch (I->IT) { + case InfoType::IT_namespace: { +json::Value V = +extractValue(*static_cast(I), CDCtx); +if (auto Err = setupTemplateValue(CDCtx, V, I)) + return Err; +NamespaceTemplate->render(V, OS); +break; + } + case InfoType::IT_record: { +json::Value V = +extractValue(*static_cast(I), CDCtx); +if (auto Err = setupTemplateValue(CDCtx, V, I)) + return Err; +// Serialize the JSON value to the output stream in a readable format. +RecordTemplate->render(V, OS); +break; + } + case InfoType::IT_enum: +OS << "IT_enum\n"; +break; + case InfoType::IT_function: +OS << "IT_Function\n"; +break; + case InfoType::IT_typedef: +OS << "IT_typedef\n"; +break; + case InfoType::IT_default: +return createStringError(inconvertibleErrorCode(), "unexpected InfoType"); + } return Error::success(); } Error MustacheHTMLGenerator::createResources(ClangDocContext &CDCtx) { + for (const auto &FilePath : CDCtx.UserStylesheets) +if (Error Err = copyFile(FilePath, CDCtx.OutDirectory)) + return Err; + for (const auto &FilePath : CDCtx.JsScripts) +if (Error Err = copyFile(FilePath, CDCtx.OutDirectory)) + return Err; return Error::success(); } diff --git a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt index 81c18e6014072..fd14d85c63485 10
[clang-tools-extra] 6a0e626 - [clang-doc] Add HTMLMustacheGenerator methods (#138061)
Author: Paul Kirth Date: 2025-05-16T17:30:45-07:00 New Revision: 6a0e626af58bdf8ae8c07cfe8aec94f4565734a3 URL: https://github.com/llvm/llvm-project/commit/6a0e626af58bdf8ae8c07cfe8aec94f4565734a3 DIFF: https://github.com/llvm/llvm-project/commit/6a0e626af58bdf8ae8c07cfe8aec94f4565734a3.diff LOG: [clang-doc] Add HTMLMustacheGenerator methods (#138061) Split from #133161. This patch fills in the implementation for a number of the MustacheHTMLGenerator methods. Many of these APIs are just stubbed out, and will have their implementation filled in by later patches. Co-authored-by: Peter Chou Added: Modified: clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp clang-tools-extra/unittests/clang-doc/CMakeLists.txt clang-tools-extra/unittests/clang-doc/HTMLMustacheGeneratorTest.cpp Removed: diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp index 6ba0325685599..366deb55b77b9 100644 --- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp @@ -70,18 +70,113 @@ class MustacheTemplateFile : public Template { MustacheTemplateFile(StringRef TemplateStr) : Template(TemplateStr) {} }; +static std::unique_ptr NamespaceTemplate = nullptr; + +static std::unique_ptr RecordTemplate = nullptr; + +static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { + return Error::success(); +} + Error MustacheHTMLGenerator::generateDocs( StringRef RootDir, StringMap> Infos, const clang::doc::ClangDocContext &CDCtx) { + if (auto Err = setupTemplateFiles(CDCtx)) +return Err; + // Track which directories we already tried to create. + StringSet<> CreatedDirs; + // Collect all output by file name and create the necessary directories. + StringMap> FileToInfos; + for (const auto &Group : Infos) { +doc::Info *Info = Group.getValue().get(); + +SmallString<128> Path; +sys::path::native(RootDir, Path); +sys::path::append(Path, Info->getRelativeFilePath("")); +if (!CreatedDirs.contains(Path)) { + if (std::error_code EC = sys::fs::create_directories(Path)) +return createStringError(EC, "failed to create directory '%s'.", + Path.c_str()); + CreatedDirs.insert(Path); +} + +sys::path::append(Path, Info->getFileBaseName() + ".html"); +FileToInfos[Path].push_back(Info); + } + + for (const auto &Group : FileToInfos) { +std::error_code FileErr; +raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None); +if (FileErr) + return createFileOpenError(Group.getKey(), FileErr); + +for (const auto &Info : Group.getValue()) + if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) +return Err; + } return Error::success(); } +static json::Value extractValue(const NamespaceInfo &I, +const ClangDocContext &CDCtx) { + Object NamespaceValue = Object(); + return NamespaceValue; +} + +static json::Value extractValue(const RecordInfo &I, +const ClangDocContext &CDCtx) { + Object RecordValue = Object(); + return RecordValue; +} + +static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V, +Info *I) { + return createStringError(inconvertibleErrorCode(), + "setupTemplateValue is unimplemented"); +} + Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS, const ClangDocContext &CDCtx) { + switch (I->IT) { + case InfoType::IT_namespace: { +json::Value V = +extractValue(*static_cast(I), CDCtx); +if (auto Err = setupTemplateValue(CDCtx, V, I)) + return Err; +NamespaceTemplate->render(V, OS); +break; + } + case InfoType::IT_record: { +json::Value V = +extractValue(*static_cast(I), CDCtx); +if (auto Err = setupTemplateValue(CDCtx, V, I)) + return Err; +// Serialize the JSON value to the output stream in a readable format. +RecordTemplate->render(V, OS); +break; + } + case InfoType::IT_enum: +OS << "IT_enum\n"; +break; + case InfoType::IT_function: +OS << "IT_Function\n"; +break; + case InfoType::IT_typedef: +OS << "IT_typedef\n"; +break; + case InfoType::IT_default: +return createStringError(inconvertibleErrorCode(), "unexpected InfoType"); + } return Error::success(); } Error MustacheHTMLGenerator::createResources(ClangDocContext &CDCtx) { + for (const auto &FilePath : CDCtx.UserStylesheets) +if (Error Err = copyFile(FilePath, CDCtx.OutDirectory)) + return Err; + for (const auto &FilePath : CDCtx.JsScripts) +if (Error Err = copyFile(FilePath, CDCtx.OutDirectory)) + return Err; return Error::success(); } diff --g
[clang-tools-extra] [clang-doc] Add HTMLMustacheGenerator methods (PR #138061)
https://github.com/ilovepi closed https://github.com/llvm/llvm-project/pull/138061 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)
https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/138062 >From 442fe2fd1353c540bc0ec39ec913e7e414def6bc Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Wed, 30 Apr 2025 08:10:20 -0700 Subject: [PATCH] [clang-doc] Add helpers for Template config This patch adds or fills in some helper functions related to template setup when initializing the mustache backend. It was split from #133161. Co-authored-by: Peter Chou --- .../clang-doc/HTMLMustacheGenerator.cpp | 45 ++ .../clang-doc/support/CMakeLists.txt | 4 +- clang-tools-extra/clang-doc/support/Utils.cpp | 61 +++ clang-tools-extra/clang-doc/support/Utils.h | 26 .../unittests/clang-doc/CMakeLists.txt| 12 .../clang-doc/HTMLMustacheGeneratorTest.cpp | 11 +++- .../unittests/clang-doc/config.h.cmake| 6 ++ 7 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/clang-doc/support/Utils.cpp create mode 100644 clang-tools-extra/clang-doc/support/Utils.h create mode 100644 clang-tools-extra/unittests/clang-doc/config.h.cmake diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp index 366deb55b77b9..f7e53fc64196a 100644 --- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mustache.h" +#include "llvm/Support/Path.h" using namespace llvm; using namespace llvm::json; @@ -74,7 +75,51 @@ static std::unique_ptr NamespaceTemplate = nullptr; static std::unique_ptr RecordTemplate = nullptr; +static Error +setupTemplate(std::unique_ptr &Template, + StringRef TemplatePath, + std::vector> Partials) { + auto T = MustacheTemplateFile::createMustacheFile(TemplatePath); + if (Error Err = T.takeError()) +return Err; + Template = std::move(T.get()); + for (const auto [Name, FileName] : Partials) { +if (auto Err = Template->registerPartialFile(Name, FileName)) + return Err; + } + return Error::success(); +} + static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { + // Template files need to use the native path when they're opened, + // but have to be used in Posix style when used in HTML. + auto ConvertToNative = [](std::string &&Path) -> std::string { +SmallString<128> PathBuf(Path); +llvm::sys::path::native(PathBuf); +return PathBuf.str().str(); + }; + + std::string NamespaceFilePath = + ConvertToNative(CDCtx.MustacheTemplates.lookup("namespace-template")); + std::string ClassFilePath = + ConvertToNative(CDCtx.MustacheTemplates.lookup("class-template")); + std::string CommentFilePath = + ConvertToNative(CDCtx.MustacheTemplates.lookup("comments-template")); + std::string FunctionFilePath = + ConvertToNative(CDCtx.MustacheTemplates.lookup("function-template")); + std::string EnumFilePath = + ConvertToNative(CDCtx.MustacheTemplates.lookup("enum-template")); + std::vector> Partials = { + {"Comments", CommentFilePath}, + {"FunctionPartial", FunctionFilePath}, + {"EnumPartial", EnumFilePath}}; + + if (Error Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, Partials)) +return Err; + + if (Error Err = setupTemplate(RecordTemplate, ClassFilePath, Partials)) +return Err; + return Error::success(); } diff --git a/clang-tools-extra/clang-doc/support/CMakeLists.txt b/clang-tools-extra/clang-doc/support/CMakeLists.txt index a4f7993d5c9d8..f470a613b95d9 100644 --- a/clang-tools-extra/clang-doc/support/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/support/CMakeLists.txt @@ -6,4 +6,6 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangDocSupport STATIC File.cpp - ) \ No newline at end of file + Utils.cpp + ) + diff --git a/clang-tools-extra/clang-doc/support/Utils.cpp b/clang-tools-extra/clang-doc/support/Utils.cpp new file mode 100644 index 0..f1d193379afa6 --- /dev/null +++ b/clang-tools-extra/clang-doc/support/Utils.cpp @@ -0,0 +1,61 @@ +//===--===// +// +// 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 +// +//===--===// + +#include "Utils.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace llvm; + +SmallString<128> appendPathNative(StringRef Base, StringRef Path) { + SmallString<128> Default; + sys::path::native(Base, Default); + sys::path::append(Default, Path); + return Default; +} + +SmallString<128> appendPathPosix
[clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)
https://github.com/ilovepi edited https://github.com/llvm/llvm-project/pull/138062 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
https://github.com/el-ev approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
@@ -112,8 +112,16 @@ class CIRGenFunctionInfo final // NOLINTNEXTLINE(readability-identifier-naming) void Profile(llvm::FoldingSetNodeID &id) { -id.AddBoolean(required.getOpaqueData()); -getReturnType().Profile(id); +// It's unfortunate that we are looping over the arguments twice (here and +// in the static Profile function we call from here), but if the Profile +// functions get out of sync, we can end up with incorrect function +// signatures, and we don't have the argument types in the format that the bcardosolopes wrote: Oh, I see, thanks for the extra context! https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
andykaylor wrote: > LGTM. Is there an easy to add a test for this? I understand sometimes it's > hard, but just double checking. The only thing I can think of would be a unit test that calculates folding set IDs for a bunch of similar, but slightly different, function signatures to verify that we don't incorrectly match them. That's probably worth doing, but I wouldn't want to hold this fix for it. https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Cygwin][MinGW] Internal class in explicitly-instantiation-declarated template should be instantiated (PR #140145)
jeremyd2019 wrote: trying to use this libc++ ci is less than helpful: the jobs keep failing for no apparent reason (cancelled? docker not running?), and whatever seems to be supposed to rerun the failed jobs is not all that reliable about doing so. Hopefully my llvm-mingw fork will show this technique works, and we can be reassured that being in an ifdef that isn't true for any other platform shouldn't break any other platform either. https://github.com/llvm/llvm-project/pull/140145 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f7ef8dc - [CIR] Fix problem with phantom function arguments (#140322)
Author: Andy Kaylor Date: 2025-05-16T18:01:12-07:00 New Revision: f7ef8dcbad9d5ac6cf2a8917d5ce03564fdfd0d8 URL: https://github.com/llvm/llvm-project/commit/f7ef8dcbad9d5ac6cf2a8917d5ce03564fdfd0d8 DIFF: https://github.com/llvm/llvm-project/commit/f7ef8dcbad9d5ac6cf2a8917d5ce03564fdfd0d8.diff LOG: [CIR] Fix problem with phantom function arguments (#140322) There was a problem introduced today where sometimes the CIR for functions with no arguments would be generated with phantom arguments. This was causing intermittent test failures. The problem appears to have been that we were using two different Profile implementations to generate the FoldingSetNodeID for CIRGenFunctionInfo so occaissionally when we tried to look for a pre-existing entry for a function with no arguments it would incorrectly match a CIRGenFunctionInfo entry that had arguments. To prevent this from happening again, I rewrote one of the two Profile functions to call the other. Added: Modified: clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h Removed: diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h index 1e06599575fbd..b74460b09a44e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h @@ -112,8 +112,16 @@ class CIRGenFunctionInfo final // NOLINTNEXTLINE(readability-identifier-naming) void Profile(llvm::FoldingSetNodeID &id) { -id.AddBoolean(required.getOpaqueData()); -getReturnType().Profile(id); +// It's unfortunate that we are looping over the arguments twice (here and +// in the static Profile function we call from here), but if the Profile +// functions get out of sync, we can end up with incorrect function +// signatures, and we don't have the argument types in the format that the +// static Profile function requires. +llvm::SmallVector argTypes; +for (const ArgInfo &argInfo : arguments()) + argTypes.push_back(argInfo.type); + +Profile(id, required, getReturnType(), argTypes); } llvm::ArrayRef arguments() const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix problem with phantom function arguments (PR #140322)
https://github.com/andykaylor closed https://github.com/llvm/llvm-project/pull/140322 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Driver] Use llvm::is_contained (NFC) (PR #140310)
https://github.com/tgymnich approved this pull request. https://github.com/llvm/llvm-project/pull/140310 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Frontend] Avoid creating a temporary instance of std::string (NFC) (PR #140326)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Kazu Hirata (kazutakahirata) Changes Since getLastArgValue returns StringRef, and the constructor of SmallString accepts StringRef, we do not need to go through a temporary instance of std::string. --- Full diff: https://github.com/llvm/llvm-project/pull/140326.diff 1 Files Affected: - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+1-2) ``diff diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index fd48e425a5c21..3c23073fc6a8c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2055,8 +2055,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, // The memory profile runtime appends the pid to make this name more unique. const char *MemProfileBasename = "memprof.profraw"; if (Args.hasArg(OPT_fmemory_profile_EQ)) { -SmallString<128> Path( -std::string(Args.getLastArgValue(OPT_fmemory_profile_EQ))); +SmallString<128> Path(Args.getLastArgValue(OPT_fmemory_profile_EQ)); llvm::sys::path::append(Path, MemProfileBasename); Opts.MemoryProfileOutput = std::string(Path); } else if (Args.hasArg(OPT_fmemory_profile)) `` https://github.com/llvm/llvm-project/pull/140326 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Frontend] Avoid creating a temporary instance of std::string (NFC) (PR #140326)
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/140326 Since getLastArgValue returns StringRef, and the constructor of SmallString accepts StringRef, we do not need to go through a temporary instance of std::string. >From 0f87807ef3159de0350dd85b4f5f8dd289c797f4 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Fri, 16 May 2025 17:58:06 -0700 Subject: [PATCH] [Frontend] Avoid creating a temporary instance of std::string (NFC) Since getLastArgValue returns StringRef, and the constructor of SmallString accepts StringRef, we do not need to go through a temporary instance of std::string. --- clang/lib/Frontend/CompilerInvocation.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index fd48e425a5c21..3c23073fc6a8c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2055,8 +2055,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, // The memory profile runtime appends the pid to make this name more unique. const char *MemProfileBasename = "memprof.profraw"; if (Args.hasArg(OPT_fmemory_profile_EQ)) { -SmallString<128> Path( -std::string(Args.getLastArgValue(OPT_fmemory_profile_EQ))); +SmallString<128> Path(Args.getLastArgValue(OPT_fmemory_profile_EQ)); llvm::sys::path::append(Path, MemProfileBasename); Opts.MemoryProfileOutput = std::string(Path); } else if (Args.hasArg(OPT_fmemory_profile)) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] suggest headers on undeclared errors (#120388) (PR #140247)
@@ -26,14 +26,18 @@ void no_get_1() { auto [a0, a1] = A(); // expected-error {{decomposes into 3 elements}} auto [b0, b1] = B(); // expected-error {{decomposes into 3 elements}} } - auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit initialization of binding declaration 'a0'}} + auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} \ + // expected-note {{perhaps `#include ` is needed?}} \ shafik wrote: Yeah, this does not seem helpful, it feels actively harmful actually. https://github.com/llvm/llvm-project/pull/140247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [-Wunsafe-buffer-usage] Fix false warnings when const sized array is safely accessed (array [idx %const]) (PR #140113)
malavikasamak wrote: CC @dtarditi https://github.com/llvm/llvm-project/pull/140113 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix an assertion in the resolution of perfect matches (PR #140073)
cor3ntin wrote: @alexfh Thanks a lot. I have a fix, a PR will be made once I run the tests https://github.com/llvm/llvm-project/pull/140073 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits