[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; kovdan01 wrote: Do I get it correct that you use `unsigned` for all bit fields instead of `bool IsXXX : 1` for flags and just `uint16_t ConstantDiscriminator` because you rely on some implementation-defined behavior which makes packing fields of the same types more efficient? If you do not rely on that, having more specific types looks more appropriate. In `class CGPointerAuthInfo` you use different types for bit fields (e.g. `bool IsXXX : 1` is used for flags). So, it's better to keep things consistent and also use such convention here (or, alternatively, use `unsigned` everywhere if there is a strong reason for this) https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include kovdan01 wrote: There are several unneeded includes (vector, map, ...). If I'm not mistaken, only clang/Basic/LangOptions.h and llvm/Support/ErrorHandling.h are required. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -3041,3 +3046,20 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name); } + +void CodeGenFunction::EmitPointerAuthOperandBundle( +const CGPointerAuthInfo &pointerAuth, +SmallVectorImpl &bundles) { + if (!pointerAuth.isSigned()) +return; + + auto key = Builder.getInt32(pointerAuth.getKey()); kovdan01 wrote: ```suggestion auto *Key = Builder.getInt32(pointerAuth.getKey()); ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -104,10 +109,13 @@ class CGCallee { /// Construct a callee. Call this constructor directly when this /// isn't a direct call. - CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr) + CGCallee( + const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr, + const CGPointerAuthInfo &pointerAuthInfo = /*FIXME*/ CGPointerAuthInfo()) kovdan01 wrote: Could you please provide additional context for this FIXME? https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -3041,3 +3046,20 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name); } + +void CodeGenFunction::EmitPointerAuthOperandBundle( kovdan01 wrote: `PascalCase` for variables in this function - surrounding code already uses this naming convention https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -75,3 +93,36 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, return CGM.getConstantSignedPointer(pointer, key, storageAddress, otherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for +/// functionType. +llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *pointer, kovdan01 wrote: `PascalCase` for variables in this function and all over the file - it's a new file, so IMHO there is no reason to stick with old naming conventions https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -26,6 +26,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/NoSanitizeList.h" +#include "clang/Basic/PointerAuthOptions.h" kovdan01 wrote: This include looks unneeded since further forward declaration `class PointerAuthSchema;` does the job https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -75,3 +93,36 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, return CGM.getConstantSignedPointer(pointer, key, storageAddress, otherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for +/// functionType. +llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *pointer, + QualType functionType, + GlobalDecl GD) { + assert(functionType->isFunctionType() || + functionType->isFunctionReferenceType() || + functionType->isFunctionPointerType()); + + if (auto pointerAuth = getFunctionPointerAuthInfo(functionType)) { +return getConstantSignedPointer( + pointer, pointerAuth.getKey(), nullptr, + cast_or_null(pointerAuth.getDiscriminator())); + } + + return pointer; +} + +llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD, + llvm::Type *Ty) { + const FunctionDecl *FD = cast(GD.getDecl()); kovdan01 wrote: nit ```suggestion const auto *FD = cast(GD.getDecl()); ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; + unsigned IsIsaPointer : 1; + unsigned AuthenticatesNullValues : 1; + PointerAuthenticationMode SelectedAuthenticationMode : 2; + Discrimination DiscriminationKind : 2; + unsigned Key : 4; + unsigned ConstantDiscriminator : 16; + +public: + PointerAuthSchema() : TheKind(Kind::None) {} + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + PointerAuthenticationMode AuthenticationMode, + Discrimination OtherDiscrimination, + std::optional ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : TheKind(Kind::ARM8_3), IsAddressDiscriminated(IsAddressDiscriminated), +IsIsaPointer(IsIsaPointer), +AuthenticatesNullValues(AuthenticatesNullValues), +SelectedAuthenticationMode(AuthenticationMode), +DiscriminationKind(OtherDiscrimination), Key(unsigned(Key)) { kovdan01 wrote: Consider using `llvm::to_underlying` from llvm/ADT/STLForwardCompat.h: ```suggestion DiscriminationKind(OtherDiscrimination), Key(llvm::to_underlying(Key)) { ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -28,6 +28,24 @@ using namespace clang; using namespace CodeGen; +/// Return the abstract pointer authentication schema for a pointer to the given +/// function type. +CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) { + auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers; kovdan01 wrote: ```suggestion const auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers; ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; + unsigned IsIsaPointer : 1; + unsigned AuthenticatesNullValues : 1; + PointerAuthenticationMode SelectedAuthenticationMode : 2; + Discrimination DiscriminationKind : 2; + unsigned Key : 4; + unsigned ConstantDiscriminator : 16; + +public: + PointerAuthSchema() : TheKind(Kind::None) {} + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + PointerAuthenticationMode AuthenticationMode, + Discrimination OtherDiscrimination, + std::optional ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : TheKind(Kind::ARM8_3), IsAddressDiscriminated(IsAddressDiscriminated), +IsIsaPointer(IsIsaPointer), +AuthenticatesNullValues(AuthenticatesNullValues), +SelectedAuthenticationMode(AuthenticationMode), +DiscriminationKind(OtherDiscrimination), Key(unsigned(Key)) { +assert((getOtherDiscrimination() != Discrimination::Constant || +ConstantDiscriminatorOrNone) && + "constant discrimination requires a constant!"); +if (ConstantDiscriminatorOrNone) + ConstantDiscriminator = *ConstantDiscriminatorOrNone; + } + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + Discrimination OtherDiscrimination, + std::optional ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : PointerAuthSchema(Key, IsAddressDiscriminated, + PointerAuthenticationMode::SignAndAuth, + OtherDiscrimination, ConstantDiscriminatorOrNone, + IsIsaPointer, AuthenticatesNullValues) {} + + Kind getKind() const { return TheKind; } + + explicit operator bool() const { return isEnabled(); } + + bool isEnabled() const { return getKind() != Kind::None; } + + bool isAddressDiscriminated() const { +assert(getKind() != Kind::None); +return IsAddressDiscriminated; + } + + bool isIsaPointer() const { +assert(getKind() != Kind::None); +return IsIsaPointer; + } + + bool authenticatesNullValues() const { +assert(getKind() != Kind::None); +return AuthenticatesNullValues; + } + + bool hasOtherDiscrimination() const { +return getOtherDiscrimination() != Discrimination::None; + } + + Discrimination getOtherDiscrimination() const { +assert(getKind() != Kind::None); +return DiscriminationKind; + } + + uint16_t getConstantDiscrimination() const { +assert(getOtherDiscrimination() == Discrimination::Constant); +return (uint16_t)ConstantDiscriminator; kovdan01 wrote: Is the manual cast really needed? The following works for me just fine: ```suggestion return ConstantDiscriminator; ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -351,6 +351,9 @@ def err_drv_omp_host_ir_file_not_found : Error< "target regions but cannot be found">; def err_drv_omp_host_target_not_supported : Error< "target '%0' is not a supported OpenMP host target">; +def err_drv_ptrauth_not_supported : Error< + "target '%0' does not support native pointer authentication">; kovdan01 wrote: This error message looks untested https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [Flang][OpenMP] Update flang with changes to the OpenMP dialect (PR #92524)
@@ -1086,8 +1086,9 @@ static void genTargetDataClauses( // ordering. // TODO: Perhaps create a user provideable compiler option that will // re-introduce a hard-error rather than a warning in these cases. - promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr(clauseOps, useDeviceTypes, -useDeviceLocs, useDeviceSyms); + promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr( + clauseOps.useDeviceAddrVars, clauseOps.useDevicePtrVars, useDeviceTypes, + useDeviceLocs, useDeviceSyms); ergawy wrote: Not sure why we need that change? Why not pass `clauseOps` and retrieve both members inside `promoteNonCPtrUseDevicePtrArgsToUseDEviceAddr`? https://github.com/llvm/llvm-project/pull/92524 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][OpenMP] Clause-based OpenMP operation definition (PR #92523)
tblah wrote: > @tblah thanks for giving this a look. Basically the issue here with the > reduction clause is that its description is currently different for each > operation that accepts it. > It would be great to agree on a generic description for that clause that > would work for all ops, so that it makes sense while reading the generated > documentation and also being centralized into the clause definition rather > than each operation. I created a gist > [here](https://gist.github.com/skatrak/ee6e1829980867f8119f91f84cb284b1) with > the whole list of descriptions that currently exist for `reduction`, in case > that helps with figuring out a shared description. Thanks for taking the time to create the gist. Some thoughts - I think some of the descriptions are out of date. `omp.reduction` has been removed: https://github.com/llvm/llvm-project/pull/92732 - Assuming that `omp.reduction` really was unused, I think that leaves byref as the main difference? I guess fixing byref is on me (https://github.com/llvm/llvm-project/pull/92244). Unfortunately I can't work on this immediately so I won't hold up this PR for it. https://github.com/llvm/llvm-project/pull/92523 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][OpenMP] Clause-based OpenMP operation definition (PR #92523)
https://github.com/tblah approved this pull request. LGTM, but please wait for another reviewer https://github.com/llvm/llvm-project/pull/92523 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][OpenMP] Clause-based OpenMP operation definition (PR #92523)
https://github.com/tblah edited https://github.com/llvm/llvm-project/pull/92523 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -1856,6 +1856,12 @@ class ConstantLValueEmitter : public ConstStmtVisitor kovdan01 wrote: >From the function prototype, it's unclear that the first element of the pair >stands for `StorageAddress` and the second one - for `OtherDiscriminator`. >Consider adding a comment or, alternatively, using a named structure instead >of `std::pair` (would break `std::tie` usage though) https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -0,0 +1,63 @@ +//===--- CGPointerAuth.cpp - IR generation for pointer authentication -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file contains common routines relating to the emission of +// pointer authentication operations. +// +//===--===// + +#include "CodeGenModule.h" +#include "clang/CodeGen/CodeGenABITypes.h" + +using namespace clang; +using namespace CodeGen; + +/// Build a signed-pointer "ptrauth" constant. +static llvm::ConstantPtrAuth * +buildConstantAddress(CodeGenModule &CGM, llvm::Constant *Pointer, unsigned Key, + llvm::Constant *StorageAddress, + llvm::Constant *OtherDiscriminator) { + llvm::Constant *AddressDiscriminator = nullptr; kovdan01 wrote: Do we need to set this to `nullptr`? We 100% define this in either `if` or `else` branch and do not use the unitialized value before. Same applies to `IntegerDiscriminator` below. You can also use smth like ``` llvm::Constant *AddressDiscriminator = (StorageAddress ? StorageAddress : llvm::Constant::getNullValue(CGM.UnqualPtrTy)); assert(!StorageAddress || (StorageAddress->getType() == CGM.UnqualPtrTy)); ``` https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2061,6 +2071,58 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) { } } +ConstantLValue +ConstantLValueEmitter::emitPointerAuthSignConstant(const CallExpr *E) { + llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->getArg(0)); + unsigned Key = emitPointerAuthKey(E->getArg(1)); + llvm::Constant *StorageAddress; + llvm::Constant *OtherDiscriminator; + std::tie(StorageAddress, OtherDiscriminator) = + emitPointerAuthDiscriminator(E->getArg(2)); + + llvm::Constant *SignedPointer = CGM.getConstantSignedPointer( + UnsignedPointer, Key, StorageAddress, OtherDiscriminator); + return SignedPointer; +} + +llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) { + Expr::EvalResult Result; + bool Succeeded = E->EvaluateAsRValue(Result, CGM.getContext()); + assert(Succeeded); + (void)Succeeded; + + // The assertions here are all checked by Sema. + assert(Result.Val.isLValue()); + return ConstantEmitter(CGM, Emitter.CGF) + .emitAbstract(E->getExprLoc(), Result.Val, E->getType()); +} + +unsigned ConstantLValueEmitter::emitPointerAuthKey(const Expr *E) { + return E->EvaluateKnownConstInt(CGM.getContext()).getZExtValue(); +} + +std::pair +ConstantLValueEmitter::emitPointerAuthDiscriminator(const Expr *E) { + E = E->IgnoreParens(); + + if (auto *Call = dyn_cast(E)) { kovdan01 wrote: ```suggestion if (const auto *Call = dyn_cast(E)) { ``` https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
@@ -0,0 +1,46 @@ +//===--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H +#define _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class move_only_function; + +template +struct __is_move_only_function : false_type {}; + +template +struct __is_move_only_function> : true_type {}; + +template +struct _MoveOnlyFunctionTrivialVTable { + using _CallFunc = _ReturnT(_BufferT&, _ArgTypes...); + + _CallFunc* __call_; +}; + +template +struct _MoveOnlyFunctionNonTrivialVTable : _MoveOnlyFunctionTrivialVTable<_BufferT, _ReturnT, _ArgTypes...> { EricWF wrote: You either don't need the inheritance, or you don't need to give the "destruct" base class all the arguments, you only need that for the call. https://github.com/llvm/llvm-project/pull/94670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
@@ -0,0 +1,233 @@ +//===--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +// This header is unguarded on purpose. This header is an implementation detail of move_only_function.h +// and generates multiple versions of std::move_only_function + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/move_only_function_common.h> +#include <__type_traits/is_trivially_destructible.h> +#include <__utility/exchange.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <__utility/pointer_int_pair.h> +#include <__utility/small_buffer.h> +#include <__utility/swap.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_IN_MOVE_ONLY_FUNCTION_H +# error This header should only be included from move_only_function.h +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_CV +# define _LIBCPP_MOVE_ONLY_FUNCTION_CV +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_REF EricWF wrote: Huh, so I stand corrected here. Normally, the way the terrible diagnostics come about is through the diagnostic caret pointing at a macro expansion. For example, were an invalid expression formed via a macro expansion, it would produce a diagnostic like: https://godbolt.org/z/dKr1nzPd9 ``` :12:1: error: no matching function for call to 'invoke' 12 | EXPAND ``` However, since we never actually expand any of the expressions fully from a macro, and none of the macros lead an expression (where the caret might point, `_VSTD` was notorious for this), the diagnostics produced by your implementation don't get all muddy. Neither do they really appear to hide too much information. I was worried it would be hard to tell the actual CV, ref, and noexcept qualifiers were present from a particular diagnostic. And while you can't see what's used from the source, the clang diagnostics always seem to provide enough information to figure out which specialization your in. But that also seems to work: ``` /home/eric/llvm-project/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.move/call/rvalue_const_noexcept.pass.cpp:51:5: error: no matching function for call to object of type 'std::move_only_function' 51 | f(); | ^ /home/eric/llvm-project/libcxx/include/__functional/move_only_function_impl.h:200:34: note: candidate function not viable: expects an rvalue for object argument 200 | _LIBCPP_HIDE_FROM_ABI _ReturnT operator()(_ArgTypes... __args) _LIBCPP_MOVE_ONLY_FUNCTION_CVREF ``` Now I still hate using the preprocessor, and dislike creating non-modular re-includable headers. And I have a strong aversion to its use. But diagnostics don't appear to be an issue here. https://github.com/llvm/llvm-project/pull/94670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives (PR #94689)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/94689 >From 64fcf25e2158de44bccf725a0f91d8228b7cb7a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 6 Jun 2024 15:10:13 -0500 Subject: [PATCH 1/3] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives The categories are primarily meant for OpenMP, where the spec assigns a category to each directive. It's one of declarative, executable, informational, meta, subsidiary, and utility. These will be used in clang to avoid listing directives belonging to certain categories by hand. --- .../llvm/Frontend/Directive/DirectiveBase.td | 15 +++ llvm/include/llvm/Frontend/OpenACC/ACC.td | 21 llvm/include/llvm/Frontend/OpenMP/OMP.td | 109 ++ llvm/include/llvm/TableGen/DirectiveEmitter.h | 6 + llvm/test/TableGen/directive1.td | 23 +++- llvm/test/TableGen/directive2.td | 23 +++- llvm/utils/TableGen/DirectiveEmitter.cpp | 31 - 7 files changed, 225 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td index ce532e0cfae29..6889c7e642ec6 100644 --- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td +++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td @@ -156,6 +156,18 @@ def AS_FromLeaves : Association<"FromLeaves"> {}// See below // The name "AS_FromLeaves" is recognized by TableGen, and there is no enum // generated for it. +// Kinds of directive categories. +class Category { + string name = n; // Name of the enum value in enum class Category. +} + +def CA_Declarative: Category<"Declarative"> {} +def CA_Executable: Category<"Executable"> {} +def CA_Informational: Category<"Informational"> {} +def CA_Meta: Category<"Meta"> {} +def CA_Subsidiary: Category<"Subsidiary"> {} +def CA_Utility: Category<"Utility"> {} + // Information about a specific directive. class Directive { // Name of the directive. Can be composite directive sepearted by whitespace. @@ -190,4 +202,7 @@ class Directive { // What the directive is associated with. Association association = AS_FromLeaves; + + // The category if the directive. + Category category = ?; } diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td index dfa6a222e9f77..30a81efe7f8a6 100644 --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -268,6 +268,7 @@ def ACCC_Unknown : Clause<"unknown"> { // 2.12 def ACC_Atomic : Directive<"atomic"> { let association = AS_Block; + let category = CA_Executable; } // 2.6.5 @@ -293,6 +294,7 @@ def ACC_Data : Directive<"data"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.13 @@ -308,6 +310,7 @@ def ACC_Declare : Directive<"declare"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.5.3 @@ -334,6 +337,7 @@ def ACC_Kernels : Directive<"kernels"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.1 @@ -363,6 +367,7 @@ def ACC_Parallel : Directive<"parallel"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.2 @@ -391,6 +396,7 @@ def ACC_Serial : Directive<"serial"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.9 @@ -411,11 +417,13 @@ def ACC_Loop : Directive<"loop"> { VersionedClause ]; let association = AS_Loop; + let category = CA_Executable; } // 2.10 def ACC_Cache : Directive<"cache"> { let association = AS_None; + let category = CA_Executable; } // 2.14.1 @@ -426,6 +434,7 @@ def ACC_Init : Directive<"init"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.15.1 @@ -442,6 +451,7 @@ def ACC_Routine : Directive<"routine"> { VersionedClause ]; let association = AS_Declaration; + let category = CA_Declarative; } // 2.14.3 @@ -461,6 +471,7 @@ def ACC_Set : Directive<"set"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.2 @@ -471,6 +482,7 @@ def ACC_Shutdown : Directive<"shutdown"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.4 @@ -490,6 +502,7 @@ def ACC_Update : Directive<"update"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.16.3 @@ -499,6 +512,7 @@ def ACC_Wait : Directive<"wait"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.6 @@ -516,6 +530,7 @@ def ACC_EnterData : Directive<"enter data"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.7 @@ -534,6 +549,7 @@ def ACC_E
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
EricWF wrote: After implementing a version myself, I think there's a bunch of unneeded complexity in this type. I compared the two implementations on a personal compiler-explorer which is set up to compare libc++ patches (I'm working to provide to other developers). The use of `__libcpp_allocate` and `__libcpp_deallocate` allow the compiler to optimize away the allocations in mine, but not in this implementation. The result is the difference between each test optimizing to basically zero code vs a bunch of code. This is the codegen for one of the `call` tests ```asm test(): # @test() push rax lea rax, [rip + std::__2::move_only_function::__trivial_vtable_] cmp rax, 7 jbe .LBB0_8 lea rax, [rip + std::__2::move_only_function::__trivial_vtable_] cmp rax, 7 jbe .LBB0_8 mov byte ptr [rip + called], 0 mov edi, 40 mov esi, 1 call operator new[](unsigned long, std::align_val_t)@PLT lea rcx, [rip + std::__2::move_only_function::__non_trivial_vtable_] cmp rcx, 7 jbe .LBB0_8 mov byte ptr [rip + called], 1 mov esi, 40 mov edx, 1 mov rdi, rax call operator delete[](void*, unsigned long, std::align_val_t)@PLT mov byte ptr [rip + called], 0 mov edi, 1 mov esi, 1 call operator new[](unsigned long, std::align_val_t)@PLT lea rcx, [rip + std::__2::move_only_function::__non_trivial_vtable_] cmp rcx, 7 jbe .LBB0_8 mov byte ptr [rip + called], 1 mov esi, 1 mov edx, 1 mov rdi, rax call operator delete[](void*, unsigned long, std::align_val_t)@PLT lea rax, [rip + std::__2::move_only_function::__trivial_vtable_] cmp rax, 7 jbe .LBB0_11 lea rax, [rip + std::__2::move_only_function::__trivial_vtable_] cmp rax, 7 jbe .LBB0_8 pop rax ret .LBB0_8: ud2 .LBB0_11: lea rdi, [rip + .L.str.2] lea rsi, [rip + .L.str.1] lea rcx, [rip + .L__PRETTY_FUNCTION__.test()] mov edx, 56 call __assert_fail@PLT mov rdi, rax call __clang_call_terminate mov rdi, rax call __clang_call_terminate test_return(): # @test_return() push rax lea rax, [rip + std::__2::move_only_function::__trivial_vtable_] cmp rax, 7 jbe .LBB1_9 lea rax, [rip + std::__2::move_only_function::__trivial_vtable_] cmp rax, 7 jbe .LBB1_9 mov byte ptr [rip + called], 0 mov edi, 40 mov esi, 1 call operator new[](unsigned long, std::align_val_t)@PLT lea rcx, [rip + std::__2::move_only_function::__non_trivial_vtable_] cmp rcx, 7 jbe .LBB1_9 cmp byte ptr [rip + called], 1 je .LBB1_11 mov esi, 40 mov edx, 1 mov rdi, rax call operator delete[](void*, unsigned long, std::align_val_t)@PLT mov byte ptr [rip + called], 0 mov edi, 1 mov esi, 1 call operator new[](unsigned long, std::align_val_t)@PLT lea rcx, [rip + std::__2::move_only_function::__non_trivial_vtable_] cmp rcx, 7 jbe .LBB1_9 cmp byte ptr [rip + called], 1 je .LBB1_13 mov esi, 1 mov edx, 1 mov rdi, rax pop rax jmp operator delete[](void*, unsigned long, std::align_val_t)@PLT # TAILCALL .LBB1_9: ud2 .LBB1_11: lea rdi, [rip + .L.str.6] lea rsi, [rip + .L.str.1] lea rcx, [rip + .L__PRETTY_FUNCTION__.test_return()] mov edx, 89 call __assert_fail@PLT .LBB1_13: lea rdi, [rip + .L.str.6] lea rsi, [rip + .L.str.1] lea rcx, [rip + .L__PRETTY_FUNCTION__.test_return()] mov edx, 95 call __assert_fail@PLT mov rdi, rax call __clang_call_terminate mov rdi, rax call __clang_call_terminate main: # @main push rax call test_return() call test() xor eax, eax pop rcx ret __clang_call_terminate: # @__clang_call_terminate push rax call __cxa_begin_catch@PLT call std::terminate()@PLT std::__2::move_only_function::__trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&): # @std::__2::move_only_function::__trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&) jmp qword ptr [rdi] # TAILCALL std::__2::move_only_function::__trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&): # @std::__2::move_only_function::__trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&) mov byte ptr [rip + called], 1 ret std::__2::move_only_function::__trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&): # @std::__2::move_only_function::__trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&) mov byte ptr [rip + called], 1 ret std::__2::move_only_function::__non_trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&): # @std::__2::move_only_function::__non_trivial_vtable_::{lambda(std::__2::__small_buffer<24ul, 8ul>&)#1}::__invoke(std::__2::__small_buffer<24ul, 8ul>&) mov rdi, qword ptr [rdi] mov esi, 40 mov edx, 1 jmp operator
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
@@ -0,0 +1,46 @@ +//===--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H +#define _LIBCPP___FUNCTIONAL_MOVE_ONLY_FUNCTION_COMMON_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class move_only_function; + +template +struct __is_move_only_function : false_type {}; + +template +struct __is_move_only_function> : true_type {}; + +template +struct _MoveOnlyFunctionTrivialVTable { + using _CallFunc = _ReturnT(_BufferT&, _ArgTypes...); + + _CallFunc* __call_; +}; + +template +struct _MoveOnlyFunctionNonTrivialVTable : _MoveOnlyFunctionTrivialVTable<_BufferT, _ReturnT, _ArgTypes...> { philnik777 wrote: The call function pointer is in the base class though. I always want the call pointer and only sometimes the destructor pointer. https://github.com/llvm/llvm-project/pull/94670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
https://github.com/EricWF requested changes to this pull request. Please see the previous comment for the requested changes. https://github.com/llvm/llvm-project/pull/94670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
EricWF wrote: Oh, I just noticed there are no tests for exception safety. Could you please add some throwing types? (Or perhaps I just missed those tests?). Currently this code terminates: ``` #include #include struct ThrowsOnConstruct { explicit ThrowsOnConstruct(int x) : value(x) { if (x == 42) throw 42; } ThrowsOnConstruct(ThrowsOnConstruct const&) = delete; ThrowsOnConstruct(ThrowsOnConstruct && other) : value(other.value) { if (other.value == 101) throw 101; other.value = -1; } ~ThrowsOnConstruct() { assert(value != -1); value = -1; } int operator()() const noexcept { return value; } int value; }; int main() { using MV = std::move_only_function; try { MV f(ThrowsOnConstruct(101)); } catch (...) { } } ``` In particular, I don't think this constructor can be `noexcept`. I also think there are some missing tests for reference_wrapper. https://github.com/llvm/llvm-project/pull/94670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
philnik777 wrote: @EricWF When switching to `__libcpp_operator_{new,delete}` everything gets compiled exactly the same on my system. Could you disclose which test you used for this code? You also claim that the `__pointer_int_pair` causes the optimizer to lose track of the function pointer causing the call to not be elided, but I can't see any calls other than `new` and `delete` in the code you posted either. https://github.com/llvm/llvm-project/pull/94670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2126,14 +2219,16 @@ static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call) { } static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, -PointerAuthOpKind OpKind) { +PointerAuthOpKind OpKind, +bool RequireConstant) { if (S.checkArgCount(Call, 3)) return ExprError(); if (checkPointerAuthEnabled(S, Call)) return ExprError(); - if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind) || + if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind, RequireConstant) || asl wrote: Yes, `checkAndConvertPointerAuthValue` looks better to me as otherwise it is not pretty clear there are side effects. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
@@ -0,0 +1,233 @@ +//===--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +// This header is unguarded on purpose. This header is an implementation detail of move_only_function.h +// and generates multiple versions of std::move_only_function + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/move_only_function_common.h> +#include <__type_traits/is_trivially_destructible.h> +#include <__utility/exchange.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <__utility/pointer_int_pair.h> +#include <__utility/small_buffer.h> +#include <__utility/swap.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_IN_MOVE_ONLY_FUNCTION_H +# error This header should only be included from move_only_function.h +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_CV +# define _LIBCPP_MOVE_ONLY_FUNCTION_CV +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_REF +# define _LIBCPP_MOVE_ONLY_FUNCTION_REF +# define _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS _LIBCPP_MOVE_ONLY_FUNCTION_CV& +#else +# define _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS _LIBCPP_MOVE_ONLY_FUNCTION_CV _LIBCPP_MOVE_ONLY_FUNCTION_REF +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT +# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT false +#endif + +#define _LIBCPP_MOVE_ONLY_FUNCTION_CVREF _LIBCPP_MOVE_ONLY_FUNCTION_CV _LIBCPP_MOVE_ONLY_FUNCTION_REF + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifdef _LIBCPP_ABI_MOVE_ONLY_FUNCTION_TRIVIAL_ABI +# define _LIBCPP_MOVE_ONLY_FUNCTION_TRIVIAL_ABI [[_Clang::__trivial_abi__]] +#else +# define _LIBCPP_MOVE_ONLY_FUNCTION_TRIVIAL_ABI +#endif + +template +class move_only_function; + +template +class _LIBCPP_MOVE_ONLY_FUNCTION_TRIVIAL_ABI move_only_function<_ReturnT( +_ArgTypes...) _LIBCPP_MOVE_ONLY_FUNCTION_CVREF noexcept(_LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT)> { +private: + static constexpr size_t __buffer_size_ = 3 * sizeof(void*); + static constexpr size_t __buffer_alignment_ = alignof(void*); + using _BufferT = __small_buffer<__buffer_size_, __buffer_alignment_>; + + using _TrivialVTable= _MoveOnlyFunctionTrivialVTable<_BufferT, _ReturnT, _ArgTypes...>; + using _NonTrivialVTable = _MoveOnlyFunctionNonTrivialVTable<_BufferT, _ReturnT, _ArgTypes...>; + + template + static constexpr _TrivialVTable __trivial_vtable_ = { + .__call_ = [](_BufferT& __buffer, _ArgTypes... __args) noexcept(_LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT) -> _ReturnT { +return std::invoke_r<_ReturnT>( +static_cast<_Functor _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS>(*__buffer.__get<_Functor>()), +std::forward<_ArgTypes>(__args)...); + }}; + + template + static constexpr _NonTrivialVTable __non_trivial_vtable_{ + __trivial_vtable_<_Functor>, + [](_BufferT& __buffer) noexcept -> void { +std::destroy_at(__buffer.__get<_Functor>()); +__buffer.__dealloc<_Functor>(); + }, + }; + + template + _LIBCPP_HIDE_FROM_ABI __pointer_bool_pair __get_vptr() { +if constexpr (_BufferT::__fits_in_buffer<_Functor> && is_trivially_destructible_v<_Functor>) { + return {&__trivial_vtable_<_Functor>, false}; +} else { + return {&__non_trivial_vtable_<_Functor>, true}; +} + } + + template + static constexpr bool __is_callable_from = [] { +using _DVT = decay_t<_VT>; +if (_LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT) { + return is_nothrow_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_CVREF, _ArgTypes...> && + is_nothrow_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS, _ArgTypes...>; +} else { + return is_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_CVREF, _ArgTypes...> && + is_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS, _ArgTypes...>; +} + }(); + + template + _LIBCPP_HIDE_FROM_ABI void __construct(_Args&&... __args) { +static_assert(is_constructible_v, _Func>); + +using _StoredFunc = decay_t<_Func>; +__vtable_ = __get_vptr<_StoredFunc>(); +__buffer_.__construct<_StoredFunc>(std::forward<_Args>(__args)...); + } + + _LIBCPP_HIDE_FROM_ABI void __reset() { +if (__vtable_.__get_value()) huixie90 wrote: IIUC, I think this is the only place where the `bool` is used. IIUC, the only purpose of the bool is an optimisation that skips the virtual function call for trivially destructible type, I think we can avoid using this bool at all. You can just have a vtable that co
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/94771 This is a follow up patch to #94652 and handles the lowering of the reduce intrinsic with DIM argument and non scalar result. >From fd911977863888c7c005f00ae05049b32fe9d4d6 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 6 Jun 2024 14:17:44 -0700 Subject: [PATCH] [flang] Lower REDUCE intrinsic with DIM argument --- .../Optimizer/Builder/Runtime/Reduction.h | 7 + flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 12 +- .../Optimizer/Builder/Runtime/Reduction.cpp | 186 ++- flang/test/Lower/Intrinsics/reduce.f90| 221 ++ 4 files changed, 423 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h index 27652208b524e..fedf453a6dc8d 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h @@ -240,6 +240,13 @@ mlir::Value genReduce(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value maskBox, mlir::Value identity, mlir::Value ordered); +/// Generate call to `Reduce` intrinsic runtime routine. This is the version +/// that takes arrays of any rank with a dim argument specified. +void genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value arrayBox, mlir::Value operation, mlir::Value dim, + mlir::Value maskBox, mlir::Value identity, + mlir::Value ordered, mlir::Value resultBox); + } // namespace fir::runtime #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_REDUCTION_H diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 0e29849a57688..e250a476b5802 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -5790,7 +5790,17 @@ IntrinsicLibrary::genReduce(mlir::Type resultType, return fir::runtime::genReduce(builder, loc, array, operation, mask, identity, ordered); } - TODO(loc, "reduce with array result"); + // Handle cases that have an array result. + // Create mutable fir.box to be passed to the runtime for the result. + mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, rank - 1); + fir::MutableBoxValue resultMutableBox = + fir::factory::createTempMutableBox(builder, loc, resultArrayType); + mlir::Value resultIrBox = + fir::factory::getMutableIRBox(builder, loc, resultMutableBox); + mlir::Value dim = fir::getBase(args[2]); + fir::runtime::genReduceDim(builder, loc, array, operation, dim, mask, + identity, ordered, resultIrBox); + return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE"); } // REPEAT diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp index a7cd53328d69a..e83af63916dcd 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp @@ -486,6 +486,28 @@ struct ForcedReduceReal16 { } }; +/// Placeholder for DIM real*16 version of Reduce Intrinsic +struct ForcedReduceReal16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceReal16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::FloatType::getF128(ctx); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for integer*16 version of Reduce Intrinsic struct ForcedReduceInteger16 { static constexpr const char *name = @@ -506,6 +528,28 @@ struct ForcedReduceInteger16 { } }; +/// Placeholder for DIM integer*16 version of Reduce Intrinsic +struct ForcedReduceInteger16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceInteger16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::IntegerType::get(ctx, 128); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); +
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
llvmbot wrote: @llvm/pr-subscribers-flang-fir-hlfir Author: Valentin Clement (バレンタイン クレメン) (clementval) Changes This is a follow up patch to #94652 and handles the lowering of the reduce intrinsic with DIM argument and non scalar result. --- Full diff: https://github.com/llvm/llvm-project/pull/94771.diff 4 Files Affected: - (modified) flang/include/flang/Optimizer/Builder/Runtime/Reduction.h (+7) - (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+11-1) - (modified) flang/lib/Optimizer/Builder/Runtime/Reduction.cpp (+184-2) - (modified) flang/test/Lower/Intrinsics/reduce.f90 (+221) ``diff diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h index 27652208b524e..fedf453a6dc8d 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h @@ -240,6 +240,13 @@ mlir::Value genReduce(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value maskBox, mlir::Value identity, mlir::Value ordered); +/// Generate call to `Reduce` intrinsic runtime routine. This is the version +/// that takes arrays of any rank with a dim argument specified. +void genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value arrayBox, mlir::Value operation, mlir::Value dim, + mlir::Value maskBox, mlir::Value identity, + mlir::Value ordered, mlir::Value resultBox); + } // namespace fir::runtime #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_REDUCTION_H diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 0e29849a57688..e250a476b5802 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -5790,7 +5790,17 @@ IntrinsicLibrary::genReduce(mlir::Type resultType, return fir::runtime::genReduce(builder, loc, array, operation, mask, identity, ordered); } - TODO(loc, "reduce with array result"); + // Handle cases that have an array result. + // Create mutable fir.box to be passed to the runtime for the result. + mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, rank - 1); + fir::MutableBoxValue resultMutableBox = + fir::factory::createTempMutableBox(builder, loc, resultArrayType); + mlir::Value resultIrBox = + fir::factory::getMutableIRBox(builder, loc, resultMutableBox); + mlir::Value dim = fir::getBase(args[2]); + fir::runtime::genReduceDim(builder, loc, array, operation, dim, mask, + identity, ordered, resultIrBox); + return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE"); } // REPEAT diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp index a7cd53328d69a..e83af63916dcd 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp @@ -486,6 +486,28 @@ struct ForcedReduceReal16 { } }; +/// Placeholder for DIM real*16 version of Reduce Intrinsic +struct ForcedReduceReal16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceReal16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::FloatType::getF128(ctx); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for integer*16 version of Reduce Intrinsic struct ForcedReduceInteger16 { static constexpr const char *name = @@ -506,6 +528,28 @@ struct ForcedReduceInteger16 { } }; +/// Placeholder for DIM integer*16 version of Reduce Intrinsic +struct ForcedReduceInteger16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceInteger16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::IntegerType::get(ctx, 128); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(b
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
@@ -527,10 +571,32 @@ struct ForcedReduceComplex10 { } }; +/// Placeholder for Dim complex(10) version of Reduce Intrinsic +struct ForcedReduceComplex10Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(CppReduceComplex10Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx)); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for complex(16) version of Reduce Intrinsic struct ForcedReduceComplex16 { static constexpr const char *name = - ExpandAndQuoteKey(RTNAME(CppReduceComplex16)); + ExpandAndQuoteKey(RTNAME(CppReduceComplex16Dim)); vzakhari wrote: Is this change intended? https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
@@ -527,10 +571,32 @@ struct ForcedReduceComplex10 { } }; +/// Placeholder for Dim complex(10) version of Reduce Intrinsic +struct ForcedReduceComplex10Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(CppReduceComplex10Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx)); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for complex(16) version of Reduce Intrinsic struct ForcedReduceComplex16 { static constexpr const char *name = - ExpandAndQuoteKey(RTNAME(CppReduceComplex16)); + ExpandAndQuoteKey(RTNAME(CppReduceComplex16Dim)); clementval wrote: No bad change! Thanks for catching it! https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
@@ -527,10 +571,32 @@ struct ForcedReduceComplex10 { } }; +/// Placeholder for Dim complex(10) version of Reduce Intrinsic +struct ForcedReduceComplex10Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(CppReduceComplex10Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx)); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for complex(16) version of Reduce Intrinsic struct ForcedReduceComplex16 { static constexpr const char *name = - ExpandAndQuoteKey(RTNAME(CppReduceComplex16)); + ExpandAndQuoteKey(RTNAME(CppReduceComplex16Dim)); clementval wrote: ```suggestion ExpandAndQuoteKey(RTNAME(CppReduceComplex16)); ``` https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?Message-ID: In-Reply-To: https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/94771 >From fd911977863888c7c005f00ae05049b32fe9d4d6 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 6 Jun 2024 14:17:44 -0700 Subject: [PATCH 1/2] [flang] Lower REDUCE intrinsic with DIM argument --- .../Optimizer/Builder/Runtime/Reduction.h | 7 + flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 12 +- .../Optimizer/Builder/Runtime/Reduction.cpp | 186 ++- flang/test/Lower/Intrinsics/reduce.f90| 221 ++ 4 files changed, 423 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h index 27652208b524e..fedf453a6dc8d 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h @@ -240,6 +240,13 @@ mlir::Value genReduce(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value maskBox, mlir::Value identity, mlir::Value ordered); +/// Generate call to `Reduce` intrinsic runtime routine. This is the version +/// that takes arrays of any rank with a dim argument specified. +void genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value arrayBox, mlir::Value operation, mlir::Value dim, + mlir::Value maskBox, mlir::Value identity, + mlir::Value ordered, mlir::Value resultBox); + } // namespace fir::runtime #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_REDUCTION_H diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 0e29849a57688..e250a476b5802 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -5790,7 +5790,17 @@ IntrinsicLibrary::genReduce(mlir::Type resultType, return fir::runtime::genReduce(builder, loc, array, operation, mask, identity, ordered); } - TODO(loc, "reduce with array result"); + // Handle cases that have an array result. + // Create mutable fir.box to be passed to the runtime for the result. + mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, rank - 1); + fir::MutableBoxValue resultMutableBox = + fir::factory::createTempMutableBox(builder, loc, resultArrayType); + mlir::Value resultIrBox = + fir::factory::getMutableIRBox(builder, loc, resultMutableBox); + mlir::Value dim = fir::getBase(args[2]); + fir::runtime::genReduceDim(builder, loc, array, operation, dim, mask, + identity, ordered, resultIrBox); + return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE"); } // REPEAT diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp index a7cd53328d69a..e83af63916dcd 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp @@ -486,6 +486,28 @@ struct ForcedReduceReal16 { } }; +/// Placeholder for DIM real*16 version of Reduce Intrinsic +struct ForcedReduceReal16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceReal16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::FloatType::getF128(ctx); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for integer*16 version of Reduce Intrinsic struct ForcedReduceInteger16 { static constexpr const char *name = @@ -506,6 +528,28 @@ struct ForcedReduceInteger16 { } }; +/// Placeholder for DIM integer*16 version of Reduce Intrinsic +struct ForcedReduceInteger16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceInteger16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::IntegerType::get(ctx, 128); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + aut
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -1261,6 +1262,10 @@ class ASTContext : public RefCountedBase { /// space. QualType removeAddrSpaceQualType(QualType T) const; + /// Return the "other" type-specific discriminator for the given type. ojhunt wrote: @asl thoughts? https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -1261,6 +1262,10 @@ class ASTContext : public RefCountedBase { /// space. QualType removeAddrSpaceQualType(QualType T) const; + /// Return the "other" type-specific discriminator for the given type. ojhunt wrote: How would `/// Return the "other" discriminator used for the pointer auth schema used for vtable pointers in instances of the requested type` sound? it's more explicit about what is being produced https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -1261,6 +1262,10 @@ class ASTContext : public RefCountedBase { /// space. QualType removeAddrSpaceQualType(QualType T) const; + /// Return the "other" type-specific discriminator for the given type. asl wrote: @ojhunt This looks much better, thanks! https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw==?= Message-ID: In-Reply-To: @@ -540,9 +606,31 @@ struct ForcedReduceComplex16 { auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); vzakhari wrote: Then, I guess, this should not be needed as well :) https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?Message-ID: In-Reply-To: @@ -540,9 +606,31 @@ struct ForcedReduceComplex16 { auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); clementval wrote: This is needed because it was actually not tested in the previous patch. I can move this change to the other patch since it's not merged yet. https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?Message-ID: In-Reply-To: @@ -540,9 +606,31 @@ struct ForcedReduceComplex16 { auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); vzakhari wrote: Hmm, I must be missing something. The runtime API is defined as: ``` void RTDEF(CppReduceComplex16)(std::complex &result, const Descriptor &array, ReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const std::complex *identity, bool ordered) { ``` So the first argument should be a reference to a complex value, isn't it right? https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?Message-ID: In-Reply-To: @@ -540,9 +606,31 @@ struct ForcedReduceComplex16 { auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); auto i1Ty = mlir::IntegerType::get(ctx, 1); return mlir::FunctionType::get( - ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + +/// Placeholder for Dim complex(16) version of Reduce Intrinsic +struct ForcedReduceComplex16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(CppReduceComplex16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx)); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {boxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, vzakhari wrote: The first argument is a box reference here but not in the non-dim case. https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?Message-ID: In-Reply-To: @@ -540,9 +606,31 @@ struct ForcedReduceComplex16 { auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); auto i1Ty = mlir::IntegerType::get(ctx, 1); return mlir::FunctionType::get( - ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + +/// Placeholder for Dim complex(16) version of Reduce Intrinsic +struct ForcedReduceComplex16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(CppReduceComplex16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx)); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {boxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, clementval wrote: Let me double check that. I have probably messade up smth here https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
https://github.com/huixie90 edited https://github.com/llvm/llvm-project/pull/94670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Implement std::move_only_function (P0288R9) (PR #94670)
@@ -0,0 +1,233 @@ +//===--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +// This header is unguarded on purpose. This header is an implementation detail of move_only_function.h +// and generates multiple versions of std::move_only_function + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/move_only_function_common.h> +#include <__type_traits/is_trivially_destructible.h> +#include <__utility/exchange.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <__utility/pointer_int_pair.h> +#include <__utility/small_buffer.h> +#include <__utility/swap.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_IN_MOVE_ONLY_FUNCTION_H +# error This header should only be included from move_only_function.h +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_CV +# define _LIBCPP_MOVE_ONLY_FUNCTION_CV +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_REF +# define _LIBCPP_MOVE_ONLY_FUNCTION_REF +# define _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS _LIBCPP_MOVE_ONLY_FUNCTION_CV& +#else +# define _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS _LIBCPP_MOVE_ONLY_FUNCTION_CV _LIBCPP_MOVE_ONLY_FUNCTION_REF +#endif + +#ifndef _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT +# define _LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT false +#endif + +#define _LIBCPP_MOVE_ONLY_FUNCTION_CVREF _LIBCPP_MOVE_ONLY_FUNCTION_CV _LIBCPP_MOVE_ONLY_FUNCTION_REF + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifdef _LIBCPP_ABI_MOVE_ONLY_FUNCTION_TRIVIAL_ABI +# define _LIBCPP_MOVE_ONLY_FUNCTION_TRIVIAL_ABI [[_Clang::__trivial_abi__]] +#else +# define _LIBCPP_MOVE_ONLY_FUNCTION_TRIVIAL_ABI +#endif + +template +class move_only_function; + +template +class _LIBCPP_MOVE_ONLY_FUNCTION_TRIVIAL_ABI move_only_function<_ReturnT( +_ArgTypes...) _LIBCPP_MOVE_ONLY_FUNCTION_CVREF noexcept(_LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT)> { +private: + static constexpr size_t __buffer_size_ = 3 * sizeof(void*); + static constexpr size_t __buffer_alignment_ = alignof(void*); + using _BufferT = __small_buffer<__buffer_size_, __buffer_alignment_>; + + using _TrivialVTable= _MoveOnlyFunctionTrivialVTable<_BufferT, _ReturnT, _ArgTypes...>; + using _NonTrivialVTable = _MoveOnlyFunctionNonTrivialVTable<_BufferT, _ReturnT, _ArgTypes...>; + + template + static constexpr _TrivialVTable __trivial_vtable_ = { + .__call_ = [](_BufferT& __buffer, _ArgTypes... __args) noexcept(_LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT) -> _ReturnT { +return std::invoke_r<_ReturnT>( +static_cast<_Functor _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS>(*__buffer.__get<_Functor>()), +std::forward<_ArgTypes>(__args)...); + }}; + + template + static constexpr _NonTrivialVTable __non_trivial_vtable_{ + __trivial_vtable_<_Functor>, + [](_BufferT& __buffer) noexcept -> void { +std::destroy_at(__buffer.__get<_Functor>()); +__buffer.__dealloc<_Functor>(); + }, + }; + + template + _LIBCPP_HIDE_FROM_ABI __pointer_bool_pair __get_vptr() { +if constexpr (_BufferT::__fits_in_buffer<_Functor> && is_trivially_destructible_v<_Functor>) { + return {&__trivial_vtable_<_Functor>, false}; +} else { + return {&__non_trivial_vtable_<_Functor>, true}; +} + } + + template + static constexpr bool __is_callable_from = [] { +using _DVT = decay_t<_VT>; +if (_LIBCPP_MOVE_ONLY_FUNCTION_NOEXCEPT) { + return is_nothrow_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_CVREF, _ArgTypes...> && + is_nothrow_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS, _ArgTypes...>; +} else { + return is_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_CVREF, _ArgTypes...> && + is_invocable_r_v<_ReturnT, _DVT _LIBCPP_MOVE_ONLY_FUNCTION_INVOKE_QUALS, _ArgTypes...>; +} + }(); + + template + _LIBCPP_HIDE_FROM_ABI void __construct(_Args&&... __args) { +static_assert(is_constructible_v, _Func>); + +using _StoredFunc = decay_t<_Func>; +__vtable_ = __get_vptr<_StoredFunc>(); +__buffer_.__construct<_StoredFunc>(std::forward<_Args>(__args)...); + } + + _LIBCPP_HIDE_FROM_ABI void __reset() { +if (__vtable_.__get_value()) philnik777 wrote: The `bool` is in the low bit of the pointer to avoid the need to even look at the vtable in the destructor. The cost of zeroing the lower bits of the pointer is pretty much non-existent on modern platforms (the delay is at most a single cycle - most likely not even
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
ojhunt wrote: Had to do a force push to resolve merge conflicts following @ahatanak's PR, so this change now includes `CodeGenFunction::EmitPointerAuthAuth` etc https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?Message-ID: In-Reply-To: @@ -540,9 +606,31 @@ struct ForcedReduceComplex16 { auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); clementval wrote: Yes you are right. I messed up the this one with the DIM version. I'll revert it back. https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?=,Valentin Clement Message-ID: In-Reply-To: https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/94771 >From fd911977863888c7c005f00ae05049b32fe9d4d6 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 6 Jun 2024 14:17:44 -0700 Subject: [PATCH 1/3] [flang] Lower REDUCE intrinsic with DIM argument --- .../Optimizer/Builder/Runtime/Reduction.h | 7 + flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 12 +- .../Optimizer/Builder/Runtime/Reduction.cpp | 186 ++- flang/test/Lower/Intrinsics/reduce.f90| 221 ++ 4 files changed, 423 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h index 27652208b524e..fedf453a6dc8d 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h @@ -240,6 +240,13 @@ mlir::Value genReduce(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value maskBox, mlir::Value identity, mlir::Value ordered); +/// Generate call to `Reduce` intrinsic runtime routine. This is the version +/// that takes arrays of any rank with a dim argument specified. +void genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value arrayBox, mlir::Value operation, mlir::Value dim, + mlir::Value maskBox, mlir::Value identity, + mlir::Value ordered, mlir::Value resultBox); + } // namespace fir::runtime #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_REDUCTION_H diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 0e29849a57688..e250a476b5802 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -5790,7 +5790,17 @@ IntrinsicLibrary::genReduce(mlir::Type resultType, return fir::runtime::genReduce(builder, loc, array, operation, mask, identity, ordered); } - TODO(loc, "reduce with array result"); + // Handle cases that have an array result. + // Create mutable fir.box to be passed to the runtime for the result. + mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, rank - 1); + fir::MutableBoxValue resultMutableBox = + fir::factory::createTempMutableBox(builder, loc, resultArrayType); + mlir::Value resultIrBox = + fir::factory::getMutableIRBox(builder, loc, resultMutableBox); + mlir::Value dim = fir::getBase(args[2]); + fir::runtime::genReduceDim(builder, loc, array, operation, dim, mask, + identity, ordered, resultIrBox); + return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE"); } // REPEAT diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp index a7cd53328d69a..e83af63916dcd 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp @@ -486,6 +486,28 @@ struct ForcedReduceReal16 { } }; +/// Placeholder for DIM real*16 version of Reduce Intrinsic +struct ForcedReduceReal16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceReal16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::FloatType::getF128(ctx); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for integer*16 version of Reduce Intrinsic struct ForcedReduceInteger16 { static constexpr const char *name = @@ -506,6 +528,28 @@ struct ForcedReduceInteger16 { } }; +/// Placeholder for DIM integer*16 version of Reduce Intrinsic +struct ForcedReduceInteger16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceInteger16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::IntegerType::get(ctx, 128); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?=,Valentin Clement Message-ID: In-Reply-To: clementval wrote: Thanks Slava and Jean for the review! I fixed the mismatch in `ForcedReduceComplex16` and `ForcedReduceComplex16Dim`. Thanks Slava for catching that. https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw==?=,Valentin Clement Message-ID: In-Reply-To: https://github.com/vzakhari approved this pull request. Thank you, Valentin! https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw==?=,Valentin Clement Message-ID: In-Reply-To: https://github.com/jeanPerier approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?=,Valentin Clement Message-ID: In-Reply-To: jeanPerier wrote: Beware that the windows failure seems related to this change or the previous one: ``` C:\ws\src\flang\lib\Optimizer\Builder\Runtime\Reduction.cpp(1499): error C2065: '_FortranAReduceReal10': undeclared identifier ``` I think you need "Forced" definition for the REAL*10 too. https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?=,Valentin Clement Message-ID: In-Reply-To: clementval wrote: > Beware that the windows failure seems related to this change or the previous > one: > > ``` > > C:\ws\src\flang\lib\Optimizer\Builder\Runtime\Reduction.cpp(1499): error > C2065: '_FortranAReduceReal10': undeclared identifier > > ``` > > > > I think you need "Forced" definition for the REAL*10 too. I'll look at that! Thanks https://github.com/llvm/llvm-project/pull/94771 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; ahatanak wrote: I don't think it makes any difference on macOS or Linux, but mixing bool bitfields and unsigned bitfields can increase the size of the struct on Windows (see https://learn.microsoft.com/en-us/cpp/c-language/storage-and-alignment-of-structures?view=msvc-170). The underlying types of the enums used here are all unsigned. I guess we should use `unsigned` as the underlying type of bitfields in `class CGPointerAuthInfo` too. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang] Lower REDUCE intrinsic with DIM argument (PR #94771)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?=,Valentin Clement ,Valentin Clement Message-ID: In-Reply-To: https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/94771 >From fd911977863888c7c005f00ae05049b32fe9d4d6 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 6 Jun 2024 14:17:44 -0700 Subject: [PATCH 1/4] [flang] Lower REDUCE intrinsic with DIM argument --- .../Optimizer/Builder/Runtime/Reduction.h | 7 + flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 12 +- .../Optimizer/Builder/Runtime/Reduction.cpp | 186 ++- flang/test/Lower/Intrinsics/reduce.f90| 221 ++ 4 files changed, 423 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h index 27652208b524e..fedf453a6dc8d 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h @@ -240,6 +240,13 @@ mlir::Value genReduce(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value maskBox, mlir::Value identity, mlir::Value ordered); +/// Generate call to `Reduce` intrinsic runtime routine. This is the version +/// that takes arrays of any rank with a dim argument specified. +void genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value arrayBox, mlir::Value operation, mlir::Value dim, + mlir::Value maskBox, mlir::Value identity, + mlir::Value ordered, mlir::Value resultBox); + } // namespace fir::runtime #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_REDUCTION_H diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 0e29849a57688..e250a476b5802 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -5790,7 +5790,17 @@ IntrinsicLibrary::genReduce(mlir::Type resultType, return fir::runtime::genReduce(builder, loc, array, operation, mask, identity, ordered); } - TODO(loc, "reduce with array result"); + // Handle cases that have an array result. + // Create mutable fir.box to be passed to the runtime for the result. + mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, rank - 1); + fir::MutableBoxValue resultMutableBox = + fir::factory::createTempMutableBox(builder, loc, resultArrayType); + mlir::Value resultIrBox = + fir::factory::getMutableIRBox(builder, loc, resultMutableBox); + mlir::Value dim = fir::getBase(args[2]); + fir::runtime::genReduceDim(builder, loc, array, operation, dim, mask, + identity, ordered, resultIrBox); + return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE"); } // REPEAT diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp index a7cd53328d69a..e83af63916dcd 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp @@ -486,6 +486,28 @@ struct ForcedReduceReal16 { } }; +/// Placeholder for DIM real*16 version of Reduce Intrinsic +struct ForcedReduceReal16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceReal16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::FloatType::getF128(ctx); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy = fir::ReferenceType::get(ty); + auto refBoxTy = fir::ReferenceType::get(boxTy); + auto i1Ty = mlir::IntegerType::get(ctx, 1); + return mlir::FunctionType::get( + ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, + {}); +}; + } +}; + /// Placeholder for integer*16 version of Reduce Intrinsic struct ForcedReduceInteger16 { static constexpr const char *name = @@ -506,6 +528,28 @@ struct ForcedReduceInteger16 { } }; +/// Placeholder for DIM integer*16 version of Reduce Intrinsic +struct ForcedReduceInteger16Dim { + static constexpr const char *name = + ExpandAndQuoteKey(RTNAME(ReduceInteger16Dim)); + static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() { +return [](mlir::MLIRContext *ctx) { + auto ty = mlir::IntegerType::get(ctx, 128); + auto boxTy = + fir::runtime::getModel()(ctx); + auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, ty); + auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8)); + auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int)); + auto refTy =
[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16-bit ptrauth stable hash. (PR #93902)
https://github.com/asl approved this pull request. https://github.com/llvm/llvm-project/pull/93902 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)
asl wrote: So, regarding big-endian things. Original siphash is always "little-endian" regardless of the host platform. On big endian hosts it essentially does byte swap in the end. We do not have it here, so we will end with different hashes on platforms with different endianness. >From the pauth perspective this is not a problem, as we do not do >cross-platform hash calculation and further comparison. The hash output >(discriminator value) is always compiled on compiler side and left as-is. So, we can either keep the present code as-is. Or we can just sprinkle few calls from `Endian.h` to do byteswap on BE platforms. https://github.com/llvm/llvm-project/pull/94394 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -15,6 +15,29 @@ typedef enum { ptrauth_key_asib = 1, ptrauth_key_asda = 2, ptrauth_key_asdb = 3, + +#ifdef __APPLE__ asl wrote: Looks like this is something from already merged commit. Worth rebasing? https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] acb7210 - Revert "[lld][AArch64][ELF][PAC] Support `.relr.auth.dyn` section (#87635)"
Author: Daniil Kovalev Date: 2024-06-08T09:21:11+03:00 New Revision: acb7210fdeaf3ddf80e28cfc0e1faefc939478cf URL: https://github.com/llvm/llvm-project/commit/acb7210fdeaf3ddf80e28cfc0e1faefc939478cf DIFF: https://github.com/llvm/llvm-project/commit/acb7210fdeaf3ddf80e28cfc0e1faefc939478cf.diff LOG: Revert "[lld][AArch64][ELF][PAC] Support `.relr.auth.dyn` section (#87635)" This reverts commit ca1f0d41b8c5f42ca6cdcbdf9732bf4df2fcc80f. Added: Modified: lld/ELF/Arch/AArch64.cpp lld/ELF/Relocations.cpp lld/ELF/SyntheticSections.cpp lld/ELF/SyntheticSections.h lld/ELF/Writer.cpp lld/test/ELF/aarch64-reloc-pauth.s Removed: diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index cf5c2380690f1..47e6ea1ff7756 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -429,19 +429,6 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, case R_AARCH64_PREL64: write64(loc, val); break; - case R_AARCH64_AUTH_ABS64: -// If val is wider than 32 bits, the relocation must have been moved from -// .relr.auth.dyn to .rela.dyn, and the addend write is not needed. -// -// If val fits in 32 bits, we have two potential scenarios: -// * True RELR: Write the 32-bit `val`. -// * RELA: Even if the value now fits in 32 bits, it might have been -// converted from RELR during an iteration in -// finalizeAddressDependentContent(). Writing the value is harmless -// because dynamic linking ignores it. -if (isInt<32>(val)) - write32(loc, val); -break; case R_AARCH64_ADD_ABS_LO12_NC: or32AArch64Imm(loc, val); break; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 2c02c2e572bfd..04db413a6609f 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -898,9 +898,9 @@ static void addRelativeReloc(InputSectionBase &isec, uint64_t offsetInSec, isec.addReloc({expr, type, offsetInSec, addend, &sym}); if (shard) part.relrDyn->relocsVec[parallel::getThreadIndex()].push_back( - {&isec, isec.relocs().size() - 1}); + {&isec, offsetInSec}); else - part.relrDyn->relocs.push_back({&isec, isec.relocs().size() - 1}); + part.relrDyn->relocs.push_back({&isec, offsetInSec}); return; } part.relaDyn->addRelativeReloc(target->relativeRel, isec, offsetInSec, @@ -1154,12 +1154,6 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset, // relative relocation. Use a symbolic relocation instead. if (sym.isPreemptible) { part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type); -} else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0) { - // When symbol values are determined in - // finalizeAddressDependentContent, some .relr.auth.dyn relocations - // may be moved to .rela.dyn. - sec->addReloc({expr, type, offset, addend, &sym}); - part.relrAuthDyn->relocs.push_back({sec, sec->relocs().size() - 1}); } else { part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset, DynamicReloc::AddendOnlyWithTargetVA, sym, diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index ad280289cebf9..cc423d152e912 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1420,12 +1420,6 @@ DynamicSection::computeContents() { addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT, sizeof(Elf_Relr)); } - if (part.relrAuthDyn && part.relrAuthDyn->getParent() && - !part.relrAuthDyn->relocs.empty()) { -addInSec(DT_AARCH64_AUTH_RELR, *part.relrAuthDyn); -addInt(DT_AARCH64_AUTH_RELRSZ, part.relrAuthDyn->getParent()->size); -addInt(DT_AARCH64_AUTH_RELRENT, sizeof(Elf_Relr)); - } if (isMain && in.relaPlt->isNeeded()) { addInSec(DT_JMPREL, *in.relaPlt); entries.emplace_back(DT_PLTRELSZ, addPltRelSz()); @@ -1737,13 +1731,10 @@ template void RelocationSection::writeTo(uint8_t *buf) { } } -RelrBaseSection::RelrBaseSection(unsigned concurrency, bool isAArch64Auth) -: SyntheticSection( - SHF_ALLOC, - isAArch64Auth - ? SHT_AARCH64_AUTH_RELR - : (config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR), - config->wordsize, isAArch64Auth ? ".relr.auth.dyn" : ".relr.dyn"), +RelrBaseSection::RelrBaseSection(unsigned concurrency) +: SyntheticSection(SHF_ALLOC, + config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR, + config->wordsize, ".relr.dyn"), relocsVec(concurrency) {} void RelrBaseSection::mergeRels() { @@ -2011,8 +2002,8 @@ bool AndroidPackedRelocationSection::updateAllocSize() { } template -RelrSection::RelrSection(unsigned con
[llvm-branch-commits] [clang] [llvm] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -47,6 +47,17 @@ void test_blend_discriminator(int *dp, int (*fp)(int), int value) { float *mismatch = __builtin_ptrauth_blend_discriminator(dp, value); // expected-error {{incompatible integer to pointer conversion initializing 'float *' with an expression of type}} } +void test_string_discriminator(const char *str) { + __builtin_ptrauth_string_discriminator(); // expected-error {{too few arguments}} + __builtin_ptrauth_string_discriminator(str, str); // expected-error {{too many arguments}} + (void) __builtin_ptrauth_string_discriminator("test string"); // no warning asl wrote: Can we have `:"test string"` case here as well? As we're checking on the width of the literal character? https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
https://github.com/asl edited https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -162,20 +162,27 @@ struct ThunkInfo { /// Holds a pointer to the overridden method this thunk is for, /// if needed by the ABI to distinguish different thunks with equal - /// adjustments. Otherwise, null. + /// adjustments. + /// In the Itanium ABI, this field can hold the method that created the + /// vtable entry for this thunk. + /// Otherwise, null. /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using /// an ABI-specific comparator. const CXXMethodDecl *Method; + const Type *ThisType { nullptr }; ThunkInfo() : Method(nullptr) {} ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return, +const Type *thisType, asl wrote: nit: consistent naming of parameters https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -3088,6 +3089,17 @@ QualType ASTContext::removeAddrSpaceQualType(QualType T) const { return QualType(TypeNode, Quals.getFastQualifiers()); } +uint16_t ASTContext::getPointerAuthVTablePointerDiscriminator( +const CXXRecordDecl *record) { + assert(record->isPolymorphic() && + "Attempted to get vtable pointer discriminator on a monomorphic type"); + std::unique_ptr MC(createMangleContext()); + SmallString<256> Str; + llvm::raw_svector_ostream Out(Str); + MC->mangleCXXVTable(record, Out); + return llvm::getPointerAuthStableSipHash16(Str.c_str()); asl wrote: ```suggestion return llvm::getPointerAuthStableSipHash16(Str.str()); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -7037,8 +7036,64 @@ void ItaniumMangleContextImpl::mangleCXXDtorComdat(const CXXDestructorDecl *D, Mangler.mangle(GlobalDecl(D, Dtor_Comdat)); } +static void mangleOverrideDiscrimination(CXXNameMangler &mangler, + ASTContext &context, + const ThunkInfo &thunk) { + auto &langOpts = context.getLangOpts(); + auto thisType = thunk.ThisType; + auto thisRecord = thisType->getPointeeCXXRecordDecl(); + auto ptrauthClassRecord = context.baseForVTableAuthentication(thisRecord); + unsigned typedDiscriminator = + context.getPointerAuthVTablePointerDiscriminator(thisRecord); + mangler.mangleVendorQualifier("__vtptrauth"); + auto &manglerStream = mangler.getStream(); + manglerStream << "I"; + if (auto explicitAuth = + ptrauthClassRecord->getAttr()) { +manglerStream << "Lj" << explicitAuth->getKey(); asl wrote: Do we have mangling bits documented somewhere? https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -7064,21 +7119,29 @@ void ItaniumMangleContextImpl::mangleThunk(const CXXMethodDecl *MD, Thunk.Return.Virtual.Itanium.VBaseOffsetOffset); Mangler.mangleFunctionEncoding(MD); + if (!elideOverrideInfo) { +mangleOverrideDiscrimination(Mangler, getASTContext(), Thunk); + } } -void ItaniumMangleContextImpl::mangleCXXDtorThunk( -const CXXDestructorDecl *DD, CXXDtorType Type, -const ThisAdjustment &ThisAdjustment, raw_ostream &Out) { +void ItaniumMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD, + CXXDtorType Type, + const ThunkInfo &Thunk, + bool elideOverrideInfo, + raw_ostream &Out) { // ::= T // # base is the nominal target function of thunk CXXNameMangler Mangler(*this, Out, DD, Type); Mangler.getStream() << "_ZT"; + auto &ThisAdjustment = Thunk.This; // Mangle the 'this' pointer adjustment. Mangler.mangleCallOffset(ThisAdjustment.NonVirtual, ThisAdjustment.Virtual.Itanium.VCallOffsetOffset); Mangler.mangleFunctionEncoding(GlobalDecl(DD, Type)); + if (!elideOverrideInfo) asl wrote: update comment above with mangling scheme description? https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
https://github.com/asl edited https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -3094,9 +3188,10 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, ReturnAdjustmentOffset.VirtualBase); } } - +auto thisType = (OverriddenMD ? OverriddenMD : MD)->getThisType().getTypePtr(); asl wrote: ```suggestion auto ThisType = (OverriddenMD ? OverriddenMD : MD)->getThisType().getTypePtr(); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -3094,9 +3188,10 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, ReturnAdjustmentOffset.VirtualBase); } } - +auto thisType = (OverriddenMD ? OverriddenMD : MD)->getThisType().getTypePtr(); AddMethod(FinalOverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment, +thisType, asl wrote: ```suggestion ThisType, ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -2588,6 +2588,12 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { // the same addr space. Note that this might not be LLVM address space 0. VTableField = VTableField.withElementType(PtrTy); + if (auto authenticationInfo = CGM.getVTablePointerAuthInfo( asl wrote: ```suggestion if (auto AuthenticationInfo = CGM.getVTablePointerAuthInfo( ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
https://github.com/asl edited https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -2588,6 +2588,12 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { // the same addr space. Note that this might not be LLVM address space 0. VTableField = VTableField.withElementType(PtrTy); + if (auto authenticationInfo = CGM.getVTablePointerAuthInfo( + this, Vptr.Base.getBase(), VTableField.emitRawPointer(*this))) { +VTableAddressPoint = +EmitPointerAuthSign(*authenticationInfo, VTableAddressPoint); asl wrote: ```suggestion EmitPointerAuthSign(*AuthenticationInfo, VTableAddressPoint); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -2681,12 +2687,35 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { llvm::Value *CodeGenFunction::GetVTablePtr(Address This, llvm::Type *VTableTy, - const CXXRecordDecl *RD) { + const CXXRecordDecl *RD, + VTableAuthMode authMode) { Address VTablePtrSrc = This.withElementType(VTableTy); llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); + if (auto authenticationInfo = asl wrote: ```suggestion if (auto *AuthenticationInfo = ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -2681,12 +2687,35 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { llvm::Value *CodeGenFunction::GetVTablePtr(Address This, llvm::Type *VTableTy, - const CXXRecordDecl *RD) { + const CXXRecordDecl *RD, + VTableAuthMode authMode) { asl wrote: ```suggestion VTableAuthMode AuthMode) { ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -2681,12 +2687,35 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { llvm::Value *CodeGenFunction::GetVTablePtr(Address This, llvm::Type *VTableTy, - const CXXRecordDecl *RD) { + const CXXRecordDecl *RD, + VTableAuthMode authMode) { Address VTablePtrSrc = This.withElementType(VTableTy); llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); + if (auto authenticationInfo = +CGM.getVTablePointerAuthInfo(this, RD, This.emitRawPointer(*this))) { +if (authMode != VTableAuthMode::UnsafeUbsanStrip) { asl wrote: ```suggestion if (AuthMode != VTableAuthMode::UnsafeUbsanStrip) { ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -2681,12 +2687,35 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { llvm::Value *CodeGenFunction::GetVTablePtr(Address This, llvm::Type *VTableTy, - const CXXRecordDecl *RD) { + const CXXRecordDecl *RD, + VTableAuthMode authMode) { Address VTablePtrSrc = This.withElementType(VTableTy); llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); + if (auto authenticationInfo = +CGM.getVTablePointerAuthInfo(this, RD, This.emitRawPointer(*this))) { +if (authMode != VTableAuthMode::UnsafeUbsanStrip) { + VTable = cast( + EmitPointerAuthAuth(*authenticationInfo, VTable)); asl wrote: ```suggestion EmitPointerAuthAuth(*AuthenticationInfo, VTable)); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -2681,12 +2687,35 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { llvm::Value *CodeGenFunction::GetVTablePtr(Address This, llvm::Type *VTableTy, - const CXXRecordDecl *RD) { + const CXXRecordDecl *RD, + VTableAuthMode authMode) { Address VTablePtrSrc = This.withElementType(VTableTy); llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); + if (auto authenticationInfo = +CGM.getVTablePointerAuthInfo(this, RD, This.emitRawPointer(*this))) { +if (authMode != VTableAuthMode::UnsafeUbsanStrip) { + VTable = cast( + EmitPointerAuthAuth(*authenticationInfo, VTable)); + if (authMode == VTableAuthMode::MustTrap) { asl wrote: ```suggestion if (AuthMode == VTableAuthMode::MustTrap) { ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -803,6 +803,14 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, llvm::Constant *VTableAddressPoint = CGM.getCXXABI().getVTableAddressPoint(BaseSubobject(CD, Offset), VTableClass); + if (auto authentication = asl wrote: ```suggestion if (auto *Authentication = ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -803,6 +803,14 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, llvm::Constant *VTableAddressPoint = CGM.getCXXABI().getVTableAddressPoint(BaseSubobject(CD, Offset), VTableClass); + if (auto authentication = + CGM.getVTablePointerAuthentication(VTableClass)) { +VTableAddressPoint = Emitter.tryEmitConstantSignedPointer( +VTableAddressPoint, *authentication); asl wrote: ```suggestion VTableAddressPoint, *Authentication); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -23,11 +23,53 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/IR/ValueMap.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Support/SipHash.h" #include using namespace clang; using namespace CodeGen; +/// Given a pointer-authentication schema, return a concrete "other" +/// discriminator for it. +llvm::Constant *CodeGenModule::getPointerAuthOtherDiscriminator( asl wrote: It would be great to have consistent code style for variable names in this file. https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; kovdan01 wrote: > I guess we should use `unsigned` as the underlying type of bitfields in > `class CGPointerAuthInfo` too. This works for me, thanks https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -90,6 +90,11 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr( VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange); + if (auto &schema = asl wrote: ```suggestion if (auto &Schema = ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -90,6 +90,11 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr( VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange); + if (auto &schema = + CGM.getCodeGenOpts().PointerAuth.CXXVTTVTablePointers) + Init = CGM.getConstantSignedPointer(Init, schema, nullptr, GlobalDecl(), asl wrote: ```suggestion Init = CGM.getConstantSignedPointer(Init, Schema, nullptr, GlobalDecl(), ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -219,8 +219,10 @@ CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn, "Store of this should be in entry block?"); // Adjust "this", if necessary. Builder.SetInsertPoint(&*ThisStore); - llvm::Value *AdjustedThisPtr = - CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This); + + const CXXRecordDecl *thisValueClass = Thunk.ThisType->getPointeeCXXRecordDecl(); asl wrote: ```suggestion const CXXRecordDecl *ThisValueClass = Thunk.ThisType->getPointeeCXXRecordDecl(); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -219,8 +219,10 @@ CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn, "Store of this should be in entry block?"); // Adjust "this", if necessary. Builder.SetInsertPoint(&*ThisStore); - llvm::Value *AdjustedThisPtr = - CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This); + + const CXXRecordDecl *thisValueClass = Thunk.ThisType->getPointeeCXXRecordDecl(); + llvm::Value *AdjustedThisPtr = CGM.getCXXABI().performThisAdjustment( + *this, ThisPtr, thisValueClass, Thunk); asl wrote: ```suggestion *this, ThisPtr, ThisValueClass, Thunk); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -307,10 +309,15 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const CXXMethodDecl *MD = cast(CurGD.getDecl()); // Adjust the 'this' pointer if necessary + const CXXRecordDecl *thisValueClass = asl wrote: ```suggestion const CXXRecordDecl *ThisValueClass = ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -307,10 +309,15 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const CXXMethodDecl *MD = cast(CurGD.getDecl()); // Adjust the 'this' pointer if necessary + const CXXRecordDecl *thisValueClass = + MD->getThisType()->getPointeeCXXRecordDecl(); + if (Thunk) +thisValueClass = Thunk->ThisType->getPointeeCXXRecordDecl(); asl wrote: ```suggestion ThisValueClass = Thunk->ThisType->getPointeeCXXRecordDecl(); ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)
@@ -307,10 +309,15 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const CXXMethodDecl *MD = cast(CurGD.getDecl()); // Adjust the 'this' pointer if necessary + const CXXRecordDecl *thisValueClass = + MD->getThisType()->getPointeeCXXRecordDecl(); + if (Thunk) +thisValueClass = Thunk->ThisType->getPointeeCXXRecordDecl(); + llvm::Value *AdjustedThisPtr = -Thunk ? CGM.getCXXABI().performThisAdjustment( - *this, LoadCXXThisAddress(), Thunk->This) - : LoadCXXThis(); + Thunk ? CGM.getCXXABI().performThisAdjustment(*this, LoadCXXThisAddress(), +thisValueClass, *Thunk) asl wrote: ```suggestion ThisValueClass, *Thunk) ``` https://github.com/llvm/llvm-project/pull/94056 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits