[llvm-branch-commits] [flang] [Flang][OpenMP] Derived type explicit allocatable member mapping (PR #113557)
llvmbot wrote: @llvm/pr-subscribers-flang-openmp Author: None (agozillon) Changes This PR is one of 3 in a PR stack, this is the primary change set which seeks to extend the current derived type explicit member mapping support to handle descriptor member mapping at arbitrary levels of nesting. The PR stack seems to do this reasonably (from testing so far) but as you can create quite complex mappings with derived types (in particular when adding allocatable derived types or arrays of allocatable derived types) I imagine there will be hiccups, which I am more than happy to address. There will also be further extensions to this work to handle the implicit auto-magical mapping of descriptor members in derived types and a few other changes planned for the future (with some ideas on optimizing things). The changes in this PR primarily occur in the OpenMP lowering and the OMPMapInfoFinalization pass. In the OpenMP lowering several utility functions were added or extended to support the generation of appropriate intermediate member mappings which are currently required when the parent (or multiple parents) of a mapped member are descriptor types. We need to map the entirety of these types or do a "deep copy" for lack of a better term, where we map both the base address and the descriptor as without the copying of both of these we lack the information in the case of the descriptor to access the member or attach the pointers data to the pointer and in the latter case we require the base address to map the chunk of data. Currently we do not segment descriptor based derived types as we do with regular non-descriptor derived types, we effectively map their entirety in all cases at the moment, I hope to address this at some point in the future as it adds a fair bit of a performance penalty to having nestings of allocatable derived types as an example. The process of mapping all intermediate descriptor members in a members path only occurs if a member has an allocatable or object parent in its symbol path or the member itself is a member or allocatable. This occurs in the createParentSymAndGenIntermediateMaps function, which will also generate the appropriate address for the allocatable member within the derived type to use as a the varPtr field of the map (for intermediate allocatable maps and final allocatable mappings). In this case it's necessary as we can't utilise the usual Fortran::lower functionality such as gatherDataOperandAddrAndBounds without causing issues later in the lowering due to extra allocas being spawned which seem to affect the pointer attachment (at least this is my current assumption, it results in memory access errors on the device due to incorrect map information generation). This is similar to why we do not use the MLIR value generated for this and utilise the original symbol provided when mapping descriptor types external to derived types. Hopefully this can be rectified in the future so this function can be simplified and more closely aligned to the other type mappings. We also make use of fir::CoordinateOp as opposed to the HLFIR version as the HLFIR version doesn't support the appropriate lowering to FIR necessary at the moment, we also cannot use a single CoordinateOp (similarly to a single GEP) as when we index through a descriptor operation (BoxType) we encounter issues later in the lowering, however in either case we need access to intermediate descriptors so individual CoordinateOp's aid this (although, being able to compress them into a smaller amount of CoordinateOp's may simplify the IR and perhaps result in a better end product, something to consider for the future). The other large change area was in the OMPMapInfoFinalization pass, where the pass had to be extended to support the expansion of box types (or multiple nestings of box types) within derived types, or box type derived types. This requires expanding each BoxType mapping from one into two maps and then modifying all of the existing member indices of the overarching parent mapping to account for the addition of these new members alongside adjusting the existing member indices to support the addition of these new maps which extend the original member indices (as a base address of a box type is currently considered a member of the box type at a position of 0 as when lowered to LLVM-IR it's a pointer contained at this position in the descriptor type, however, this means extending mapped children of this expanded descriptor type to additionally incorporate the new member index in the correct location in its own index list). I believe there is a reasonable amount of comments that should aid in understanding this better, alongside the test alterations for the pass. A subset of the changes were also aimed at making some of the utilities for packing and unpacking the DenseIntElementsAttr containing the member indices shareable across the lowering and OMPMapI
[llvm-branch-commits] [clang] [Multilib] Custom flags processing for library selection (PR #110659)
https://github.com/vhscampos ready_for_review https://github.com/llvm/llvm-project/pull/110659 ___ 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] [OpenMP][MLIR] Descriptor explicit member map lowering changes (PR #113556)
https://github.com/agozillon created https://github.com/llvm/llvm-project/pull/113556 This is one of 3 PRs in a PR stack that aims to add support for explicit mapping of allocatable members in derived types. The primary changes in this PR are the OpenMPToLLVMIRTranslation.cpp changes, which are small and seek to alter the current member mapping to add an additional map insertion for pointers. Effectively, if the member is a pointer (currently indicated by having a varPtrPtr field) we add an additional map for the pointer and then alter the subsequent mapping of the member (the data) to utilise the member rather than the parents base pointer. This appears to be necessary in certain cases when mapping pointer data within record types to avoid segfaulting on device (due to incorrect data mapping). In general this record type mapping may be simplifiable in the future. There are also additions of tests which should help to showcase the affect of the changes above. >From 113f7a9c9834b970ab2d69a6c5eaaf639e453682 Mon Sep 17 00:00:00 2001 From: agozillon Date: Fri, 4 Oct 2024 13:03:22 -0500 Subject: [PATCH] [OpenMP][MLIR] Descriptor explicit member map lowering changes This is one of 3 PRs in a PR stack that aims to add support for explicit mapping of allocatable members in derived types. The primary changes in this PR are the OpenMPToLLVMIRTranslation.cpp changes, which are small and seek to alter the current member mapping to add an additional map insertion for pointers. Effectively, if the member is a pointer (currently indicated by having a varPtrPtr field) we add an additional map for the pointer and then alter the subsequent mapping of the member (the data) to utilise the member rather than the parents base pointer. This appears to be necessary in certain cases when mapping pointer data within record types to avoid segfaulting on device (due to incorrect data mapping). In general this record type mapping may be simplifiable in the future. There are also additions of tests which should help to showcase the affect of the changes above. --- mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 2 +- mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 58 +++-- .../OpenMP/OpenMPToLLVMIRTranslation.cpp | 81 - mlir/test/Dialect/OpenMP/ops.mlir | 4 +- ...t-nested-ptr-record-type-mapping-host.mlir | 66 ++ ...arget-nested-record-type-mapping-host.mlir | 2 +- ...get-record-type-with-ptr-member-host.mlir} | 114 ++ 7 files changed, 197 insertions(+), 130 deletions(-) create mode 100644 mlir/test/Target/LLVMIR/omptarget-nested-ptr-record-type-mapping-host.mlir rename mlir/test/Target/LLVMIR/{omptarget-fortran-allocatable-types-host.mlir => omptarget-record-type-with-ptr-member-host.mlir} (58%) diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td index 626539cb7bde42..348c1b9c2b8bdf 100644 --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -895,7 +895,7 @@ def MapInfoOp : OpenMP_Op<"map.info", [AttrSizedOperandSegments]> { TypeAttr:$var_type, Optional:$var_ptr_ptr, Variadic:$members, - OptionalAttr:$members_index, + OptionalAttr:$members_index, Variadic:$bounds, /* rank-0 to rank-{n-1} */ OptionalAttr:$map_type, OptionalAttr:$map_capture_type, diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp index e1df647d6a3c71..8d31cda3a33ee9 100644 --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -1395,16 +1395,15 @@ static void printMapClause(OpAsmPrinter &p, Operation *op, } static ParseResult parseMembersIndex(OpAsmParser &parser, - DenseIntElementsAttr &membersIdx) { - SmallVector values; - int64_t value; - int64_t shape[2] = {0, 0}; - unsigned shapeTmp = 0; + ArrayAttr &membersIdx) { + SmallVector values, memberIdxs; + auto parseIndices = [&]() -> ParseResult { +int64_t value; if (parser.parseInteger(value)) return failure(); -shapeTmp++; -values.push_back(APInt(32, value, /*isSigned=*/true)); +values.push_back(IntegerAttr::get(parser.getBuilder().getIntegerType(64), + APInt(64, value, /*isSigned=*/false))); return success(); }; @@ -1418,52 +1417,29 @@ static ParseResult parseMembersIndex(OpAsmParser &parser, if (failed(parser.parseRSquare())) return failure(); -// Only set once, if any indices are not the same size -// we error out in the next check as that's unsupported -if (shape[1] == 0) - shape[1] = shapeTmp; - -// Verify that the recently p
[llvm-branch-commits] [Flang][OpenMP] Derived type explicit allocatable member mapping (PR #111192)
@@ -145,11 +146,174 @@ createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, builder.getIntegerAttr(builder.getIntegerType(64, false), mapType), builder.getAttr(mapCaptureType), builder.getStringAttr(name), builder.getBoolAttr(partialMap)); - return op; } -static int +omp::ObjectList gatherObjects(omp::Object obj, + semantics::SemanticsContext &semaCtx) { + omp::ObjectList objList; + std::optional baseObj = obj; + while (baseObj.has_value()) { +objList.push_back(baseObj.value()); +baseObj = getBaseObject(baseObj.value(), semaCtx); + } + return omp::ObjectList{llvm::reverse(objList)}; +} + +bool isDuplicateMemberMapInfo(OmpMapParentAndMemberData &parentMembers, + llvm::SmallVectorImpl &memberIndices) { + for (auto memberData : parentMembers.memberPlacementIndices) +if (std::equal(memberIndices.begin(), memberIndices.end(), + memberData.begin())) + return true; + return false; +} + +static void generateArrayIndices(lower::AbstractConverter &converter, + fir::FirOpBuilder &firOpBuilder, + lower::StatementContext &stmtCtx, + mlir::Location clauseLocation, + llvm::SmallVectorImpl &indices, + omp::Object object) { + if (auto maybeRef = evaluate::ExtractDataRef(*object.ref())) { agozillon wrote: happy to do the early returns, but I'd like to keep the llvm_unreachable and not replace it with a continue, it'd be ideal to know if it was generating incorrect indices if it was used with an array ref with triplets! https://github.com/llvm/llvm-project/pull/92 ___ 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][OpenMP] Derived type explicit allocatable member mapping (PR #111192)
@@ -49,38 +51,95 @@ using DeclareTargetCapturePair = // and index data when lowering OpenMP map clauses. Keeps track of the // placement of the component in the derived type hierarchy it rests within, // alongside the generated mlir::omp::MapInfoOp for the mapped component. -struct OmpMapMemberIndicesData { +// +// As an example of what the contents of this data structure may be like, +// when provided the following derived type and map of that type: +// +// type :: bottom_layer +// real(8) :: i2 +// real(4) :: array_i2(10) +// real(4) :: array_j2(10) +// end type bottom_layer +// +// type :: top_layer +// real(4) :: i +// integer(4) :: array_i(10) +// real(4) :: j +// type(bottom_layer) :: nested +// integer, allocatable :: array_j(:) +// integer(4) :: k +// end type top_layer +// +// type(top_layer) :: top_dtype +// +// map(tofrom: top_dtype%nested%i2, top_dtype%k, top_dtype%nested%array_i2) +// +// We would end up with an OmpMapParentAndMemberData populated like below: +// +// memberPlacementIndices: +// Vector 1: 3, 0 +// Vector 2: 5 +// Vector 3: 3, 1 +// +// memberMap: +// Entry 1: omp.map.info for "top_dtype%nested%i2" +// Entry 2: omp.map.info for "top_dtype%k" +// Entry 3: omp.map.info for "top_dtype%nested%array_i2" +// +// And this OmpMapParentAndMemberData would be accessed via the parent +// symbol for top_dtype. Other parent derived type instances that have +// members mapped would have there own OmpMapParentAndMemberData entry +// accessed via their own symbol. +struct OmpMapParentAndMemberData { agozillon wrote: I would prefer to keep it the way it is (at least for this iteration), as a structure of arrays as opposed to an array of structures, I had it as the latter originally, but it makes the functions for transforming from this structure to the array attributes that the map holds and vice versa more complicated and accessing and storing the data is a little bit more cumbersome. I believe the rather large description above also helps describe the intent of the structure, or I would hope at least or I could have skipped writing it :-) https://github.com/llvm/llvm-project/pull/92 ___ 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] [Multilib] Add -fmultilib-flag command-line option (PR #110658)
https://github.com/vhscampos ready_for_review https://github.com/llvm/llvm-project/pull/110658 ___ 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] [Serialization] Code cleanups and polish 83233 (PR #83237)
usx95 wrote: > I tried to take a look at eigen and it looks like the declaration looks well > and I had no clue how that happens. A reproducer may be necessary here to > proceed. Thanks in advance. I can reproduce using the following sources and invocations outlined in `run.sh` https://github.com/usx95/llvm-project/commit/363d877bd317638b197f57c3591860e1688950d5 ```sh > module-reproducer/run.sh Building sensor_data.cc Building tensor.cc Building base.cc In module 'sensor_data': ../../eigen/Eigen/src/Core/../plugins/CommonCwiseBinaryOps.inc:47:29: warning: inline function 'Eigen::operator*' is not defined [-Wundefined-inline] 47 | EIGEN_MAKE_SCALAR_BINARY_OP(operator*, product) | ^ ../../eigen/Eigen/src/Geometry/AngleAxis.h:221:35: note: used here 221 | Vector3 sin_axis = sin(m_angle) * m_axis; | ^ 1 warning generated. ``` This warning is a new breakage and does not happed without this change (ignore the linker failure). https://github.com/llvm/llvm-project/pull/83237 ___ 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] [compiler-rt] 56d9bb2 - Revert "[Sanitizers] Intercept timer_create (#112285)"
Author: Florian Mayer Date: 2024-10-25T09:41:43-07:00 New Revision: 56d9bb2798882c3653552949eaf1a30d3392ab5a URL: https://github.com/llvm/llvm-project/commit/56d9bb2798882c3653552949eaf1a30d3392ab5a DIFF: https://github.com/llvm/llvm-project/commit/56d9bb2798882c3653552949eaf1a30d3392ab5a.diff LOG: Revert "[Sanitizers] Intercept timer_create (#112285)" This reverts commit b373278767458284f4e5ba49d5223eb1a6f51aa5. Added: Modified: compiler-rt/lib/hwasan/hwasan_platform_interceptors.h compiler-rt/lib/msan/tests/msan_test.cpp compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h Removed: diff --git a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h index e8011014c2331d..d92b5105219427 100644 --- a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h +++ b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h @@ -200,9 +200,6 @@ #undef SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID #define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID 0 -#undef SANITIZER_INTERCEPT_TIMER_CREATE -#define SANITIZER_INTERCEPT_TIMER_CREATE 0 - #undef SANITIZER_INTERCEPT_GETITIMER #define SANITIZER_INTERCEPT_GETITIMER 0 diff --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp index ad265acf4c1e39..41b99fabe84f47 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cpp +++ b/compiler-rt/lib/msan/tests/msan_test.cpp @@ -4881,27 +4881,4 @@ TEST(MemorySanitizer, throw_catch) { // pass } } - -#if defined(__linux__) -TEST(MemorySanitizer, timer_create) { - timer_t timer; - EXPECT_POISONED(timer); - int res = timer_create(CLOCK_REALTIME, nullptr, &timer); - ASSERT_EQ(0, res); - EXPECT_NOT_POISONED(timer); - - // Make sure the timer is usable. - struct itimerspec cur_value {}; - cur_value.it_value.tv_sec = 1; - EXPECT_EQ(0, timer_settime(timer, 0, &cur_value, nullptr)); - - timer_t timer2; - EXPECT_POISONED(timer2); - // Use an invalid clock_id to make timer_create fail. - res = timer_create(INT_MAX, nullptr, &timer2); - ASSERT_EQ(-1, res); - EXPECT_POISONED(timer2); - timer_delete(timer); -} -#endif } // namespace diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 211f9f70d7e4c6..b8627f8557afe2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2289,24 +2289,6 @@ INTERCEPTOR(int, pthread_getcpuclockid, uptr thread, #define INIT_CLOCK_GETCPUCLOCKID #endif -#if SANITIZER_INTERCEPT_TIMER_CREATE -INTERCEPTOR(int, timer_create, __sanitizer_clockid_t clockid, void *sevp, -__sanitizer_timer_t *timer) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, timer_create, clockid, sevp, timer); - int res = REAL(timer_create)(clockid, sevp, timer); - if (!res && timer) { -COMMON_INTERCEPTOR_WRITE_RANGE(ctx, timer, sizeof *timer); - } - return res; -} - -# define INIT_TIMER_CREATE \ -COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_create, "GLIBC_2.3.3"); -#else -# define INIT_TIMER_CREATE -#endif - #if SANITIZER_INTERCEPT_GETITIMER INTERCEPTOR(int, getitimer, int which, void *curr_value) { void *ctx; @@ -10284,7 +10266,6 @@ static void InitializeCommonInterceptors() { INIT_SETPWENT; INIT_CLOCK_GETTIME; INIT_CLOCK_GETCPUCLOCKID; - INIT_TIMER_CREATE; INIT_GETITIMER; INIT_TIME; INIT_GLOB; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 36fafdc642642b..6959a6d52d604e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -237,9 +237,6 @@ (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID \ (SI_LINUX || SI_FREEBSD || SI_NETBSD) -// TODO: This should be SI_POSIX, adding Linux first until I have time -// to verify all timer_t typedefs on other platforms. -#define SANITIZER_INTERCEPT_TIMER_CREATE SI_LINUX #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX #define SANITIZER_INTERCEPT_TIME SI_POSIX #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index b4ccf7b3d7bef4..e8c81aa8e28163 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -1517,10 +1517,6 @@ extern const int si_SEGV_ACCERR; #defin
[llvm-branch-commits] [flang] [Flang][OpenMP] Access full list of entry block syms and vars (NFC) (PR #113681)
skatrak wrote: PR stack: - #113680 - #113681 - #113682 - #113683 https://github.com/llvm/llvm-project/pull/113681 ___ 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] [AArch64][PAC] Move emission of LR checks in tail calls to AsmPrinter (PR #110705)
https://github.com/atrosinenko updated https://github.com/llvm/llvm-project/pull/110705 >From aec7d908c567a857d63a731eab044bbdd2925558 Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko Date: Mon, 23 Sep 2024 19:51:55 +0300 Subject: [PATCH 1/3] [AArch64][PAC] Move emission of LR checks in tail calls to AsmPrinter Move the emission of the checks performed on the authenticated LR value during tail calls to AArch64AsmPrinter class, so that different checker sequences can be reused by pseudo instructions expanded there. This adds one more option to AuthCheckMethod enumeration, the generic XPAC variant which is not restricted to checking the LR register. --- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 143 +++--- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 13 ++ llvm/lib/Target/AArch64/AArch64InstrInfo.td | 2 + .../lib/Target/AArch64/AArch64PointerAuth.cpp | 182 +- llvm/lib/Target/AArch64/AArch64PointerAuth.h | 40 ++-- llvm/lib/Target/AArch64/AArch64Subtarget.cpp | 2 - llvm/lib/Target/AArch64/AArch64Subtarget.h| 23 --- llvm/test/CodeGen/AArch64/ptrauth-ret-trap.ll | 36 ++-- .../AArch64/sign-return-address-tailcall.ll | 54 +++--- 9 files changed, 192 insertions(+), 303 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 6d2dd0ecbccf31..50502477706ccf 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -153,6 +153,7 @@ class AArch64AsmPrinter : public AsmPrinter { void emitPtrauthCheckAuthenticatedValue(Register TestedReg, Register ScratchReg, AArch64PACKey::ID Key, + AArch64PAuth::AuthCheckMethod Method, bool ShouldTrap, const MCSymbol *OnFailure); @@ -1731,7 +1732,8 @@ unsigned AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc, /// of proceeding to the next instruction (only if ShouldTrap is false). void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue( Register TestedReg, Register ScratchReg, AArch64PACKey::ID Key, -bool ShouldTrap, const MCSymbol *OnFailure) { +AArch64PAuth::AuthCheckMethod Method, bool ShouldTrap, +const MCSymbol *OnFailure) { // Insert a sequence to check if authentication of TestedReg succeeded, // such as: // @@ -1757,38 +1759,70 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue( //Lsuccess: // ... // - // This sequence is expensive, but we need more information to be able to - // do better. - // - // We can't TBZ the poison bit because EnhancedPAC2 XORs the PAC bits - // on failure. - // We can't TST the PAC bits because we don't always know how the address - // space is setup for the target environment (and the bottom PAC bit is - // based on that). - // Either way, we also don't always know whether TBI is enabled or not for - // the specific target environment. + // See the documentation on AuthCheckMethod enumeration constants for + // the specific code sequences that can be used to perform the check. + using AArch64PAuth::AuthCheckMethod; - unsigned XPACOpc = getXPACOpcodeForKey(Key); + if (Method == AuthCheckMethod::None) +return; + if (Method == AuthCheckMethod::DummyLoad) { +EmitToStreamer(MCInstBuilder(AArch64::LDRWui) + .addReg(getWRegFromXReg(ScratchReg)) + .addReg(TestedReg) + .addImm(0)); +assert(ShouldTrap && !OnFailure && "DummyLoad always traps on error"); +return; + } MCSymbol *SuccessSym = createTempSymbol("auth_success_"); + if (Method == AuthCheckMethod::XPAC || Method == AuthCheckMethod::XPACHint) { +// mov Xscratch, Xtested +emitMovXReg(ScratchReg, TestedReg); - // mov Xscratch, Xtested - emitMovXReg(ScratchReg, TestedReg); - - // xpac(i|d) Xscratch - EmitToStreamer(MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg)); +if (Method == AuthCheckMethod::XPAC) { + // xpac(i|d) Xscratch + unsigned XPACOpc = getXPACOpcodeForKey(Key); + EmitToStreamer( + MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg)); +} else { + // xpaclri + + // Note that this method applies XPAC to TestedReg instead of ScratchReg. + assert(TestedReg == AArch64::LR && + "XPACHint mode is only compatible with checking the LR register"); + assert((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) && + "XPACHint mode is only compatible with I-keys"); + EmitToStreamer(MCInstBuilder(AArch64::XPACLRI)); +} - // cmp Xtested, Xscratch - EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs) - .addReg(AArch64::XZR) - .addReg(TestedReg) - .
[llvm-branch-commits] [flang] [Flang][OpenMP] Properly bind arguments of composite operations (PR #113682)
llvmbot wrote: @llvm/pr-subscribers-flang-fir-hlfir Author: Sergio Afonso (skatrak) Changes When composite constructs are lowered, clauses for each leaf construct are lowered before creating the set of loop wrapper operations, using these outside values to populate their operand lists. Then, when the loop nest associated to that composite construct is lowered, the binding of Fortran symbols to the entry block arguments defined by these loop wrappers is performed, resulting in the creation of `hlfir.declare` operations in the entry block of the `omp.loop_nest`. This approach prevents `hlfir.declare` operations related to the binding and other operations resulting from the evaluation of the clauses from being inserted between loop wrapper operations, which would be an illegal MLIR representation. However, this introduces the problem of entry block arguments defined by a wrapper that then should be used by one of its nested wrappers, because the corresponding Fortran symbol would still be mapped to an outside value at the time of gathering the list of operands for the nested wrapper. This patch adds operand re-mapping logic to update wrappers without changing when clauses are evaluated or where the `hlfir.declare` creation is performed. --- Full diff: https://github.com/llvm/llvm-project/pull/113682.diff 1 Files Affected: - (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+19-2) ``diff diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index e2545a68241004..149a7b9407b526 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -589,10 +589,27 @@ static void genLoopVars( llvm::SmallVector locs(args.size(), loc); firOpBuilder.createBlock(®ion, {}, tiv, locs); + // Update nested wrapper operands if parent wrappers have mapped these values + // to block arguments. + // + // Binding these values earlier would take care of this, but we cannot rely on + // that approach because binding in between the creation of a wrapper and the + // next one would result in 'hlfir.declare' operations being introduced inside + // of a wrapper, which is illegal. + mlir::IRMapping mapper; + for (auto [argGeneratingOp, blockArgs] : wrapperArgs) { +for (mlir::OpOperand &operand : argGeneratingOp->getOpOperands()) + operand.set(mapper.lookupOrDefault(operand.get())); + +for (const auto [arg, var] : llvm::zip_equal( + argGeneratingOp->getRegion(0).getArguments(), blockArgs.getVars())) + mapper.map(var, arg); + } + // Bind the entry block arguments of parent wrappers to the corresponding // symbols. - for (auto [argGeneratingOp, args] : wrapperArgs) -bindEntryBlockArgs(converter, argGeneratingOp, args); + for (auto [argGeneratingOp, blockArgs] : wrapperArgs) +bindEntryBlockArgs(converter, argGeneratingOp, blockArgs); // The argument is not currently in memory, so make a temporary for the // argument, and store it there, then bind that location to the argument. `` https://github.com/llvm/llvm-project/pull/113682 ___ 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] Revert "[Flang][OpenMP] Disable lowering of omp.simd reductions in co… (PR #113683)
llvmbot wrote: @llvm/pr-subscribers-flang-openmp @llvm/pr-subscribers-flang-fir-hlfir Author: Sergio Afonso (skatrak) Changes …mposites (#112686)" Lowering of reductions in composite operations can now be re-enabled, since previous commits in this PR stack fix the MLIR representation produced and it no longer triggers a compiler crash during translation to LLVM IR. This reverts commit c44860c8d2582abd88794267b4fa0fa953bbef80. --- Full diff: https://github.com/llvm/llvm-project/pull/113683.diff 2 Files Affected: - (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+6-14) - (modified) flang/test/Lower/OpenMP/wsloop-simd.f90 (+21) ``diff diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 149a7b9407b526..315a0bad7425a8 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2237,12 +2237,6 @@ static void genCompositeDistributeParallelDoSimd( genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps, simdReductionSyms); - // TODO: Remove this after omp.simd reductions on composite constructs are - // supported. - simdClauseOps.reductionVars.clear(); - simdClauseOps.reductionByref.clear(); - simdClauseOps.reductionSyms.clear(); - mlir::omp::LoopNestOperands loopNestClauseOps; llvm::SmallVector iv; genLoopNestClauses(converter, semaCtx, eval, simdItem->clauses, loc, @@ -2264,7 +2258,9 @@ static void genCompositeDistributeParallelDoSimd( wsloopOp.setComposite(/*val=*/true); EntryBlockArgs simdArgs; - // TODO: Add private and reduction syms and vars. + // TODO: Add private syms and vars. + simdArgs.reduction.syms = simdReductionSyms; + simdArgs.reduction.vars = simdClauseOps.reductionVars; auto simdOp = genWrapperOp(converter, loc, simdClauseOps, simdArgs); simdOp.setComposite(/*val=*/true); @@ -2357,12 +2353,6 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps, simdReductionSyms); - // TODO: Remove this after omp.simd reductions on composite constructs are - // supported. - simdClauseOps.reductionVars.clear(); - simdClauseOps.reductionByref.clear(); - simdClauseOps.reductionSyms.clear(); - // TODO: Support delayed privatization. DataSharingProcessor dsp(converter, semaCtx, simdItem->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, @@ -2386,7 +2376,9 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, wsloopOp.setComposite(/*val=*/true); EntryBlockArgs simdArgs; - // TODO: Add private and reduction syms and vars. + // TODO: Add private syms and vars. + simdArgs.reduction.syms = simdReductionSyms; + simdArgs.reduction.vars = simdClauseOps.reductionVars; auto simdOp = genWrapperOp(converter, loc, simdClauseOps, simdArgs); simdOp.setComposite(/*val=*/true); diff --git a/flang/test/Lower/OpenMP/wsloop-simd.f90 b/flang/test/Lower/OpenMP/wsloop-simd.f90 index 899ab59714f144..49a9a523e11fe7 100644 --- a/flang/test/Lower/OpenMP/wsloop-simd.f90 +++ b/flang/test/Lower/OpenMP/wsloop-simd.f90 @@ -45,3 +45,24 @@ subroutine do_simd_simdlen() end do !$omp end do simd end subroutine do_simd_simdlen + +! CHECK-LABEL: func.func @_QPdo_simd_reduction( +subroutine do_simd_reduction() + integer :: sum + sum = 0 + ! CHECK: omp.wsloop + ! CHECK-SAME: reduction(@[[RED_SYM:.*]] %{{.*}} -> %[[RED_OUTER:.*]] : !fir.ref) + ! CHECK-NEXT: omp.simd + ! CHECK-SAME: reduction(@[[RED_SYM]] %[[RED_OUTER]] -> %[[RED_INNER:.*]] : !fir.ref) + ! CHECK-NEXT: omp.loop_nest + ! CHECK: %[[RED_DECL:.*]]:2 = hlfir.declare %[[RED_INNER]] + ! CHECK: %[[RED:.*]] = fir.load %[[RED_DECL]]#0 : !fir.ref + ! CHECK: %[[RESULT:.*]] = arith.addi %[[RED]], %{{.*}} : i32 + ! CHECK: hlfir.assign %[[RESULT]] to %[[RED_DECL]]#0 : i32, !fir.ref + ! CHECK-NEXT: omp.yield + !$omp do simd reduction(+:sum) +do index_ = 1, 10 + sum = sum + 1 +end do + !$omp end do simd +end subroutine do_simd_reduction `` https://github.com/llvm/llvm-project/pull/113683 ___ 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] Parsing support for iterator in DEPEND clause (PR #113622)
https://github.com/kiranchandramohan approved this pull request. LG. https://github.com/llvm/llvm-project/pull/113622 ___ 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] Parsing support for iterator in DEPEND clause (PR #113622)
@@ -3307,6 +3307,15 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) { } } } +if (std::get>(inOut->t)) { + unsigned version{context_.langOptions().OpenMPVersion}; + unsigned allowedInVersion = 50; kiranchandramohan wrote: ```suggestion unsigned allowedInVersion{50}; ``` https://github.com/llvm/llvm-project/pull/113622 ___ 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] Revert "[Flang][OpenMP] Disable lowering of omp.simd reductions in co… (PR #113683)
skatrak wrote: PR stack: - #113680 - #113681 - #113682 - #113683 https://github.com/llvm/llvm-project/pull/113683 ___ 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] AMDGPU: Mark grid size loads with range metadata (PR #113019)
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/113019 >From 5336b212f224d01d78e515ffae7f63ae48cdd2ab Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sat, 19 Oct 2024 02:18:45 +0400 Subject: [PATCH] AMDGPU: Mark grid size loads with range metadata Only handles the v5 case. --- .../AMDGPU/AMDGPULowerKernelAttributes.cpp| 33 - llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp| 1 + ...amdgpu-max-num-workgroups-load-annotate.ll | 124 ++ 3 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/amdgpu-max-num-workgroups-load-annotate.ll diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelAttributes.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelAttributes.cpp index 1bb5e794da7dd6..5fc0c36359b6f5 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelAttributes.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelAttributes.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsAMDGPU.h" +#include "llvm/IR/MDBuilder.h" #include "llvm/IR/PatternMatch.h" #include "llvm/Pass.h" @@ -83,6 +84,20 @@ Function *getBasePtrIntrinsic(Module &M, bool IsV5OrAbove) { } // end anonymous namespace +static void annotateGridSizeLoadWithRangeMD(LoadInst *Load, +uint32_t MaxNumGroups) { + if (MaxNumGroups == 0 || MaxNumGroups == std::numeric_limits::max()) +return; + + if (!Load->getType()->isIntegerTy(32)) +return; + + // TODO: If there is existing range metadata, preserve it if it is stricter. + MDBuilder MDB(Load->getContext()); + MDNode *Range = MDB.createRange(APInt(32, 1), APInt(32, MaxNumGroups + 1)); + Load->setMetadata(LLVMContext::MD_range, Range); +} + static bool processUse(CallInst *CI, bool IsV5OrAbove) { Function *F = CI->getParent()->getParent(); @@ -92,7 +107,11 @@ static bool processUse(CallInst *CI, bool IsV5OrAbove) { const bool HasUniformWorkGroupSize = F->getFnAttribute("uniform-work-group-size").getValueAsBool(); - if (!HasReqdWorkGroupSize && !HasUniformWorkGroupSize) + SmallVector MaxNumWorkgroups = + AMDGPU::getIntegerVecAttribute(*F, "amdgpu-max-num-workgroups", 3); + + if (!HasReqdWorkGroupSize && !HasUniformWorkGroupSize && + none_of(MaxNumWorkgroups, [](unsigned X) { return X != 0; })) return false; Value *BlockCounts[3] = {nullptr, nullptr, nullptr}; @@ -133,16 +152,22 @@ static bool processUse(CallInst *CI, bool IsV5OrAbove) { if (IsV5OrAbove) { // Base is ImplicitArgPtr. switch (Offset) { case HIDDEN_BLOCK_COUNT_X: -if (LoadSize == 4) +if (LoadSize == 4) { BlockCounts[0] = Load; + annotateGridSizeLoadWithRangeMD(Load, MaxNumWorkgroups[0]); +} break; case HIDDEN_BLOCK_COUNT_Y: -if (LoadSize == 4) +if (LoadSize == 4) { BlockCounts[1] = Load; + annotateGridSizeLoadWithRangeMD(Load, MaxNumWorkgroups[1]); +} break; case HIDDEN_BLOCK_COUNT_Z: -if (LoadSize == 4) +if (LoadSize == 4) { BlockCounts[2] = Load; + annotateGridSizeLoadWithRangeMD(Load, MaxNumWorkgroups[2]); +} break; case HIDDEN_GROUP_SIZE_X: if (LoadSize == 2) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp b/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp index 54b17ca2cffb15..b18ce90cf45dba 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp @@ -369,6 +369,7 @@ const AMDGPUSubtarget &AMDGPUSubtarget::get(const TargetMachine &TM, const Funct TM.getSubtarget(F)); } +// FIXME: This has no reason to be in subtarget SmallVector AMDGPUSubtarget::getMaxNumWorkGroups(const Function &F) const { return AMDGPU::getIntegerVecAttribute(F, "amdgpu-max-num-workgroups", 3, diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-max-num-workgroups-load-annotate.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-max-num-workgroups-load-annotate.ll new file mode 100644 index 00..9064292129928f --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/amdgpu-max-num-workgroups-load-annotate.ll @@ -0,0 +1,124 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5 +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-lower-kernel-attributes %s | FileCheck %s + +define i32 @use_grid_size_x_max_num_workgroups() #0 { +; CHECK-LABEL: define i32 @use_grid_size_x_max_num_workgroups( +; CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT:[[IMPLICITARG_PTR:%.*]] = call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() +; CHECK-NEXT:[[GRID_SIZE_X:%.*]] = load i32, ptr addrspace(4) [[IMPLICITARG_PTR]], align 4, !range [[RNG0:![0-9]+]] +; CHECK-NEXT:ret i32 [[GRID_SIZE_X]] +; + %implicitarg.ptr = call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() + %grid.size.x = load i32,
[llvm-branch-commits] [clang] clang/AMDGPU: Emit grid size builtins with range metadata (PR #113038)
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/113038 >From 79c3169ecb9042947330202fc1274c4a6cbcb8a8 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sat, 19 Oct 2024 02:39:06 +0400 Subject: [PATCH] clang/AMDGPU: Emit grid size builtins with range metadata These cannot be 0. --- clang/lib/CodeGen/CGBuiltin.cpp | 6 ++ clang/test/CodeGenOpenCL/builtins-amdgcn.cl | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e2d03eff8ab4a0..a7a209809303bb 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18545,6 +18545,12 @@ Value *EmitAMDGPUGridSize(CodeGenFunction &CGF, unsigned Index) { auto *GEP = CGF.Builder.CreateGEP(CGF.Int8Ty, DP, Offset); auto *LD = CGF.Builder.CreateLoad( Address(GEP, CGF.Int32Ty, CharUnits::fromQuantity(4))); + + llvm::MDBuilder MDB(CGF.getLLVMContext()); + + // Known non-zero. + LD->setMetadata(llvm::LLVMContext::MD_range, + MDB.createRange(APInt(32, 1), APInt::getZero(32))); LD->setMetadata(llvm::LLVMContext::MD_invariant_load, llvm::MDNode::get(CGF.getLLVMContext(), {})); return LD; diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl index bf5f2971cf118c..be6cee5e9217bf 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl @@ -639,7 +639,7 @@ void test_get_workgroup_size(int d, global int *out) // CHECK-LABEL: @test_get_grid_size( // CHECK: {{.*}}call align 4 dereferenceable(64){{.*}} ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() // CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 %.sink -// CHECK: load i32, ptr addrspace(4) %{{.*}}, align 4, !invariant.load +// CHECK: load i32, ptr addrspace(4) %{{.*}}, align 4, !range [[$GRID_RANGE:![0-9]+]], !invariant.load void test_get_grid_size(int d, global int *out) { switch (d) { @@ -896,5 +896,6 @@ void test_set_fpenv(unsigned long env) { __builtin_amdgcn_set_fpenv(env); } +// CHECK-DAG: [[$GRID_RANGE]] = !{i32 1, i32 0} // CHECK-DAG: [[$WS_RANGE]] = !{i16 1, i16 1025} // CHECK-DAG: attributes #[[$NOUNWIND_READONLY]] = { convergent mustprogress nocallback nofree nounwind willreturn memory(none) } ___ 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] [Coverage][Single] Enable Branch coverage for `BinLAnd` and `BinLOr` (PR #113113)
https://github.com/chapuni updated https://github.com/llvm/llvm-project/pull/113113 >From 16e2bb8b73bcde1c2618bb358a905a9f463c1217 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 20 Oct 2024 16:24:26 +0900 Subject: [PATCH 1/2] [Coverage][Single] Enable Branch coverage for `BinLAnd` and `BinLOr` --- clang/lib/CodeGen/CGExprScalar.cpp | 83 +++- clang/lib/CodeGen/CGStmt.cpp | 4 -- clang/lib/CodeGen/CodeGenFunction.cpp| 43 ++-- clang/lib/CodeGen/CoverageMappingGen.cpp | 6 -- 4 files changed, 104 insertions(+), 32 deletions(-) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 11d4ec8a267605..83962ba96aa484 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -4918,6 +4918,9 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { } Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { + auto HasLHSSkip = CGF.getIsCounterPair(E); + auto HasRHSSkip = CGF.getIsCounterPair(E->getRHS()); + // Perform vector logical and on comparisons with zero vectors. if (E->getType()->isVectorType()) { CGF.incrementProfileCounter(E); @@ -4964,11 +4967,17 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { CodeGenFunction::isInstrumentedCondition(E->getRHS())) { CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond); llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end"); +llvm::BasicBlock *RHSSkip = +(HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : FBlock); llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt"); -Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock); +Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip); CGF.EmitBlock(RHSBlockCnt); -CGF.incrementProfileCounter(E->getRHS()); +CGF.incrementProfileCounter(false, E->getRHS()); CGF.EmitBranch(FBlock); +if (HasRHSSkip.second) { + CGF.EmitBlock(RHSSkip); + CGF.incrementProfileCounter(true, E->getRHS()); +} CGF.EmitBlock(FBlock); } @@ -4997,12 +5006,21 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end"); llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land.rhs"); + llvm::BasicBlock *LHSFalseBlock = + (HasLHSSkip.second ? CGF.createBasicBlock("land.lhsskip") : ContBlock); + CodeGenFunction::ConditionalEvaluation eval(CGF); // Branch on the LHS first. If it is false, go to the failure (cont) block. - CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock, + CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, LHSFalseBlock, CGF.getProfileCount(E->getRHS())); + if (HasLHSSkip.second) { +CGF.EmitBlock(LHSFalseBlock); +CGF.incrementProfileCounter(true, E); +CGF.EmitBranch(ContBlock); + } + // Any edges into the ContBlock are now from an (indeterminate number of) // edges from this first condition. All of these values will be false. Start // setting up the PHI node in the Cont Block for this. @@ -5014,7 +5032,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { eval.begin(CGF); CGF.EmitBlock(RHSBlock); - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(false, E); Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); eval.end(CGF); @@ -5024,15 +5042,24 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { // If we're generating for profiling or coverage, generate a branch on the // RHS to a block that increments the RHS true counter needed to track branch // condition coverage. + llvm::BasicBlock *ContIncoming = RHSBlock; if (InstrumentRegions && CodeGenFunction::isInstrumentedCondition(E->getRHS())) { CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond); llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt"); -Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock); +llvm::BasicBlock *RHSBlockSkip = +(HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : ContBlock); +Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip); CGF.EmitBlock(RHSBlockCnt); -CGF.incrementProfileCounter(E->getRHS()); +CGF.incrementProfileCounter(false, E->getRHS()); CGF.EmitBranch(ContBlock); PN->addIncoming(RHSCond, RHSBlockCnt); +if (HasRHSSkip.second) { + CGF.EmitBlock(RHSBlockSkip); + CGF.incrementProfileCounter(true, E->getRHS()); + CGF.EmitBranch(ContBlock); + ContIncoming = RHSBlockSkip; +} } // Emit an unconditional branch from this block to ContBlock. @@ -5042,7 +5069,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { CGF.EmitBlock(ContBlock); } // Insert an entry into the phi node for the edge with the value of RHSCond.
[llvm-branch-commits] [flang] [flang][OpenMP] Parsing support for iterator in DEPEND clause (PR #113622)
https://github.com/kiranchandramohan edited https://github.com/llvm/llvm-project/pull/113622 ___ 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] Access full list of entry block syms and vars (NFC) (PR #113681)
llvmbot wrote: @llvm/pr-subscribers-flang-fir-hlfir Author: Sergio Afonso (skatrak) Changes This patch adds methods to `EntryBlockArgs` to access the full list of entry block argument-related symbols and variables, in their standard order. This helps centralizing this logic in as few places as possible to avoid future inconsistencies. --- Full diff: https://github.com/llvm/llvm-project/pull/113681.diff 1 Files Affected: - (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+16-5) ``diff diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index fc54da8babe63e..e2545a68241004 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -76,6 +76,18 @@ struct EntryBlockArgs { reduction.isValid() && taskReduction.isValid() && useDeviceAddr.isValid() && useDevicePtr.isValid(); } + + auto getSyms() const { +return llvm::concat( +inReduction.syms, map.syms, priv.syms, reduction.syms, +taskReduction.syms, useDeviceAddr.syms, useDevicePtr.syms); + } + + auto getVars() const { +return llvm::concat( +inReduction.vars, map.vars, priv.vars, reduction.vars, +taskReduction.vars, useDeviceAddr.vars, useDevicePtr.vars); + } }; } // namespace @@ -1506,8 +1518,7 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable, genEntryBlock(converter, args, op->getRegion(0)); bindEntryBlockArgs( converter, llvm::cast(op), args); -return llvm::to_vector(llvm::concat( -args.priv.syms, args.reduction.syms)); +return llvm::to_vector(args.getSyms()); }; assert((!enableDelayedPrivatization || dsp) && @@ -1581,11 +1592,11 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, mlir::Operation *terminator = lower::genOpenMPTerminator(builder, sectionsOp, loc); - auto reductionCallback = [&](mlir::Operation *op) { + auto genRegionEntryCB = [&](mlir::Operation *op) { genEntryBlock(converter, args, op->getRegion(0)); bindEntryBlockArgs( converter, llvm::cast(op), args); -return reductionSyms; +return llvm::to_vector(args.getSyms()); }; // Generate nested SECTION constructs. @@ -1611,7 +1622,7 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, OpWithBodyGenInfo(converter, symTable, semaCtx, loc, nestedEval, llvm::omp::Directive::OMPD_section) .setClauses(§ionQueue.begin()->clauses) -.setGenRegionEntryCb(reductionCallback), +.setGenRegionEntryCb(genRegionEntryCB), sectionQueue, sectionQueue.begin()); } `` https://github.com/llvm/llvm-project/pull/113681 ___ 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] Properly bind arguments of composite operations (PR #113682)
https://github.com/skatrak created https://github.com/llvm/llvm-project/pull/113682 When composite constructs are lowered, clauses for each leaf construct are lowered before creating the set of loop wrapper operations, using these outside values to populate their operand lists. Then, when the loop nest associated to that composite construct is lowered, the binding of Fortran symbols to the entry block arguments defined by these loop wrappers is performed, resulting in the creation of `hlfir.declare` operations in the entry block of the `omp.loop_nest`. This approach prevents `hlfir.declare` operations related to the binding and other operations resulting from the evaluation of the clauses from being inserted between loop wrapper operations, which would be an illegal MLIR representation. However, this introduces the problem of entry block arguments defined by a wrapper that then should be used by one of its nested wrappers, because the corresponding Fortran symbol would still be mapped to an outside value at the time of gathering the list of operands for the nested wrapper. This patch adds operand re-mapping logic to update wrappers without changing when clauses are evaluated or where the `hlfir.declare` creation is performed. >From b6565532e5a9484e03700e29c528938f8f4d5734 Mon Sep 17 00:00:00 2001 From: Sergio Afonso Date: Fri, 25 Oct 2024 11:45:19 +0100 Subject: [PATCH] [Flang][OpenMP] Properly bind arguments of composite operations When composite constructs are lowered, clauses for each leaf construct are lowered before creating the set of loop wrapper operations, using these outside values to populate their operand lists. Then, when the loop nest associated to that composite construct is lowered, the binding of Fortran symbols to the entry block arguments defined by these loop wrappers is performed, resulting in the creation of `hlfir.declare` operations in the entry block of the `omp.loop_nest`. This approach prevents `hlfir.declare` operations related to the binding and other operations resulting from the evaluation of the clauses from being inserted between loop wrapper operations, which would be an illegal MLIR representation. However, this introduces the problem of entry block arguments defined by a wrapper that then should be used by one of its nested wrappers, because the corresponding Fortran symbol would still be mapped to an outside value at the time of gathering the list of operands for the nested wrapper. This patch adds operand re-mapping logic to update wrappers without changing when clauses are evaluated or where the `hlfir.declare` creation is performed. --- flang/lib/Lower/OpenMP/OpenMP.cpp | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index e2545a68241004..149a7b9407b526 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -589,10 +589,27 @@ static void genLoopVars( llvm::SmallVector locs(args.size(), loc); firOpBuilder.createBlock(®ion, {}, tiv, locs); + // Update nested wrapper operands if parent wrappers have mapped these values + // to block arguments. + // + // Binding these values earlier would take care of this, but we cannot rely on + // that approach because binding in between the creation of a wrapper and the + // next one would result in 'hlfir.declare' operations being introduced inside + // of a wrapper, which is illegal. + mlir::IRMapping mapper; + for (auto [argGeneratingOp, blockArgs] : wrapperArgs) { +for (mlir::OpOperand &operand : argGeneratingOp->getOpOperands()) + operand.set(mapper.lookupOrDefault(operand.get())); + +for (const auto [arg, var] : llvm::zip_equal( + argGeneratingOp->getRegion(0).getArguments(), blockArgs.getVars())) + mapper.map(var, arg); + } + // Bind the entry block arguments of parent wrappers to the corresponding // symbols. - for (auto [argGeneratingOp, args] : wrapperArgs) -bindEntryBlockArgs(converter, argGeneratingOp, args); + for (auto [argGeneratingOp, blockArgs] : wrapperArgs) +bindEntryBlockArgs(converter, argGeneratingOp, blockArgs); // The argument is not currently in memory, so make a temporary for the // argument, and store it there, then bind that location to the argument. ___ 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] Revert "[Flang][OpenMP] Disable lowering of omp.simd reductions in co… (PR #113683)
https://github.com/skatrak created https://github.com/llvm/llvm-project/pull/113683 …mposites (#112686)" Lowering of reductions in composite operations can now be re-enabled, since previous commits in this PR stack fix the MLIR representation produced and it no longer triggers a compiler crash during translation to LLVM IR. This reverts commit c44860c8d2582abd88794267b4fa0fa953bbef80. >From 32241ac607d67467ef5ff3cbc817a8c85b2d9e13 Mon Sep 17 00:00:00 2001 From: Sergio Afonso Date: Fri, 25 Oct 2024 12:07:22 +0100 Subject: [PATCH] Revert "[Flang][OpenMP] Disable lowering of omp.simd reductions in composites (#112686)" Lowering of reductions in composite operations can now be re-enabled, since previous commits in this PR stack fix the MLIR representation produced and it no longer triggers a compiler crash during translation to LLVM IR. This reverts commit c44860c8d2582abd88794267b4fa0fa953bbef80. --- flang/lib/Lower/OpenMP/OpenMP.cpp | 20 ++-- flang/test/Lower/OpenMP/wsloop-simd.f90 | 21 + 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 149a7b9407b526..315a0bad7425a8 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2237,12 +2237,6 @@ static void genCompositeDistributeParallelDoSimd( genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps, simdReductionSyms); - // TODO: Remove this after omp.simd reductions on composite constructs are - // supported. - simdClauseOps.reductionVars.clear(); - simdClauseOps.reductionByref.clear(); - simdClauseOps.reductionSyms.clear(); - mlir::omp::LoopNestOperands loopNestClauseOps; llvm::SmallVector iv; genLoopNestClauses(converter, semaCtx, eval, simdItem->clauses, loc, @@ -2264,7 +2258,9 @@ static void genCompositeDistributeParallelDoSimd( wsloopOp.setComposite(/*val=*/true); EntryBlockArgs simdArgs; - // TODO: Add private and reduction syms and vars. + // TODO: Add private syms and vars. + simdArgs.reduction.syms = simdReductionSyms; + simdArgs.reduction.vars = simdClauseOps.reductionVars; auto simdOp = genWrapperOp(converter, loc, simdClauseOps, simdArgs); simdOp.setComposite(/*val=*/true); @@ -2357,12 +2353,6 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, genSimdClauses(converter, semaCtx, simdItem->clauses, loc, simdClauseOps, simdReductionSyms); - // TODO: Remove this after omp.simd reductions on composite constructs are - // supported. - simdClauseOps.reductionVars.clear(); - simdClauseOps.reductionByref.clear(); - simdClauseOps.reductionSyms.clear(); - // TODO: Support delayed privatization. DataSharingProcessor dsp(converter, semaCtx, simdItem->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, @@ -2386,7 +2376,9 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, wsloopOp.setComposite(/*val=*/true); EntryBlockArgs simdArgs; - // TODO: Add private and reduction syms and vars. + // TODO: Add private syms and vars. + simdArgs.reduction.syms = simdReductionSyms; + simdArgs.reduction.vars = simdClauseOps.reductionVars; auto simdOp = genWrapperOp(converter, loc, simdClauseOps, simdArgs); simdOp.setComposite(/*val=*/true); diff --git a/flang/test/Lower/OpenMP/wsloop-simd.f90 b/flang/test/Lower/OpenMP/wsloop-simd.f90 index 899ab59714f144..49a9a523e11fe7 100644 --- a/flang/test/Lower/OpenMP/wsloop-simd.f90 +++ b/flang/test/Lower/OpenMP/wsloop-simd.f90 @@ -45,3 +45,24 @@ subroutine do_simd_simdlen() end do !$omp end do simd end subroutine do_simd_simdlen + +! CHECK-LABEL: func.func @_QPdo_simd_reduction( +subroutine do_simd_reduction() + integer :: sum + sum = 0 + ! CHECK: omp.wsloop + ! CHECK-SAME: reduction(@[[RED_SYM:.*]] %{{.*}} -> %[[RED_OUTER:.*]] : !fir.ref) + ! CHECK-NEXT: omp.simd + ! CHECK-SAME: reduction(@[[RED_SYM]] %[[RED_OUTER]] -> %[[RED_INNER:.*]] : !fir.ref) + ! CHECK-NEXT: omp.loop_nest + ! CHECK: %[[RED_DECL:.*]]:2 = hlfir.declare %[[RED_INNER]] + ! CHECK: %[[RED:.*]] = fir.load %[[RED_DECL]]#0 : !fir.ref + ! CHECK: %[[RESULT:.*]] = arith.addi %[[RED]], %{{.*}} : i32 + ! CHECK: hlfir.assign %[[RESULT]] to %[[RED_DECL]]#0 : i32, !fir.ref + ! CHECK-NEXT: omp.yield + !$omp do simd reduction(+:sum) +do index_ = 1, 10 + sum = sum + 1 +end do + !$omp end do simd +end subroutine do_simd_reduction ___ 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] Access full list of entry block syms and vars (NFC) (PR #113681)
https://github.com/skatrak created https://github.com/llvm/llvm-project/pull/113681 This patch adds methods to `EntryBlockArgs` to access the full list of entry block argument-related symbols and variables, in their standard order. This helps centralizing this logic in as few places as possible to avoid future inconsistencies. >From 1e73f9391304043806276e0fb19d8089feb70f38 Mon Sep 17 00:00:00 2001 From: Sergio Afonso Date: Fri, 25 Oct 2024 11:33:50 +0100 Subject: [PATCH] [Flang][OpenMP] Access full list of entry block syms and vars (NFC) This patch adds methods to `EntryBlockArgs` to access the full list of entry block argument-related symbols and variables, in their standard order. This helps centralizing this logic in as few places as possible to avoid future inconsistencies. --- flang/lib/Lower/OpenMP/OpenMP.cpp | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index fc54da8babe63e..e2545a68241004 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -76,6 +76,18 @@ struct EntryBlockArgs { reduction.isValid() && taskReduction.isValid() && useDeviceAddr.isValid() && useDevicePtr.isValid(); } + + auto getSyms() const { +return llvm::concat( +inReduction.syms, map.syms, priv.syms, reduction.syms, +taskReduction.syms, useDeviceAddr.syms, useDevicePtr.syms); + } + + auto getVars() const { +return llvm::concat( +inReduction.vars, map.vars, priv.vars, reduction.vars, +taskReduction.vars, useDeviceAddr.vars, useDevicePtr.vars); + } }; } // namespace @@ -1506,8 +1518,7 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable, genEntryBlock(converter, args, op->getRegion(0)); bindEntryBlockArgs( converter, llvm::cast(op), args); -return llvm::to_vector(llvm::concat( -args.priv.syms, args.reduction.syms)); +return llvm::to_vector(args.getSyms()); }; assert((!enableDelayedPrivatization || dsp) && @@ -1581,11 +1592,11 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, mlir::Operation *terminator = lower::genOpenMPTerminator(builder, sectionsOp, loc); - auto reductionCallback = [&](mlir::Operation *op) { + auto genRegionEntryCB = [&](mlir::Operation *op) { genEntryBlock(converter, args, op->getRegion(0)); bindEntryBlockArgs( converter, llvm::cast(op), args); -return reductionSyms; +return llvm::to_vector(args.getSyms()); }; // Generate nested SECTION constructs. @@ -1611,7 +1622,7 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, OpWithBodyGenInfo(converter, symTable, semaCtx, loc, nestedEval, llvm::omp::Directive::OMPD_section) .setClauses(§ionQueue.begin()->clauses) -.setGenRegionEntryCb(reductionCallback), +.setGenRegionEntryCb(genRegionEntryCB), sectionQueue, sectionQueue.begin()); } ___ 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] Properly bind arguments of composite operations (PR #113682)
skatrak wrote: PR stack: - #113680 - #113681 - #113682 - #113683 https://github.com/llvm/llvm-project/pull/113682 ___ 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] [StructuralHash] Support Differences (PR #112638)
https://github.com/ilovepi approved this pull request. LGTM from my perspective. Do check w/ @ellishg before landing, though. And thanks for working on this :) https://github.com/llvm/llvm-project/pull/112638 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -361,6 +414,16 @@ class DataLayout { return PTy && isNonIntegralPointerType(PTy); } + bool shouldAvoidPtrToInt(Type *Ty) const { +auto *PTy = dyn_cast(Ty); +return PTy && shouldAvoidPtrToInt(PTy->getPointerAddressSpace()); jrtc27 wrote: It seems odd to ask about ptrtoint for something where you don't know it's a pointer already, but I guess this is to match isNonIntegralPointerType which seems to have a decent number of uses. https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation jrtc27 wrote: Is non-integral the right term for something that is _more than_ just an integer? https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could jrtc27 wrote: ```suggestion type used with copying garbage collection where the garbage collector could ``` https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -419,9 +420,24 @@ Error DataLayout::parsePointerSpec(StringRef Spec) { // Address space. Optional, defaults to 0. unsigned AddrSpace = 0; - if (!Components[0].empty()) -if (Error Err = parseAddrSpace(Components[0], AddrSpace)) + bool UnstableRepr = false; + bool NonIntegralRepr = false; + StringRef AddrSpaceStr = Components[0].drop_while([&](char C) { +if (C == 'n') { + NonIntegralRepr = true; + return true; +} else if (C == 'u') { + UnstableRepr = true; + return true; +} +return false; + }); + if (!AddrSpaceStr.empty()) { +if (Error Err = parseAddrSpace(AddrSpaceStr, AddrSpace)) return Err; + } + if (AddrSpace == 0 && (NonIntegralRepr || UnstableRepr)) +return createStringError("address space 0 cannot be non-integral"); jrtc27 wrote: The check is for non-integral or unstable, but this only mentions the former https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the jrtc27 wrote: ```suggestion The exact implications of these properties are target-specific, but the ``` https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -342,14 +346,63 @@ class DataLayout { SmallVector getNonIntegralAddressSpaces() const { jrtc27 wrote: This name seems stale given it's including unstable pointers https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -3082,16 +3129,21 @@ as follows: ``A`` Specifies the address space of objects created by '``alloca``'. Defaults to the default address space of 0. -``p[n]::[:][:]`` +``p[][]::[:][:]`` This specifies the *size* of a pointer and its and \erred alignments for address space ``n``. is optional and defaults to . The fourth parameter is the size of the index that used for address calculation, which must be less than or equal to the pointer size. If not specified, the default index size is equal to the pointer size. All sizes -are in bits. The address space, ``n``, is optional, and if not specified, -denotes the default address space 0. The value of ``n`` must be -in the range [1,2^24). +are in bits. The , is optional, and if not specified, +denotes the default address space 0. The value of must +be in the range [1,2^24). +The optional are used to specify properties of pointers in this jrtc27 wrote: Is it legal to have the same flag appear multiple times? https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. jrtc27 wrote: At least with CHERI one can turn an integer into a pointer, it's just not a valid pointer (i.e. things like `#define SIG_IGN ((__sighandler_t *)1)` work, the pointer just can't be used as anything other than a sentinel to pass around or compare against). Is that something to discuss here (/ is it also true for AMDGPU's buffer descriptors)? https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -342,14 +346,63 @@ class DataLayout { SmallVector getNonIntegralAddressSpaces() const { SmallVector AddrSpaces; for (const PointerSpec &PS : PointerSpecs) { - if (PS.IsNonIntegral) + if (PS.HasNonIntegralRepresentation || PS.HasUnstableRepresentation) AddrSpaces.push_back(PS.AddrSpace); } return AddrSpaces; } + /// Returns whether this address space is "non-integral" and "unstable". + /// This means that passes should not introduce inttoptr or ptrtoint + /// instructions operating on pointers of this address space. + /// TODO: remove this function after migrating to finer-grained properties. bool isNonIntegralAddressSpace(unsigned AddrSpace) const { -return getPointerSpec(AddrSpace).IsNonIntegral; +const PointerSpec &PS = getPointerSpec(AddrSpace); +return PS.HasNonIntegralRepresentation || PS.HasUnstableRepresentation; + } + + /// Returns whether this address space has an "unstable" pointer + /// representation. The bitwise pattern of such pointers is allowed to change + /// in a target-specific way. For example, this could be used for copying + /// garbage collection where the garbage collector could update the pointer + /// value as part of the collection sweep. + bool hasUnstableRepresentation(unsigned AddrSpace) const { +return getPointerSpec(AddrSpace).HasUnstableRepresentation; + } + + /// Returns whether this address space has a non-integral pointer + /// representation, i.e. the pointer is not just an integer address but some + /// other bitwise representation. Examples include AMDGPU buffer descriptors + /// with a 128-bit fat pointer and a 32-bit offset or CHERI capabilities that + /// contain bounds, permissions and an out-of-band validity bit. In general, + /// these pointers cannot be re-created from just an integer value. + bool hasNonIntegralRepresentation(unsigned AddrSpace) const { +return getPointerSpec(AddrSpace).HasNonIntegralRepresentation; + } + + /// Returns whether passes should avoid introducing `inttoptr` instructions + /// for this address space. + /// + /// This is currently the case "non-integral" pointer representations + /// (hasNonIntegralRepresentation()) since such pointers generally require + /// additional metadata beyond just an address. + /// New `inttoptr` instructions should also be avoided for "unstable" bitwise + /// representations (hasUnstableRepresentation()) unless the pass knows it is + /// within a critical section that retains the current representation. + bool shouldAvoidIntToPtr(unsigned AddrSpace) const { +const PointerSpec &PS = getPointerSpec(AddrSpace); +return PS.HasNonIntegralRepresentation || PS.HasUnstableRepresentation; jrtc27 wrote: Use the helpers? This is the only one that doesn't (other than the deprecated isNonIntegralAddressSpace). https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include jrtc27 wrote: ```suggestion Pointers are not represented as just an address, but may instead include ``` https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -342,14 +346,63 @@ class DataLayout { SmallVector getNonIntegralAddressSpaces() const { SmallVector AddrSpaces; for (const PointerSpec &PS : PointerSpecs) { - if (PS.IsNonIntegral) + if (PS.HasNonIntegralRepresentation || PS.HasUnstableRepresentation) AddrSpaces.push_back(PS.AddrSpace); } return AddrSpaces; } + /// Returns whether this address space is "non-integral" and "unstable". + /// This means that passes should not introduce inttoptr or ptrtoint + /// instructions operating on pointers of this address space. + /// TODO: remove this function after migrating to finer-grained properties. bool isNonIntegralAddressSpace(unsigned AddrSpace) const { -return getPointerSpec(AddrSpace).IsNonIntegral; +const PointerSpec &PS = getPointerSpec(AddrSpace); +return PS.HasNonIntegralRepresentation || PS.HasUnstableRepresentation; + } + + /// Returns whether this address space has an "unstable" pointer + /// representation. The bitwise pattern of such pointers is allowed to change + /// in a target-specific way. For example, this could be used for copying + /// garbage collection where the garbage collector could update the pointer + /// value as part of the collection sweep. + bool hasUnstableRepresentation(unsigned AddrSpace) const { +return getPointerSpec(AddrSpace).HasUnstableRepresentation; + } + + /// Returns whether this address space has a non-integral pointer + /// representation, i.e. the pointer is not just an integer address but some + /// other bitwise representation. Examples include AMDGPU buffer descriptors + /// with a 128-bit fat pointer and a 32-bit offset or CHERI capabilities that + /// contain bounds, permissions and an out-of-band validity bit. In general, + /// these pointers cannot be re-created from just an integer value. + bool hasNonIntegralRepresentation(unsigned AddrSpace) const { +return getPointerSpec(AddrSpace).HasNonIntegralRepresentation; + } + + /// Returns whether passes should avoid introducing `inttoptr` instructions + /// for this address space. + /// + /// This is currently the case "non-integral" pointer representations + /// (hasNonIntegralRepresentation()) since such pointers generally require + /// additional metadata beyond just an address. + /// New `inttoptr` instructions should also be avoided for "unstable" bitwise + /// representations (hasUnstableRepresentation()) unless the pass knows it is + /// within a critical section that retains the current representation. + bool shouldAvoidIntToPtr(unsigned AddrSpace) const { +const PointerSpec &PS = getPointerSpec(AddrSpace); +return PS.HasNonIntegralRepresentation || PS.HasUnstableRepresentation; arichardson wrote: Fair point, the inliner should take care of any redundancy. https://github.com/llvm/llvm-project/pull/105735 ___ 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] [TableGen] Remove a pointless check for iPTRAny (PR #113732)
https://github.com/jrtc27 created https://github.com/llvm/llvm-project/pull/113732 We've already called EnforceInteger on Types[0], and iPTRAny isn't regarded as an integer type (note that TableGen special-cases iPTR here to include that, though), so we cannot possibly still have an iPTRAny by this point. Delete the check, and let getFixedSizeInBits catch it along with all the other overloaded types if that ever becomes false. Also document why we have this check whilst here. ___ 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] [CodeGen] Rename MVT::iPTRAny to MVT::pAny (PR #113733)
llvmbot wrote: @llvm/pr-subscribers-mlir-llvm Author: Jessica Clarke (jrtc27) Changes Whilst in upstream LLVM iPTRAny is only ever an integer, essentially an alias for iPTR, this is not true in CHERI LLVM, where it gets used to mean "iPTR or cPTR", i.e. either an integer address or a capability (with cPTR and cN being the capability equivalents of iPTR and iN). Moreover, iPTRAny is already not itself regarded as an integer (calling isInteger() will give false), so the "i" prefix is misleading, and it stands out as different from all the other xAny that have a single letter prefix denoting their type. Thus, rename it to pAny, reflecting that it is an overloaded pointer type, which could end up being specialised to an integer type, but does not have to be. This has been verified to have no effect on the generated files for LLVM itself or any in-tree target beyond the replacement of the identifier iPTRAny with pAny in GenVT.inc. --- Full diff: https://github.com/llvm/llvm-project/pull/113733.diff 8 Files Affected: - (modified) llvm/include/llvm/CodeGen/ValueTypes.h (+1-1) - (modified) llvm/include/llvm/CodeGen/ValueTypes.td (+2-2) - (modified) llvm/include/llvm/CodeGenTypes/MachineValueType.h (+1-1) - (modified) llvm/include/llvm/IR/Intrinsics.h (+1-1) - (modified) llvm/include/llvm/IR/Intrinsics.td (+3-3) - (modified) llvm/lib/Target/NVPTX/NVPTXInstrInfo.td (+1-1) - (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp (+2-2) - (modified) mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp (+1-1) ``diff diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index 3db6f33a8093f0..a6301f0b6135f3 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -230,7 +230,7 @@ namespace llvm { /// Return true if this is an overloaded type for TableGen. bool isOverloaded() const { - return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny); + return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::pAny); } /// Return true if the bit size is a multiple of 8. diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td index 493c0cfcab60ce..6d6b92958b4321 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/llvm/include/llvm/CodeGen/ValueTypes.td @@ -338,9 +338,9 @@ def MetadataVT : ValueType<0, 505> { // Metadata let LLVMName = "Metadata"; } -// Pseudo valuetype mapped to the current pointer size to any address space. +// Pseudo valuetype to represent "pointer to any address space" // Should only be used in TableGen. -def iPTRAny: VTAny<506>; +def pAny : VTAny<506>; // Pseudo valuetype to represent "vector of any size" // Should only be used in TableGen. diff --git a/llvm/include/llvm/CodeGenTypes/MachineValueType.h b/llvm/include/llvm/CodeGenTypes/MachineValueType.h index c9a5098ef1623e..5c47ad4824a791 100644 --- a/llvm/include/llvm/CodeGenTypes/MachineValueType.h +++ b/llvm/include/llvm/CodeGenTypes/MachineValueType.h @@ -320,7 +320,7 @@ namespace llvm { llvm_unreachable("Value type is non-standard value, Other."); case iPTR: llvm_unreachable("Value type size is target-dependent. Ask TLI."); - case iPTRAny: + case pAny: case iAny: case fAny: case vAny: diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index e893295e3272b9..89dfff256e0c43 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -92,7 +92,7 @@ namespace Intrinsic { /// return the existing declaration. /// /// The \p Tys parameter is for intrinsics with overloaded types (e.g., those - /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded + /// using iAny, fAny, vAny, or pAny). For a declaration of an overloaded /// intrinsic, Tys must provide exactly one type for each overloaded type in /// the intrinsic. Function *getOrInsertDeclaration(Module *M, ID id, ArrayRef Tys = {}); diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 94e53f372127da..09f446326e2463 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -388,7 +388,7 @@ class LLVMAnyType : LLVMType { !eq(vt, iAny): ArgKind.AnyInteger, !eq(vt, fAny): ArgKind.AnyFloat, !eq(vt, vAny): ArgKind.AnyVector, -!eq(vt, iPTRAny) : ArgKind.AnyPointer, +!eq(vt, pAny): ArgKind.AnyPointer, ); let Sig = [ IIT_ARG.Number, @@ -412,8 +412,8 @@ class LLVMQualPointerType ]); } -class LLVMAnyPointerType : LLVMAnyType { - assert isAny, "iPTRAny should have isOverloaded"; +class LLVMAnyPointerType : LLVMAnyType { + assert isAny, "pAny should have isOverloaded"; } // Match the type of another intrinsic parameter. Number is an index into the diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrI
[llvm-branch-commits] [TableGen] Remove a pointless check for iPTRAny (PR #113732)
https://github.com/jrtc27 updated https://github.com/llvm/llvm-project/pull/113732 ___ 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] [CodeGen] Rename MVT::iPTRAny to MVT::pAny (PR #113733)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 3b927fa6d74e47c6e767d44b4b109ecce86f8453 24923b7f429db6387ad077cb592de78289a4b5cd --extensions h,cpp -- llvm/include/llvm/CodeGen/ValueTypes.h llvm/include/llvm/CodeGenTypes/MachineValueType.h llvm/include/llvm/IR/Intrinsics.h llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp `` View the diff from clang-format here. ``diff diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index a6301f0b61..4de1097392 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -230,7 +230,8 @@ namespace llvm { /// Return true if this is an overloaded type for TableGen. bool isOverloaded() const { - return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::pAny); + return (V == MVT::iAny || V == MVT::fAny || V == MVT::vAny || + V == MVT::pAny); } /// Return true if the bit size is a multiple of 8. `` https://github.com/llvm/llvm-project/pull/113733 ___ 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] [TableGen] Remove a pointless check for iPTRAny (PR #113732)
llvmbot wrote: @llvm/pr-subscribers-tablegen Author: Jessica Clarke (jrtc27) Changes We've already called EnforceInteger on Types[0], and iPTRAny isn't regarded as an integer type (note that TableGen special-cases iPTR here to include that, though), so we cannot possibly still have an iPTRAny by this point. Delete the check, and let getFixedSizeInBits catch it along with all the other overloaded types if that ever becomes false. Also document why we have this check whilst here. --- Full diff: https://github.com/llvm/llvm-project/pull/113732.diff 1 Files Affected: - (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp (+2-1) ``diff diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp index d2228c902a56b4..3446bfeb3e7e19 100644 --- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp @@ -2461,7 +2461,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { ValueTypeByHwMode VVT = TP.getInfer().getConcrete(Types[0], false); for (auto &P : VVT) { MVT::SimpleValueType VT = P.second.SimpleTy; -if (VT == MVT::iPTR || VT == MVT::iPTRAny) +// Can only check for types of a known size +if (VT == MVT::iPTR) continue; unsigned Size = MVT(VT).getFixedSizeInBits(); // Make sure that the value is representable for this type. `` https://github.com/llvm/llvm-project/pull/113732 ___ 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] [TableGen] Remove a pointless check for iPTRAny (PR #113732)
https://github.com/jrtc27 updated https://github.com/llvm/llvm-project/pull/113732 ___ 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] [CodeGen] Rename MVT::iPTRAny to MVT::pAny (PR #113733)
https://github.com/jrtc27 updated https://github.com/llvm/llvm-project/pull/113733 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/105735 >From e4bd1181d160b8728e7d4158417a83e183bd1709 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 22 Aug 2024 14:36:04 -0700 Subject: [PATCH 1/2] fix indentation in langref Created using spr 1.3.6-beta.1 --- llvm/docs/LangRef.rst | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 200224c78be004..1a59fba65815cc 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3103,19 +3103,19 @@ as follows: ``A`` Specifies the address space of objects created by '``alloca``'. Defaults to the default address space of 0. -``p[][n]::[:][:]`` +``p[][]::[:][:]`` This specifies the *size* of a pointer and its and \erred alignments for address space ``n``. is optional and defaults to . The fourth parameter is the size of the index that used for address calculation, which must be less than or equal to the pointer size. If not specified, the default index size is equal to the pointer size. All sizes -are in bits. The address space, ``n``, is optional, and if not specified, -denotes the default address space 0. The value of ``n`` must be -in the range [1,2^24). +are in bits. The , is optional, and if not specified, +denotes the default address space 0. The value of must +be in the range [1,2^24). The optional are used to specify properties of pointers in this -address space: the character ``u`` marks pointers as having an unstable -representation and ```n`` marks pointers as non-integral (i.e. having +address space: the character ``u`` marks pointers as having an unstable +representation and ``n`` marks pointers as non-integral (i.e. having additional metadata). See :ref:`Non-Integral Pointer Types `. ``i:[:]`` >From db97145d3a653f2999b5935f9b1cb4550230689d Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 25 Oct 2024 12:51:11 -0700 Subject: [PATCH 2/2] include feedback Created using spr 1.3.6-beta.1 --- llvm/docs/LangRef.rst | 30 +- llvm/include/llvm/IR/DataLayout.h | 8 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index c137318af678b6..3c3d0e0b4ab8ee 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -659,7 +659,7 @@ LLVM IR optionally allows the frontend to denote pointers in certain address spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") via the :ref:`datalayout string`. -These exact implications of these properties are target-specific, but the +The exact implications of these properties are target-specific, but the following IR semantics and restrictions to optimization passes apply: Unstable pointer representation @@ -668,7 +668,7 @@ Unstable pointer representation Pointers in this address space have an *unspecified* bitwise representation (i.e. not backed by a fixed integer). The bitwise pattern of such pointers is allowed to change in a target-specific way. For example, this could be a pointer -type used for with copying garbage collection where the garbage collector could +type used with copying garbage collection where the garbage collector could update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for @@ -705,10 +705,10 @@ representation of the pointer. Non-integral pointer representation ^^^ -Pointers are not represented as an address, but may instead include +Pointers are not represented as just an address, but may instead include additional metadata such as bounds information or a temporal identifier. Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a -32-bit offset or CHERI capabilities that contain bounds, permissions and an +32-bit offset, or CHERI capabilities that contain bounds, permissions and an out-of-band validity bit. In general, these pointers cannot be re-created from just an integer value. @@ -716,23 +716,25 @@ In most cases pointers with a non-integral representation behave exactly the same as an integral pointer, the only difference is that it is not possible to create a pointer just from an address. -"Non-integral" pointers also impose restrictions on the optimizer, but in -general these are less restrictive than for "unstable" pointers. The main +"Non-integral" pointers also impose restrictions on transformation passes, but +in general these are less restrictive than for "unstable" pointers. The main difference compared to integral pointers is that ``inttoptr`` instructions should not be inserted by passes as they may not be able to create a valid pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be folded to ``x`` as the ``
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation arichardson wrote: Naming is hard - I kept this pre-existing name since it can also be interpreted as _not just an integer_, i.e. it can be anything else (such as integer+metadata). https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/105735 >From e4bd1181d160b8728e7d4158417a83e183bd1709 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 22 Aug 2024 14:36:04 -0700 Subject: [PATCH 1/3] fix indentation in langref Created using spr 1.3.6-beta.1 --- llvm/docs/LangRef.rst | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 200224c78be004..1a59fba65815cc 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3103,19 +3103,19 @@ as follows: ``A`` Specifies the address space of objects created by '``alloca``'. Defaults to the default address space of 0. -``p[][n]::[:][:]`` +``p[][]::[:][:]`` This specifies the *size* of a pointer and its and \erred alignments for address space ``n``. is optional and defaults to . The fourth parameter is the size of the index that used for address calculation, which must be less than or equal to the pointer size. If not specified, the default index size is equal to the pointer size. All sizes -are in bits. The address space, ``n``, is optional, and if not specified, -denotes the default address space 0. The value of ``n`` must be -in the range [1,2^24). +are in bits. The , is optional, and if not specified, +denotes the default address space 0. The value of must +be in the range [1,2^24). The optional are used to specify properties of pointers in this -address space: the character ``u`` marks pointers as having an unstable -representation and ```n`` marks pointers as non-integral (i.e. having +address space: the character ``u`` marks pointers as having an unstable +representation and ``n`` marks pointers as non-integral (i.e. having additional metadata). See :ref:`Non-Integral Pointer Types `. ``i:[:]`` >From db97145d3a653f2999b5935f9b1cb4550230689d Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 25 Oct 2024 12:51:11 -0700 Subject: [PATCH 2/3] include feedback Created using spr 1.3.6-beta.1 --- llvm/docs/LangRef.rst | 30 +- llvm/include/llvm/IR/DataLayout.h | 8 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index c137318af678b6..3c3d0e0b4ab8ee 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -659,7 +659,7 @@ LLVM IR optionally allows the frontend to denote pointers in certain address spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") via the :ref:`datalayout string`. -These exact implications of these properties are target-specific, but the +The exact implications of these properties are target-specific, but the following IR semantics and restrictions to optimization passes apply: Unstable pointer representation @@ -668,7 +668,7 @@ Unstable pointer representation Pointers in this address space have an *unspecified* bitwise representation (i.e. not backed by a fixed integer). The bitwise pattern of such pointers is allowed to change in a target-specific way. For example, this could be a pointer -type used for with copying garbage collection where the garbage collector could +type used with copying garbage collection where the garbage collector could update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for @@ -705,10 +705,10 @@ representation of the pointer. Non-integral pointer representation ^^^ -Pointers are not represented as an address, but may instead include +Pointers are not represented as just an address, but may instead include additional metadata such as bounds information or a temporal identifier. Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a -32-bit offset or CHERI capabilities that contain bounds, permissions and an +32-bit offset, or CHERI capabilities that contain bounds, permissions and an out-of-band validity bit. In general, these pointers cannot be re-created from just an integer value. @@ -716,23 +716,25 @@ In most cases pointers with a non-integral representation behave exactly the same as an integral pointer, the only difference is that it is not possible to create a pointer just from an address. -"Non-integral" pointers also impose restrictions on the optimizer, but in -general these are less restrictive than for "unstable" pointers. The main +"Non-integral" pointers also impose restrictions on transformation passes, but +in general these are less restrictive than for "unstable" pointers. The main difference compared to integral pointers is that ``inttoptr`` instructions should not be inserted by passes as they may not be able to create a valid pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be folded to ``x`` as the ``
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. arichardson wrote: I've made this a bit more explicit, let me know what you think. https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -3082,16 +3129,21 @@ as follows: ``A`` Specifies the address space of objects created by '``alloca``'. Defaults to the default address space of 0. -``p[n]::[:][:]`` +``p[][]::[:][:]`` This specifies the *size* of a pointer and its and \erred alignments for address space ``n``. is optional and defaults to . The fourth parameter is the size of the index that used for address calculation, which must be less than or equal to the pointer size. If not specified, the default index size is equal to the pointer size. All sizes -are in bits. The address space, ``n``, is optional, and if not specified, -denotes the default address space 0. The value of ``n`` must be -in the range [1,2^24). +are in bits. The , is optional, and if not specified, +denotes the default address space 0. The value of must +be in the range [1,2^24). +The optional are used to specify properties of pointers in this arichardson wrote: The implementation currently allows this but I don't think we need to specify it either way. Most other datalayout properties can be defined multiple times with "last one wins" semantics. https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -649,48 +649,95 @@ literal types are uniqued in recent versions of LLVM. .. _nointptrtype: -Non-Integral Pointer Type -- +Non-Integral and Unstable Pointer Types +--- -Note: non-integral pointer types are a work in progress, and they should be -considered experimental at this time. +Note: non-integral/unstable pointer types are a work in progress, and they +should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address -spaces as "non-integral" via the :ref:`datalayout string`. -Non-integral pointer types represent pointers that have an *unspecified* bitwise -representation; that is, the integral representation may be target dependent or -unstable (not backed by a fixed integer). +spaces as "non-integral" or "unstable" (or both "non-integral" and "unstable") +via the :ref:`datalayout string`. + +These exact implications of these properties are target-specific, but the +following IR semantics and restrictions to optimization passes apply: + +Unstable pointer representation +^^^ + +Pointers in this address space have an *unspecified* bitwise representation +(i.e. not backed by a fixed integer). The bitwise pattern of such pointers is +allowed to change in a target-specific way. For example, this could be a pointer +type used for with copying garbage collection where the garbage collector could +update the pointer at any time in the collection sweep. ``inttoptr`` and ``ptrtoint`` instructions have the same semantics as for integral (i.e. normal) pointers in that they convert integers to and from -corresponding pointer types, but there are additional implications to be -aware of. Because the bit-representation of a non-integral pointer may -not be stable, two identical casts of the same operand may or may not +corresponding pointer types, but there are additional implications to be aware +of. + +For "unstable" pointer representations, the bit-representation of the pointer +may not be stable, so two identical casts of the same operand may or may not return the same value. Said differently, the conversion to or from the -non-integral type depends on environmental state in an implementation +"unstable" pointer type depends on environmental state in an implementation defined manner. - If the frontend wishes to observe a *particular* value following a cast, the generated IR must fence with the underlying environment in an implementation defined manner. (In practice, this tends to require ``noinline`` routines for such operations.) From the perspective of the optimizer, ``inttoptr`` and ``ptrtoint`` for -non-integral types are analogous to ones on integral types with one +"unstable" pointer types are analogous to ones on integral types with one key exception: the optimizer may not, in general, insert new dynamic occurrences of such casts. If a new cast is inserted, the optimizer would need to either ensure that a) all possible values are valid, or b) appropriate fencing is inserted. Since the appropriate fencing is implementation defined, the optimizer can't do the latter. The former is challenging as many commonly expected properties, such as -``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types. +``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for "unstable" pointer types. Similar restrictions apply to intrinsics that might examine the pointer bits, such as :ref:`llvm.ptrmask`. -The alignment information provided by the frontend for a non-integral pointer +The alignment information provided by the frontend for an "unstable" pointer (typically using attributes or metadata) must be valid for every possible representation of the pointer. +Non-integral pointer representation +^^^ + +Pointers are not represented as an address, but may instead include +additional metadata such as bounds information or a temporal identifier. +Examples include AMDGPU buffer descriptors with a 128-bit fat pointer and a +32-bit offset or CHERI capabilities that contain bounds, permissions and an +out-of-band validity bit. In general, these pointers cannot be re-created +from just an integer value. + +In most cases pointers with a non-integral representation behave exactly the +same as an integral pointer, the only difference is that it is not possible to +create a pointer just from an address. + +"Non-integral" pointers also impose restrictions on the optimizer, but in +general these are less restrictive than for "unstable" pointers. The main +difference compared to integral pointers is that ``inttoptr`` instructions +should not be inserted by passes as they may not be able to create a valid +pointer. This property also means that ``inttoptr(ptrtoint(x))`` cannot be +folded to ``x`` as the ``ptrtoint`` operation may destroy the necessary metadata +to reconstruct the pointer. +Additiona
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff c55290e17cfbf099942dc4975e9a78612c940650 94ecfa353dcf44087797594a8f77f9653c8b8e4a --extensions h,cpp -- llvm/include/llvm/IR/DataLayout.h llvm/lib/IR/DataLayout.cpp llvm/unittests/IR/DataLayoutTest.cpp `` View the diff from clang-format here. ``diff diff --git a/llvm/unittests/IR/DataLayoutTest.cpp b/llvm/unittests/IR/DataLayoutTest.cpp index 8b6616ce0f..f8efc411f8 100644 --- a/llvm/unittests/IR/DataLayoutTest.cpp +++ b/llvm/unittests/IR/DataLayoutTest.cpp @@ -412,7 +412,8 @@ TEST(DataLayout, ParsePointerSpec) { "pn0:64:64", "pu0:64:64", "pun0:64:64", "pnu0:64:64"}) EXPECT_THAT_EXPECTED( DataLayout::parse(Str), -FailedWithMessage("address space 0 cannot be non-integral or unstable")); +FailedWithMessage( +"address space 0 cannot be non-integral or unstable")); } TEST(DataLayoutTest, ParseNativeIntegersSpec) { `` https://github.com/llvm/llvm-project/pull/105735 ___ 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] MachineUniformityAnalysis: Improve isConstantOrUndefValuePhi (PR #112866)
@@ -54,9 +54,28 @@ const MachineBasicBlock *MachineSSAContext::getDefBlock(Register value) const { return F->getRegInfo().getVRegDef(value)->getParent(); } +static bool isUndef(const MachineInstr &MI) { + return MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF || + MI.getOpcode() == TargetOpcode::IMPLICIT_DEF; +} + +/// MachineInstr equivalent of PHINode::hasConstantOrUndefValue() template <> -bool MachineSSAContext::isConstantOrUndefValuePhi(const MachineInstr &Phi) { - return Phi.isConstantValuePHI(); +bool MachineSSAContext::isConstantOrUndefValuePhi(const MachineInstr &MI) { + if (!MI.isPHI()) +return false; + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); + Register This = MI.getOperand(0).getReg(); + Register ConstantValue; + for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) { +Register Incoming = MI.getOperand(i).getReg(); +if (Incoming != This && !isUndef(*MRI.getVRegDef(Incoming))) { arsenm wrote: It's probably not useful to handle PHI. The only context where we might use them now that might want understanding is the waterfall loop code? https://github.com/llvm/llvm-project/pull/112866 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -342,14 +346,63 @@ class DataLayout { SmallVector getNonIntegralAddressSpaces() const { arichardson wrote: I've changed it to getNonStandardAddressSpaces() - not too important since it's only used in unit tests right now. https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -419,9 +420,25 @@ Error DataLayout::parsePointerSpec(StringRef Spec) { // Address space. Optional, defaults to 0. unsigned AddrSpace = 0; - if (!Components[0].empty()) -if (Error Err = parseAddrSpace(Components[0], AddrSpace)) + bool UnstableRepr = false; + bool NonIntegralRepr = false; + StringRef AddrSpaceStr = Components[0].drop_while([&](char C) { +if (C == 'n') { + NonIntegralRepr = true; + return true; +} else if (C == 'u') { arsenm wrote: No else after return https://github.com/llvm/llvm-project/pull/105735 ___ 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] Extract OMP version hint into helper functions, NFC (PR #113621)
https://github.com/tblah approved this pull request. https://github.com/llvm/llvm-project/pull/113621 ___ 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] [X86] Avoid generating nested CALLSEQ for TLS pointer function arguments (PR #106965)
@@ -35971,6 +35971,15 @@ X86TargetLowering::EmitLoweredTLSAddr(MachineInstr &MI, // inside MC, therefore without the two markers shrink-wrapping // may push the prologue/epilogue pass them. const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + ritter-x2a wrote: I now opened PR #113706 for an attempt to do that. https://github.com/llvm/llvm-project/pull/106965 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
arichardson wrote: The downstream CHERI fork uses a `f` flag on the pointer spec ("fat pointer") to indentify CHERI capabilities. These have an additional property that partial copies are not possible since they would invalidate the result. I considered adding another flag to prevent splitting of loads/stores but this is not part of this commit. I imagine this property would also be useful for pointer schemes that use out-of-band metadata tables for pointers (e.g. Intel's no longer supported MPX or other similar schemes). Let me know if adding this would also be useful for any other downstreams. https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
https://github.com/arichardson ready_for_review https://github.com/llvm/llvm-project/pull/105735 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/105735 >From e4bd1181d160b8728e7d4158417a83e183bd1709 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 22 Aug 2024 14:36:04 -0700 Subject: [PATCH] fix indentation in langref Created using spr 1.3.6-beta.1 --- llvm/docs/LangRef.rst | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 200224c78be004..1a59fba65815cc 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3103,19 +3103,19 @@ as follows: ``A`` Specifies the address space of objects created by '``alloca``'. Defaults to the default address space of 0. -``p[][n]::[:][:]`` +``p[][]::[:][:]`` This specifies the *size* of a pointer and its and \erred alignments for address space ``n``. is optional and defaults to . The fourth parameter is the size of the index that used for address calculation, which must be less than or equal to the pointer size. If not specified, the default index size is equal to the pointer size. All sizes -are in bits. The address space, ``n``, is optional, and if not specified, -denotes the default address space 0. The value of ``n`` must be -in the range [1,2^24). +are in bits. The , is optional, and if not specified, +denotes the default address space 0. The value of must +be in the range [1,2^24). The optional are used to specify properties of pointers in this -address space: the character ``u`` marks pointers as having an unstable -representation and ```n`` marks pointers as non-integral (i.e. having +address space: the character ``u`` marks pointers as having an unstable +representation and ``n`` marks pointers as non-integral (i.e. having additional metadata). See :ref:`Non-Integral Pointer Types `. ``i:[:]`` ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/105735 >From e4bd1181d160b8728e7d4158417a83e183bd1709 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 22 Aug 2024 14:36:04 -0700 Subject: [PATCH] fix indentation in langref Created using spr 1.3.6-beta.1 --- llvm/docs/LangRef.rst | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 200224c78be004..1a59fba65815cc 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3103,19 +3103,19 @@ as follows: ``A`` Specifies the address space of objects created by '``alloca``'. Defaults to the default address space of 0. -``p[][n]::[:][:]`` +``p[][]::[:][:]`` This specifies the *size* of a pointer and its and \erred alignments for address space ``n``. is optional and defaults to . The fourth parameter is the size of the index that used for address calculation, which must be less than or equal to the pointer size. If not specified, the default index size is equal to the pointer size. All sizes -are in bits. The address space, ``n``, is optional, and if not specified, -denotes the default address space 0. The value of ``n`` must be -in the range [1,2^24). +are in bits. The , is optional, and if not specified, +denotes the default address space 0. The value of must +be in the range [1,2^24). The optional are used to specify properties of pointers in this -address space: the character ``u`` marks pointers as having an unstable -representation and ```n`` marks pointers as non-integral (i.e. having +address space: the character ``u`` marks pointers as having an unstable +representation and ``n`` marks pointers as non-integral (i.e. having additional metadata). See :ref:`Non-Integral Pointer Types `. ``i:[:]`` ___ 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] [StructuralHash] Support Differences (PR #112638)
https://github.com/ellishg edited https://github.com/llvm/llvm-project/pull/112638 ___ 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] [StructuralHash] Support Differences (PR #112638)
@@ -22,3 +26,13 @@ define i32 @f2(i32 %a) { ; DETAILED-HASH-NEXT: Function f1 Hash: [[DF1H:([a-f0-9]{16,})]] ; DETAILED-HASH-NOT: [[DF1H]] ; DETAILED-HASH-NEXT: Function f2 Hash: {{([a-f0-9]{16,})}} + +; When ignoring the call target, check if `f1` and `f2` produce the same function hash. +; The index for the call instruction is 1, and the index of the call target operand is 1. +; The ignored operand hashes for different call targets should be different. +; CALLTARGETIGNORED-HASH: Module Hash: {{([a-f0-9]{16,})}} ellishg wrote: Since these are stable hashes. What do you think about adding the literal hash into the test? This would allow us to know exactly when the hash was changed, otherwise the test fails. I see that you do check that f1 and f2 hash to the same value. Maybe that is good enough. https://github.com/llvm/llvm-project/pull/112638 ___ 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] [StructuralHash] Support Differences (PR #112638)
https://github.com/ellishg approved this pull request. Overall LGTM! https://github.com/llvm/llvm-project/pull/112638 ___ 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] [StructuralHash] Support Differences (PR #112638)
@@ -13,15 +13,18 @@ namespace llvm { +enum class StructuralHashOptions { None, Detailed, CallTargetIgnored }; ellishg wrote: Can you document these options and include their string values, e.g., `call-target-ignored`? https://github.com/llvm/llvm-project/pull/112638 ___ 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] [CodeGen] Rename MVT::iPTRAny to MVT::pAny (PR #113733)
https://github.com/jrtc27 updated https://github.com/llvm/llvm-project/pull/113733 ___ 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] [CodeGen] Rename MVT::iPTRAny to MVT::pAny (PR #113733)
https://github.com/jrtc27 created https://github.com/llvm/llvm-project/pull/113733 Whilst in upstream LLVM iPTRAny is only ever an integer, essentially an alias for iPTR, this is not true in CHERI LLVM, where it gets used to mean "iPTR or cPTR", i.e. either an integer address or a capability (with cPTR and cN being the capability equivalents of iPTR and iN). Moreover, iPTRAny is already not itself regarded as an integer (calling isInteger() will give false), so the "i" prefix is misleading, and it stands out as different from all the other xAny that have a single letter prefix denoting their type. Thus, rename it to pAny, reflecting that it is an overloaded pointer type, which could end up being specialised to an integer type, but does not have to be. This has been verified to have no effect on the generated files for LLVM itself or any in-tree target beyond the replacement of the identifier iPTRAny with pAny in GenVT.inc. ___ 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] [CodeGen] Rename MVT::iPTRAny to MVT::pAny (PR #113733)
llvmbot wrote: @llvm/pr-subscribers-mlir-core Author: Jessica Clarke (jrtc27) Changes Whilst in upstream LLVM iPTRAny is only ever an integer, essentially an alias for iPTR, this is not true in CHERI LLVM, where it gets used to mean "iPTR or cPTR", i.e. either an integer address or a capability (with cPTR and cN being the capability equivalents of iPTR and iN). Moreover, iPTRAny is already not itself regarded as an integer (calling isInteger() will give false), so the "i" prefix is misleading, and it stands out as different from all the other xAny that have a single letter prefix denoting their type. Thus, rename it to pAny, reflecting that it is an overloaded pointer type, which could end up being specialised to an integer type, but does not have to be. This has been verified to have no effect on the generated files for LLVM itself or any in-tree target beyond the replacement of the identifier iPTRAny with pAny in GenVT.inc. --- Full diff: https://github.com/llvm/llvm-project/pull/113733.diff 8 Files Affected: - (modified) llvm/include/llvm/CodeGen/ValueTypes.h (+1-1) - (modified) llvm/include/llvm/CodeGen/ValueTypes.td (+2-2) - (modified) llvm/include/llvm/CodeGenTypes/MachineValueType.h (+1-1) - (modified) llvm/include/llvm/IR/Intrinsics.h (+1-1) - (modified) llvm/include/llvm/IR/Intrinsics.td (+3-3) - (modified) llvm/lib/Target/NVPTX/NVPTXInstrInfo.td (+1-1) - (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp (+2-2) - (modified) mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp (+1-1) ``diff diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index 3db6f33a8093f0..a6301f0b6135f3 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -230,7 +230,7 @@ namespace llvm { /// Return true if this is an overloaded type for TableGen. bool isOverloaded() const { - return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny); + return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::pAny); } /// Return true if the bit size is a multiple of 8. diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td index 493c0cfcab60ce..6d6b92958b4321 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/llvm/include/llvm/CodeGen/ValueTypes.td @@ -338,9 +338,9 @@ def MetadataVT : ValueType<0, 505> { // Metadata let LLVMName = "Metadata"; } -// Pseudo valuetype mapped to the current pointer size to any address space. +// Pseudo valuetype to represent "pointer to any address space" // Should only be used in TableGen. -def iPTRAny: VTAny<506>; +def pAny : VTAny<506>; // Pseudo valuetype to represent "vector of any size" // Should only be used in TableGen. diff --git a/llvm/include/llvm/CodeGenTypes/MachineValueType.h b/llvm/include/llvm/CodeGenTypes/MachineValueType.h index c9a5098ef1623e..5c47ad4824a791 100644 --- a/llvm/include/llvm/CodeGenTypes/MachineValueType.h +++ b/llvm/include/llvm/CodeGenTypes/MachineValueType.h @@ -320,7 +320,7 @@ namespace llvm { llvm_unreachable("Value type is non-standard value, Other."); case iPTR: llvm_unreachable("Value type size is target-dependent. Ask TLI."); - case iPTRAny: + case pAny: case iAny: case fAny: case vAny: diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index e893295e3272b9..89dfff256e0c43 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -92,7 +92,7 @@ namespace Intrinsic { /// return the existing declaration. /// /// The \p Tys parameter is for intrinsics with overloaded types (e.g., those - /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded + /// using iAny, fAny, vAny, or pAny). For a declaration of an overloaded /// intrinsic, Tys must provide exactly one type for each overloaded type in /// the intrinsic. Function *getOrInsertDeclaration(Module *M, ID id, ArrayRef Tys = {}); diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 94e53f372127da..09f446326e2463 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -388,7 +388,7 @@ class LLVMAnyType : LLVMType { !eq(vt, iAny): ArgKind.AnyInteger, !eq(vt, fAny): ArgKind.AnyFloat, !eq(vt, vAny): ArgKind.AnyVector, -!eq(vt, iPTRAny) : ArgKind.AnyPointer, +!eq(vt, pAny): ArgKind.AnyPointer, ); let Sig = [ IIT_ARG.Number, @@ -412,8 +412,8 @@ class LLVMQualPointerType ]); } -class LLVMAnyPointerType : LLVMAnyType { - assert isAny, "iPTRAny should have isOverloaded"; +class LLVMAnyPointerType : LLVMAnyType { + assert isAny, "pAny should have isOverloaded"; } // Match the type of another intrinsic parameter. Number is an index into the diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrI
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -361,6 +414,16 @@ class DataLayout { return PTy && isNonIntegralPointerType(PTy); } + bool shouldAvoidPtrToInt(Type *Ty) const { +auto *PTy = dyn_cast(Ty); +return PTy && shouldAvoidPtrToInt(PTy->getPointerAddressSpace()); arichardson wrote: Yeah I kept this check to allow replacing existing helper calls. https://github.com/llvm/llvm-project/pull/105735 ___ 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] [StructuralHash] Support Differences (PR #112638)
https://github.com/boomanaiden154 approved this pull request. https://github.com/llvm/llvm-project/pull/112638 ___ 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] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -361,6 +414,16 @@ class DataLayout { return PTy && isNonIntegralPointerType(PTy); } + bool shouldAvoidPtrToInt(Type *Ty) const { +auto *PTy = dyn_cast(Ty); +return PTy && shouldAvoidPtrToInt(PTy->getPointerAddressSpace()); arsenm wrote: This also needs to handle the vector of pointer case https://github.com/llvm/llvm-project/pull/105735 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits