[llvm-branch-commits] [llvm] [Vectorizer] fix GEPs incorrectly marked as "inbounds" (PR #120730)
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/120730 >From 5987219575feabd0eefba5932c21b0eba8ae4fb7 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:35:56 -0800 Subject: [PATCH 1/6] simplify Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 0768eccc8aeb35..ffd89466abeea9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,12 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = Builder.CreateGEP( - IndexedTy, Ptr, NumElt, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); - ResultPtr = Builder.CreateGEP( - IndexedTy, ResultPtr, LastLane, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); + Value *ResultPtr = + Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + ResultPtr = + Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); State.set(this, ResultPtr, /*IsScalar*/ true); } >From e4e48cf7e0448f25ccdcdf7d7c262ac880853ddd Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:40:10 -0800 Subject: [PATCH 2/6] address comment Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index ffd89466abeea9..f97cae215ec087 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = - Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); - ResultPtr = - Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + // N.B. we deliberately do not use getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. + Value *ResultPtr = Builder.CreateGEP(IndexedTy, Ptr, NumElt, ""); + ResultPtr = Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, ""); State.set(this, ResultPtr, /*IsScalar*/ true); } >From 88971013ce379e6a7259544666c40c65410c4f00 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 06:12:55 -0800 Subject: [PATCH 3/6] address Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 5 +++-- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 8 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1f6996cd9c1f49..65de01471a91ef 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8436,10 +8436,11 @@ VPRecipeBuilder::tryToWidenMemory(Instruction *I, ArrayRef Operands, Ptr->getUnderlyingValue()->stripPointerCasts()); VPSingleDefRecipe *VectorPtr; if (Reverse) + // N.B. we deliberately do pass getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. VectorPtr = new VPReverseVectorPointerRecipe( Ptr, &Plan.getVF(), getLoadStoreType(I), - GEP && GEP->isInBounds() ? GEPNoWrapFlags::inBounds() - : GEPNoWrapFlags::none(), + GEPNoWrapFlags::none(), I->getDebugLoc()); else VectorPtr = new VPVectorPointerRecipe(Ptr, getLoadStoreType(I), diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index f97cae215ec087..cda90d70e5c8da 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,10 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - // N.B. we deliberately do not use getGEPNoWrapFlags here, because this - // transform can invalidate `inbounds`. -
[llvm-branch-commits] [llvm] [Vectorizer] fix GEPs incorrectly marked as "inbounds" (PR #120730)
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/120730 >From 5987219575feabd0eefba5932c21b0eba8ae4fb7 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:35:56 -0800 Subject: [PATCH 1/6] simplify Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 0768eccc8aeb35..ffd89466abeea9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,12 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = Builder.CreateGEP( - IndexedTy, Ptr, NumElt, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); - ResultPtr = Builder.CreateGEP( - IndexedTy, ResultPtr, LastLane, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); + Value *ResultPtr = + Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + ResultPtr = + Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); State.set(this, ResultPtr, /*IsScalar*/ true); } >From e4e48cf7e0448f25ccdcdf7d7c262ac880853ddd Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:40:10 -0800 Subject: [PATCH 2/6] address comment Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index ffd89466abeea9..f97cae215ec087 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = - Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); - ResultPtr = - Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + // N.B. we deliberately do not use getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. + Value *ResultPtr = Builder.CreateGEP(IndexedTy, Ptr, NumElt, ""); + ResultPtr = Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, ""); State.set(this, ResultPtr, /*IsScalar*/ true); } >From 88971013ce379e6a7259544666c40c65410c4f00 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 06:12:55 -0800 Subject: [PATCH 3/6] address Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 5 +++-- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 8 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1f6996cd9c1f49..65de01471a91ef 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8436,10 +8436,11 @@ VPRecipeBuilder::tryToWidenMemory(Instruction *I, ArrayRef Operands, Ptr->getUnderlyingValue()->stripPointerCasts()); VPSingleDefRecipe *VectorPtr; if (Reverse) + // N.B. we deliberately do pass getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. VectorPtr = new VPReverseVectorPointerRecipe( Ptr, &Plan.getVF(), getLoadStoreType(I), - GEP && GEP->isInBounds() ? GEPNoWrapFlags::inBounds() - : GEPNoWrapFlags::none(), + GEPNoWrapFlags::none(), I->getDebugLoc()); else VectorPtr = new VPVectorPointerRecipe(Ptr, getLoadStoreType(I), diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index f97cae215ec087..cda90d70e5c8da 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,10 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - // N.B. we deliberately do not use getGEPNoWrapFlags here, because this - // transform can invalidate `inbounds`. -
[llvm-branch-commits] [mlir] [mlir][rocdl] Add AMDGPU-specific `cf.assert` lowering (PR #121067)
jhuber6 wrote: > 1. Approved > > 2. Wrt OpenCL ... I hope legalization didn't get broken, but in the > OpenCL flow, pryntf should lower to ... `printf()`, which the compiler will > handle. Or at least that's my recollection of how that goes from staring at > the AMDGPU backend ~a year ago It's complicated, there's like two different flows that either lower `printf` to AMD's hostcall version or to a ring buffer type affair, then if you suppress the transform you just get `printf` symbols which is what my implementation uses. https://github.com/llvm/llvm-project/pull/121067 ___ 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] Accept `cl`-style output arguments (`/Fo`, `-Fo`) for `--fmodule-output` (PR #121046)
nikic wrote: Why is this submitted against the release/19.x branch? Is this a backport? If so, please indicate which commit it backports. https://github.com/llvm/llvm-project/pull/121046 ___ 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/krzysz00 edited 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/krzysz00 commented: Ok, so, first blob of thoughts - overall, this looks right. 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)
@@ -650,48 +650,127 @@ 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`. + +The 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 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 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 a +type field (as well as an out-of-band validity bit, see next section). +In general, valid non-integral pointers cannot becreated from just an integer +value: while ``inttoptr`` yields a deterministic bitwise pattern, the resulting +value is not guaranteed to be a valid dereferenceable pointer. + +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 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 vali
[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
@@ -650,48 +650,127 @@ 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`. + +The 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 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 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 a +type field (as well as an out-of-band validity bit, see next section). +In general, valid non-integral pointers cannot becreated from just an integer +value: while ``inttoptr`` yields a deterministic bitwise pattern, the resulting +value is not guaranteed to be a valid dereferenceable pointer. + +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 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 vali
[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 krzysz00 wrote: So, just to toss out a drive-by name suggestion (though I'm fine with keeping non-integral): how about "annotated" pointers? That is, the pointer does (without unstable) have a fixed representation and point to some address, but there are bits in that representation that "annotate" the address, and so `inttoptr(ptrtoint(v) + x) ??= gep i8, v, x` 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)
@@ -650,48 +650,127 @@ 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`. + +The 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 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 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 a +type field (as well as an out-of-band validity bit, see next section). +In general, valid non-integral pointers cannot becreated from just an integer +value: while ``inttoptr`` yields a deterministic bitwise pattern, the resulting +value is not guaranteed to be a valid dereferenceable pointer. + +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 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 vali
[llvm-branch-commits] [llvm] [Vectorizer] fix GEPs incorrectly marked as "inbounds" (PR #120730)
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/120730 >From 5987219575feabd0eefba5932c21b0eba8ae4fb7 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:35:56 -0800 Subject: [PATCH 1/6] simplify Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 0768eccc8aeb35..ffd89466abeea9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,12 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = Builder.CreateGEP( - IndexedTy, Ptr, NumElt, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); - ResultPtr = Builder.CreateGEP( - IndexedTy, ResultPtr, LastLane, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); + Value *ResultPtr = + Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + ResultPtr = + Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); State.set(this, ResultPtr, /*IsScalar*/ true); } >From e4e48cf7e0448f25ccdcdf7d7c262ac880853ddd Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:40:10 -0800 Subject: [PATCH 2/6] address comment Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index ffd89466abeea9..f97cae215ec087 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = - Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); - ResultPtr = - Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + // N.B. we deliberately do not use getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. + Value *ResultPtr = Builder.CreateGEP(IndexedTy, Ptr, NumElt, ""); + ResultPtr = Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, ""); State.set(this, ResultPtr, /*IsScalar*/ true); } >From 88971013ce379e6a7259544666c40c65410c4f00 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 06:12:55 -0800 Subject: [PATCH 3/6] address Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 5 +++-- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 8 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1f6996cd9c1f49..65de01471a91ef 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8436,10 +8436,11 @@ VPRecipeBuilder::tryToWidenMemory(Instruction *I, ArrayRef Operands, Ptr->getUnderlyingValue()->stripPointerCasts()); VPSingleDefRecipe *VectorPtr; if (Reverse) + // N.B. we deliberately do pass getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. VectorPtr = new VPReverseVectorPointerRecipe( Ptr, &Plan.getVF(), getLoadStoreType(I), - GEP && GEP->isInBounds() ? GEPNoWrapFlags::inBounds() - : GEPNoWrapFlags::none(), + GEPNoWrapFlags::none(), I->getDebugLoc()); else VectorPtr = new VPVectorPointerRecipe(Ptr, getLoadStoreType(I), diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index f97cae215ec087..cda90d70e5c8da 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,10 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - // N.B. we deliberately do not use getGEPNoWrapFlags here, because this - // transform can invalidate `inbounds`. -
[llvm-branch-commits] [llvm] [Vectorizer] fix GEPs incorrectly marked as "inbounds" (PR #120730)
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/120730 >From 5987219575feabd0eefba5932c21b0eba8ae4fb7 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:35:56 -0800 Subject: [PATCH 1/6] simplify Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 0768eccc8aeb35..ffd89466abeea9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,12 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = Builder.CreateGEP( - IndexedTy, Ptr, NumElt, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); - ResultPtr = Builder.CreateGEP( - IndexedTy, ResultPtr, LastLane, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); + Value *ResultPtr = + Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + ResultPtr = + Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); State.set(this, ResultPtr, /*IsScalar*/ true); } >From e4e48cf7e0448f25ccdcdf7d7c262ac880853ddd Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:40:10 -0800 Subject: [PATCH 2/6] address comment Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index ffd89466abeea9..f97cae215ec087 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = - Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); - ResultPtr = - Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + // N.B. we deliberately do not use getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. + Value *ResultPtr = Builder.CreateGEP(IndexedTy, Ptr, NumElt, ""); + ResultPtr = Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, ""); State.set(this, ResultPtr, /*IsScalar*/ true); } >From 88971013ce379e6a7259544666c40c65410c4f00 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 06:12:55 -0800 Subject: [PATCH 3/6] address Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 5 +++-- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 8 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1f6996cd9c1f49..65de01471a91ef 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8436,10 +8436,11 @@ VPRecipeBuilder::tryToWidenMemory(Instruction *I, ArrayRef Operands, Ptr->getUnderlyingValue()->stripPointerCasts()); VPSingleDefRecipe *VectorPtr; if (Reverse) + // N.B. we deliberately do pass getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. VectorPtr = new VPReverseVectorPointerRecipe( Ptr, &Plan.getVF(), getLoadStoreType(I), - GEP && GEP->isInBounds() ? GEPNoWrapFlags::inBounds() - : GEPNoWrapFlags::none(), + GEPNoWrapFlags::none(), I->getDebugLoc()); else VectorPtr = new VPVectorPointerRecipe(Ptr, getLoadStoreType(I), diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index f97cae215ec087..cda90d70e5c8da 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,10 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - // N.B. we deliberately do not use getGEPNoWrapFlags here, because this - // transform can invalidate `inbounds`. -
[llvm-branch-commits] [llvm] [Vectorizer] fix GEPs incorrectly marked as "inbounds" (PR #120730)
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/120730 >From 5987219575feabd0eefba5932c21b0eba8ae4fb7 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:35:56 -0800 Subject: [PATCH 1/6] simplify Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 0768eccc8aeb35..ffd89466abeea9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,12 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = Builder.CreateGEP( - IndexedTy, Ptr, NumElt, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); - ResultPtr = Builder.CreateGEP( - IndexedTy, ResultPtr, LastLane, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); + Value *ResultPtr = + Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + ResultPtr = + Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); State.set(this, ResultPtr, /*IsScalar*/ true); } >From e4e48cf7e0448f25ccdcdf7d7c262ac880853ddd Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:40:10 -0800 Subject: [PATCH 2/6] address comment Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index ffd89466abeea9..f97cae215ec087 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = - Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); - ResultPtr = - Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + // N.B. we deliberately do not use getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. + Value *ResultPtr = Builder.CreateGEP(IndexedTy, Ptr, NumElt, ""); + ResultPtr = Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, ""); State.set(this, ResultPtr, /*IsScalar*/ true); } >From 88971013ce379e6a7259544666c40c65410c4f00 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 06:12:55 -0800 Subject: [PATCH 3/6] address Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 5 +++-- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 8 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1f6996cd9c1f49..65de01471a91ef 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8436,10 +8436,11 @@ VPRecipeBuilder::tryToWidenMemory(Instruction *I, ArrayRef Operands, Ptr->getUnderlyingValue()->stripPointerCasts()); VPSingleDefRecipe *VectorPtr; if (Reverse) + // N.B. we deliberately do pass getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. VectorPtr = new VPReverseVectorPointerRecipe( Ptr, &Plan.getVF(), getLoadStoreType(I), - GEP && GEP->isInBounds() ? GEPNoWrapFlags::inBounds() - : GEPNoWrapFlags::none(), + GEPNoWrapFlags::none(), I->getDebugLoc()); else VectorPtr = new VPVectorPointerRecipe(Ptr, getLoadStoreType(I), diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index f97cae215ec087..cda90d70e5c8da 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,10 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - // N.B. we deliberately do not use getGEPNoWrapFlags here, because this - // transform can invalidate `inbounds`. -
[llvm-branch-commits] [llvm] [Vectorizer] fix GEPs incorrectly marked as "inbounds" (PR #120730)
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/120730 >From 5987219575feabd0eefba5932c21b0eba8ae4fb7 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:35:56 -0800 Subject: [PATCH 1/6] simplify Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 0768eccc8aeb35..ffd89466abeea9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,12 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = Builder.CreateGEP( - IndexedTy, Ptr, NumElt, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); - ResultPtr = Builder.CreateGEP( - IndexedTy, ResultPtr, LastLane, "", - getGEPNoWrapFlags().withoutInBounds().withoutNoUnsignedSignedWrap()); + Value *ResultPtr = + Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + ResultPtr = + Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", +getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); State.set(this, ResultPtr, /*IsScalar*/ true); } >From e4e48cf7e0448f25ccdcdf7d7c262ac880853ddd Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 05:40:10 -0800 Subject: [PATCH 2/6] address comment Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index ffd89466abeea9..f97cae215ec087 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,12 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - Value *ResultPtr = - Builder.CreateGEP(IndexedTy, Ptr, NumElt, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); - ResultPtr = - Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, "", -getGEPNoWrapFlags().withoutNoUnsignedSignedWrap()); + // N.B. we deliberately do not use getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. + Value *ResultPtr = Builder.CreateGEP(IndexedTy, Ptr, NumElt, ""); + ResultPtr = Builder.CreateGEP(IndexedTy, ResultPtr, LastLane, ""); State.set(this, ResultPtr, /*IsScalar*/ true); } >From 88971013ce379e6a7259544666c40c65410c4f00 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 20 Dec 2024 06:12:55 -0800 Subject: [PATCH 3/6] address Created using spr 1.3.4 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 5 +++-- llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 8 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1f6996cd9c1f49..65de01471a91ef 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8436,10 +8436,11 @@ VPRecipeBuilder::tryToWidenMemory(Instruction *I, ArrayRef Operands, Ptr->getUnderlyingValue()->stripPointerCasts()); VPSingleDefRecipe *VectorPtr; if (Reverse) + // N.B. we deliberately do pass getGEPNoWrapFlags here, because this + // transform can invalidate `inbounds`. VectorPtr = new VPReverseVectorPointerRecipe( Ptr, &Plan.getVF(), getLoadStoreType(I), - GEP && GEP->isInBounds() ? GEPNoWrapFlags::inBounds() - : GEPNoWrapFlags::none(), + GEPNoWrapFlags::none(), I->getDebugLoc()); else VectorPtr = new VPVectorPointerRecipe(Ptr, getLoadStoreType(I), diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index f97cae215ec087..cda90d70e5c8da 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1986,10 +1986,10 @@ void VPReverseVectorPointerRecipe::execute(VPTransformState &State) { // LastLane = 1 - RunTimeVF Value *LastLane = Builder.CreateSub(ConstantInt::get(IndexTy, 1), RunTimeVF); Value *Ptr = State.get(getOperand(0), VPLane(0)); - // N.B. we deliberately do not use getGEPNoWrapFlags here, because this - // transform can invalidate `inbounds`. -
[llvm-branch-commits] [flang] [llvm] [mlir] [Flang][OpenMP][MLIR] Initial declare target to for variables implementation (PR #119589)
agozillon wrote: Small ping for some attention on this PR if at all possible please :-) https://github.com/llvm/llvm-project/pull/119589 ___ 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] [llvm] [mlir] [MLIR][OpenMP] Introduce overlapped record type map support (PR #119588)
agozillon wrote: Small ping for some attention on this PR if at all possible please :-) https://github.com/llvm/llvm-project/pull/119588 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][Transforms][NFC] Use `DominanceInfo` to compute materialization insertion point (PR #120746)
https://github.com/zero9178 approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/120746 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][rocdl] Add AMDGPU-specific `cf.assert` lowering (PR #121067)
krzysz00 wrote: Re OpenCL and the linked test: we don't have an integration test for OpenCL's lowering because we don't have a way to execute it https://github.com/llvm/llvm-project/pull/121067 ___ 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] Allow utility constructs in specification part (PR #121509)
https://github.com/tblah approved this pull request. Looks great. Thanks! https://github.com/llvm/llvm-project/pull/121509 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][Transforms][NFC] Use `DominanceInfo` to compute materialization insertion point (PR #120746)
https://github.com/matthias-springer updated https://github.com/llvm/llvm-project/pull/120746 >From b6a6f1c020ede4e1fb3ee586d4544afe04644f82 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Sat, 9 Nov 2024 12:29:16 +0100 Subject: [PATCH] use dominfo --- mlir/include/mlir/IR/Dominance.h | 23 ++ .../Transforms/Utils/DialectConversion.cpp| 70 +-- 2 files changed, 42 insertions(+), 51 deletions(-) diff --git a/mlir/include/mlir/IR/Dominance.h b/mlir/include/mlir/IR/Dominance.h index 63504cad211a4d..9e1254c1dfe1e1 100644 --- a/mlir/include/mlir/IR/Dominance.h +++ b/mlir/include/mlir/IR/Dominance.h @@ -187,6 +187,17 @@ class DominanceInfo : public detail::DominanceInfoBase { /// dominance" of ops, the single block is considered to properly dominate /// itself in a graph region. bool properlyDominates(Block *a, Block *b) const; + + bool properlyDominates(Block *aBlock, Block::iterator aIt, Block *bBlock, + Block::iterator bIt, bool enclosingOk = true) const { +return super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk); + } + + bool dominates(Block *aBlock, Block::iterator aIt, Block *bBlock, + Block::iterator bIt, bool enclosingOk = true) const { +return (aBlock == bBlock && aIt == bIt) || + super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk); + } }; /// A class for computing basic postdominance information. @@ -210,6 +221,18 @@ class PostDominanceInfo : public detail::DominanceInfoBase { bool postDominates(Block *a, Block *b) const { return a == b || properlyPostDominates(a, b); } + + bool properlyPostDominates(Block *aBlock, Block::iterator aIt, Block *bBlock, + Block::iterator bIt, + bool enclosingOk = true) const { +return super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk); + } + + bool postDominates(Block *aBlock, Block::iterator aIt, Block *bBlock, + Block::iterator bIt, bool enclosingOk = true) const { +return (aBlock == bBlock && aIt == bIt) || + super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk); + } }; } // namespace mlir diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index 6c3863e4c7f666..1e689cd96ae711 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -54,55 +54,6 @@ static void logFailure(llvm::ScopedPrinter &os, StringRef fmt, Args &&...args) { }); } -/// Given two insertion points in the same block, choose the later one. -static OpBuilder::InsertPoint -chooseLaterInsertPointInBlock(OpBuilder::InsertPoint a, - OpBuilder::InsertPoint b) { - assert(a.getBlock() == b.getBlock() && "expected same block"); - Block *block = a.getBlock(); - if (a.getPoint() == block->begin()) -return b; - if (b.getPoint() == block->begin()) -return a; - if (a.getPoint()->isBeforeInBlock(&*b.getPoint())) -return b; - return a; -} - -/// Helper function that chooses the insertion point among the two given ones -/// that is later. -// TODO: Extend DominanceInfo API to work with block iterators. -static OpBuilder::InsertPoint chooseLaterInsertPoint(OpBuilder::InsertPoint a, - OpBuilder::InsertPoint b) { - // Case 1: Fast path: Same block. This is the most common case. - if (LLVM_LIKELY(a.getBlock() == b.getBlock())) -return chooseLaterInsertPointInBlock(a, b); - - // Case 2: Different block, but same region. - if (a.getBlock()->getParent() == b.getBlock()->getParent()) { -DominanceInfo domInfo; -if (domInfo.properlyDominates(a.getBlock(), b.getBlock())) - return b; -if (domInfo.properlyDominates(b.getBlock(), a.getBlock())) - return a; -// Neither of the two blocks dominante each other. -llvm_unreachable("unable to find valid insertion point"); - } - - // Case 3: b's region contains a: choose a. - if (b.getBlock()->getParent()->findAncestorOpInRegion( - *a.getPoint()->getParentOp())) -return a; - - // Case 4: a's region contains b: choose b. - if (a.getBlock()->getParent()->findAncestorOpInRegion( - *b.getPoint()->getParentOp())) -return b; - - // Neither of the two operations contain each other. - llvm_unreachable("unable to find valid insertion point"); -} - /// Helper function that computes an insertion point where the given value is /// defined and can be used without a dominance violation. static OpBuilder::InsertPoint computeInsertPoint(Value value) { @@ -117,9 +68,26 @@ static OpBuilder::InsertPoint computeInsertPoint(Value value) { /// defined and can be used without a dominance violation. static OpBuilder::InsertPoint computeInsertPoint(ArrayRef vals) { assert(!vals.empty() && "expected at least one va
[llvm-branch-commits] [clang] 81d2afb - Revert "[clang][analyzer] Stable order for SymbolRef-keyed containers (#121551)"
Author: Balazs Benics Date: 2025-01-03T19:42:04+01:00 New Revision: 81d2afb2991e636de374eb1d1b550786618ed036 URL: https://github.com/llvm/llvm-project/commit/81d2afb2991e636de374eb1d1b550786618ed036 DIFF: https://github.com/llvm/llvm-project/commit/81d2afb2991e636de374eb1d1b550786618ed036.diff LOG: Revert "[clang][analyzer] Stable order for SymbolRef-keyed containers (#121551)" This reverts commit 0844f83fea66332943deed7cdf97b686b2c7c37b. Added: Modified: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h clang/lib/StaticAnalyzer/Core/SymbolManager.cpp clang/test/Analysis/dump_egraph.cpp clang/test/Analysis/expr-inspection-printState-diseq-info.c clang/test/Analysis/expr-inspection-printState-eq-classes.c clang/test/Analysis/ptr-arith.cpp clang/test/Analysis/symbol-simplification-disequality-info.cpp clang/test/Analysis/symbol-simplification-fixpoint-one-iteration.cpp clang/test/Analysis/symbol-simplification-fixpoint-two-iterations.cpp clang/test/Analysis/unary-sym-expr.c Removed: diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h index aca14cf813c4bc..862a30c0e73633 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -25,8 +25,6 @@ namespace ento { class MemRegion; -using SymbolID = unsigned; - /// Symbolic value. These values used to capture symbolic execution of /// the program. class SymExpr : public llvm::FoldingSetNode { @@ -41,19 +39,9 @@ class SymExpr : public llvm::FoldingSetNode { private: Kind K; - /// A unique identifier for this symbol. - /// - /// It is useful for SymbolData to easily diff erentiate multiple symbols, but - /// also for "ephemeral" symbols, such as binary operations, because this id - /// can be used for arranging constraints or equivalence classes instead of - /// unstable pointer values. - /// - /// Note, however, that it can't be used in Profile because SymbolManager - /// needs to compute Profile before allocating SymExpr. - const SymbolID Sym; protected: - SymExpr(Kind k, SymbolID Sym) : K(k), Sym(Sym) {} + SymExpr(Kind k) : K(k) {} static bool isValidTypeForSymbol(QualType T) { // FIXME: Depending on whether we choose to deprecate structural symbols, @@ -68,14 +56,6 @@ class SymExpr : public llvm::FoldingSetNode { Kind getKind() const { return K; } - /// Get a unique identifier for this symbol. - /// The ID is unique across all SymExprs in a SymbolManager. - /// They reflect the allocation order of these SymExprs, - /// and are likely stable across runs. - /// Used as a key in SymbolRef containers and as part of identity - /// for SymbolData, e.g. SymbolConjured with ID = 7 is "conj_$7". - SymbolID getSymbolID() const { return Sym; } - virtual void dump() const; virtual void dumpToStream(raw_ostream &os) const {} @@ -132,14 +112,19 @@ inline raw_ostream &operator<<(raw_ostream &os, using SymbolRef = const SymExpr *; using SymbolRefSmallVectorTy = SmallVector; +using SymbolID = unsigned; /// A symbol representing data which can be stored in a memory location /// (region). class SymbolData : public SymExpr { + const SymbolID Sym; + void anchor() override; protected: - SymbolData(Kind k, SymbolID sym) : SymExpr(k, sym) { assert(classof(this)); } + SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) { +assert(classof(this)); + } public: ~SymbolData() override = default; @@ -147,6 +132,8 @@ class SymbolData : public SymExpr { /// Get a string representation of the kind of the region. virtual StringRef getKindStr() const = 0; + SymbolID getSymbolID() const { return Sym; } + unsigned computeComplexity() const override { return 1; }; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index b57f415ec139f8..73732d532f630f 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -25,7 +25,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/ImmutableSet.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" #include @@ -44,16 +43,15 @@ class StoreManager; class SymbolRegionValue : public SymbolData { const TypedValueRegion *R; - friend class SymExprAllocator; +public: SymbolRegionValue(SymbolID sym, const TypedValueRegion *r) : SymbolData(SymbolRegionValueKind, sym), R(r) { assert(r); assert(isValidTypeForSymbol(r->getValu