[llvm-branch-commits] [mlir] [mlir][IR] Add listener notifications for pattern begin/end (PR #84131)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/84131 This commit adds two new notifications to `RewriterBase::Listener`: * `notifyPatternBegin`: Called when a pattern application begins during a greedy pattern rewrite or dialect conversion. * `notifyPatternEnd`: Called when a pattern application finishes during a greedy pattern rewrite or dialect conversion. The listener infrastructure already provides a `notifyMatchFailure` callback that notifies about the reason for a pattern match failure. The two new notifications provide additional information about pattern applications. This change is in preparation of improving the handle update mechanism in the `apply_conversion_patterns` transform op. >From 3ecec094d43a4eb9405ad057c32e4579f1fbe680 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Wed, 6 Mar 2024 08:00:35 + Subject: [PATCH] [mlir][IR] Add listener notifications for pattern begin/end --- mlir/include/mlir/IR/PatternMatch.h | 30 +-- .../Transforms/Utils/DialectConversion.cpp| 29 +++--- .../Utils/GreedyPatternRewriteDriver.cpp | 53 +++ 3 files changed, 77 insertions(+), 35 deletions(-) diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index f8d22cfb22afd0..838b4947648f5e 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -432,11 +432,22 @@ class RewriterBase : public OpBuilder { /// Note: This notification is not triggered when unlinking an operation. virtual void notifyOperationErased(Operation *op) {} -/// Notify the listener that the pattern failed to match the given -/// operation, and provide a callback to populate a diagnostic with the -/// reason why the failure occurred. This method allows for derived -/// listeners to optionally hook into the reason why a rewrite failed, and -/// display it to users. +/// Notify the listener that the specified pattern is about to be applied +/// at the specified root operation. +virtual void notifyPatternBegin(const Pattern &pattern, Operation *op) {} + +/// Notify the listener that a pattern application finished with the +/// specified status. "success" indicates that the pattern was applied +/// successfully. "failure" indicates that the pattern could not be +/// applied. The pattern may have communicated the reason for the failure +/// with `notifyMatchFailure`. +virtual void notifyPatternEnd(const Pattern &pattern, + LogicalResult status) {} + +/// Notify the listener that the pattern failed to match, and provide a +/// callback to populate a diagnostic with the reason why the failure +/// occurred. This method allows for derived listeners to optionally hook +/// into the reason why a rewrite failed, and display it to users. virtual void notifyMatchFailure(Location loc, function_ref reasonCallback) {} @@ -478,6 +489,15 @@ class RewriterBase : public OpBuilder { if (auto *rewriteListener = dyn_cast(listener)) rewriteListener->notifyOperationErased(op); } +void notifyPatternBegin(const Pattern &pattern, Operation *op) override { + if (auto *rewriteListener = dyn_cast(listener)) +rewriteListener->notifyPatternBegin(pattern, op); +} +void notifyPatternEnd(const Pattern &pattern, + LogicalResult status) override { + if (auto *rewriteListener = dyn_cast(listener)) +rewriteListener->notifyPatternEnd(pattern, status); +} void notifyMatchFailure( Location loc, function_ref reasonCallback) override { diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index a5145246bc30c4..587fbe209b58af 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -1863,7 +1863,8 @@ class OperationLegalizer { using LegalizationAction = ConversionTarget::LegalizationAction; OperationLegalizer(const ConversionTarget &targetInfo, - const FrozenRewritePatternSet &patterns); + const FrozenRewritePatternSet &patterns, + const ConversionConfig &config); /// Returns true if the given operation is known to be illegal on the target. bool isIllegal(Operation *op) const; @@ -1955,12 +1956,16 @@ class OperationLegalizer { /// The pattern applicator to use for conversions. PatternApplicator applicator; + + /// Dialect conversion configuration. + const ConversionConfig &config; }; } // namespace OperationLegalizer::OperationLegalizer(const ConversionTarget &targetInfo, - const FrozenRewritePatternSet &patterns) -: target(targetInfo), applicator(patterns) { + const
[llvm-branch-commits] [mlir] [mlir][IR] Add listener notifications for pattern begin/end (PR #84131)
llvmbot wrote: @llvm/pr-subscribers-mlir-core Author: Matthias Springer (matthias-springer) Changes This commit adds two new notifications to `RewriterBase::Listener`: * `notifyPatternBegin`: Called when a pattern application begins during a greedy pattern rewrite or dialect conversion. * `notifyPatternEnd`: Called when a pattern application finishes during a greedy pattern rewrite or dialect conversion. The listener infrastructure already provides a `notifyMatchFailure` callback that notifies about the reason for a pattern match failure. The two new notifications provide additional information about pattern applications. This change is in preparation of improving the handle update mechanism in the `apply_conversion_patterns` transform op. --- Full diff: https://github.com/llvm/llvm-project/pull/84131.diff 3 Files Affected: - (modified) mlir/include/mlir/IR/PatternMatch.h (+25-5) - (modified) mlir/lib/Transforms/Utils/DialectConversion.cpp (+21-8) - (modified) mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp (+31-22) ``diff diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index f8d22cfb22afd0..838b4947648f5e 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -432,11 +432,22 @@ class RewriterBase : public OpBuilder { /// Note: This notification is not triggered when unlinking an operation. virtual void notifyOperationErased(Operation *op) {} -/// Notify the listener that the pattern failed to match the given -/// operation, and provide a callback to populate a diagnostic with the -/// reason why the failure occurred. This method allows for derived -/// listeners to optionally hook into the reason why a rewrite failed, and -/// display it to users. +/// Notify the listener that the specified pattern is about to be applied +/// at the specified root operation. +virtual void notifyPatternBegin(const Pattern &pattern, Operation *op) {} + +/// Notify the listener that a pattern application finished with the +/// specified status. "success" indicates that the pattern was applied +/// successfully. "failure" indicates that the pattern could not be +/// applied. The pattern may have communicated the reason for the failure +/// with `notifyMatchFailure`. +virtual void notifyPatternEnd(const Pattern &pattern, + LogicalResult status) {} + +/// Notify the listener that the pattern failed to match, and provide a +/// callback to populate a diagnostic with the reason why the failure +/// occurred. This method allows for derived listeners to optionally hook +/// into the reason why a rewrite failed, and display it to users. virtual void notifyMatchFailure(Location loc, function_ref reasonCallback) {} @@ -478,6 +489,15 @@ class RewriterBase : public OpBuilder { if (auto *rewriteListener = dyn_cast(listener)) rewriteListener->notifyOperationErased(op); } +void notifyPatternBegin(const Pattern &pattern, Operation *op) override { + if (auto *rewriteListener = dyn_cast(listener)) +rewriteListener->notifyPatternBegin(pattern, op); +} +void notifyPatternEnd(const Pattern &pattern, + LogicalResult status) override { + if (auto *rewriteListener = dyn_cast(listener)) +rewriteListener->notifyPatternEnd(pattern, status); +} void notifyMatchFailure( Location loc, function_ref reasonCallback) override { diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index a5145246bc30c4..587fbe209b58af 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -1863,7 +1863,8 @@ class OperationLegalizer { using LegalizationAction = ConversionTarget::LegalizationAction; OperationLegalizer(const ConversionTarget &targetInfo, - const FrozenRewritePatternSet &patterns); + const FrozenRewritePatternSet &patterns, + const ConversionConfig &config); /// Returns true if the given operation is known to be illegal on the target. bool isIllegal(Operation *op) const; @@ -1955,12 +1956,16 @@ class OperationLegalizer { /// The pattern applicator to use for conversions. PatternApplicator applicator; + + /// Dialect conversion configuration. + const ConversionConfig &config; }; } // namespace OperationLegalizer::OperationLegalizer(const ConversionTarget &targetInfo, - const FrozenRewritePatternSet &patterns) -: target(targetInfo), applicator(patterns) { + const FrozenRewritePatternSet &patterns, + const ConversionConfig &config) +: target(targetInfo), applica
[llvm-branch-commits] [mlir] [mlir][Transform] Remove `notifyOperationErased` workaround (PR #84134)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/84134 D144193 (#66771) has been merged. >From d9a6a5665c177185bafbe9cff264e28634b2b3e7 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Wed, 6 Mar 2024 08:09:22 + Subject: [PATCH] [mlir][Transform] Remove `notifyOperationErased` workaround D144193 (#66771) has been merged. --- .../Dialect/Transform/IR/TransformInterfaces.cpp| 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp b/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp index 71a9d61198e3fb..fe2eea535ffdcf 100644 --- a/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp @@ -1278,14 +1278,11 @@ void transform::TrackingListener::notifyMatchFailure( } void transform::TrackingListener::notifyOperationErased(Operation *op) { - // TODO: Walk can be removed when D144193 has landed. - op->walk([&](Operation *op) { -// Remove mappings for result values. -for (OpResult value : op->getResults()) - (void)replacePayloadValue(value, nullptr); -// Remove mapping for op. -(void)replacePayloadOp(op, nullptr); - }); + // Remove mappings for result values. + for (OpResult value : op->getResults()) +(void)replacePayloadValue(value, nullptr); + // Remove mapping for op. + (void)replacePayloadOp(op, nullptr); } void transform::TrackingListener::notifyOperationReplaced( ___ 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][Transform] Remove `notifyOperationErased` workaround (PR #84134)
llvmbot wrote: @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes D144193 (#66771) has been merged. --- Full diff: https://github.com/llvm/llvm-project/pull/84134.diff 1 Files Affected: - (modified) mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp (+5-8) ``diff diff --git a/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp b/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp index 71a9d61198e3fb..fe2eea535ffdcf 100644 --- a/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp @@ -1278,14 +1278,11 @@ void transform::TrackingListener::notifyMatchFailure( } void transform::TrackingListener::notifyOperationErased(Operation *op) { - // TODO: Walk can be removed when D144193 has landed. - op->walk([&](Operation *op) { -// Remove mappings for result values. -for (OpResult value : op->getResults()) - (void)replacePayloadValue(value, nullptr); -// Remove mapping for op. -(void)replacePayloadOp(op, nullptr); - }); + // Remove mappings for result values. + for (OpResult value : op->getResults()) +(void)replacePayloadValue(value, nullptr); + // Remove mapping for op. + (void)replacePayloadOp(op, nullptr); } void transform::TrackingListener::notifyOperationReplaced( `` https://github.com/llvm/llvm-project/pull/84134 ___ 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] [llvm][dfa-jump-threading] Allow DFAJumpThreading with optsize (PR #83049)
nikic wrote: > As for experimenting, I was hoping that you could just experiment locally > with local changes to LLVM. Is it much easier to experiment with a flag in > LLVM release? If so then this is fine. Agree that experimentation should be done with local changes to LLVM. Options like these tend to get added and never removed, even if they have outlived their usefulness. I could kind of see the rationale for adding it to LoopRotate (which is well-known to be problematic in this regard, and it's plausible to assume that more than one organization would have interest in testing the option), but I wouldn't want to encourage this as a general pattern for exploration of minsize optimization changes. https://github.com/llvm/llvm-project/pull/83049 ___ 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] release/18.x: [InstCombine] Fix shift calculation in InstCombineCasts (#84027) (PR #84080)
https://github.com/nikic approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/84080 ___ 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][Transform] Mapping update rules for `apply_conversion_patterns` (PR #84140)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/84140 This commit adds a new attribute to `transform.apply_conversion_patterns` that lets users specify how op handles should be updated if a tracked op is replaced during a dialect conversion. `find_replacements` is a dictionary attribute that specifies what kind of op should be considered for a tracked replaced op of a certain kind. E.g., `"arith.mulsi_extended" => "llvm.mul"` means that a tracked `arith.mulsi_extended` op should be updated to a newly created `llvm.mul` op in the transform state. The op must have been created in the same conversion pattern that replaced the `arith.mulsi_extended`. The current handle update mechanism is often not good enough because a pattern may create multiple ops and an op may not be directly replaced with the equivalent lower-level op. E.g., the lowering pattern for `arith.mulsi_extended` creates multiple ops and it is unclear which op should be considered as a replacement. Such information can now be injected by the users. (This mechanism will likely evolve over time.) `find_replacements` is available only for `transform.apply_conversion_patterns` but not for `transform.apply_patterns` at the moment. Conversion patterns are typically written in such a way that each pattern lowers exactly one op. In fact, the dialect conversion asserts that a conversion pattern either replaced or in-place modified the root op. It is unclear if the `find_replacements` mechanism is suitable for regular rewrite patterns. >From d88d842d98ccac9d828ec95c4921cbeff8ecd8db Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Wed, 6 Mar 2024 08:29:42 + Subject: [PATCH] [mlir][Transform] Specify mapping update rules for `apply_conversion_patterns` --- .../Transform/IR/TransformInterfaces.h| 51 +-- .../mlir/Dialect/Transform/IR/TransformOps.td | 11 ++ .../Transform/IR/TransformInterfaces.cpp | 46 +- .../lib/Dialect/Transform/IR/TransformOps.cpp | 142 +- mlir/test/Dialect/Transform/ops-invalid.mlir | 22 +++ .../Transform/test-pattern-application.mlir | 39 + 6 files changed, 256 insertions(+), 55 deletions(-) diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h index 32724ff4b98e8e..5db1a2c28fd414 100644 --- a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h @@ -1026,7 +1026,7 @@ class TrackingListener : public RewriterBase::Listener, /// Return the transform op in which this TrackingListener is used. TransformOpInterface getTransformOp() const { return transformOp; } -private: +protected: friend class TransformRewriter; void notifyOperationErased(Operation *op) override; @@ -1034,6 +1034,7 @@ class TrackingListener : public RewriterBase::Listener, void notifyOperationReplaced(Operation *op, ValueRange newValues) override; using Listener::notifyOperationReplaced; +private: /// The transform op in which this TrackingListener is used. TransformOpInterface transformOp; @@ -1047,23 +1048,48 @@ class TrackingListener : public RewriterBase::Listener, /// A specialized listener that keeps track of cases in which no replacement /// payload could be found. The error state of this listener must be checked /// before the end of its lifetime. -class ErrorCheckingTrackingListener : public TrackingListener { +template +class ErrorCheckingTrackingListener : public TrackingListenerTy { public: - using transform::TrackingListener::TrackingListener; + using TrackingListenerTy::TrackingListenerTy; - ~ErrorCheckingTrackingListener() override; + ~ErrorCheckingTrackingListener() override { +// The state of the ErrorCheckingTrackingListener must be checked and reset +// if there was an error. This is to prevent errors from accidentally being +// missed. +assert(status.succeeded() && "listener state was not checked"); + } /// Check and return the current error state of this listener. Afterwards, /// resets the error state to "success". - DiagnosedSilenceableFailure checkAndResetError(); + DiagnosedSilenceableFailure checkAndResetError() { +DiagnosedSilenceableFailure s = std::move(status); +status = DiagnosedSilenceableFailure::success(); +errorCounter = 0; +return s; + } /// Return "true" if this tracking listener had a failure. - bool failed() const; + bool failed() const { return !status.succeeded(); } protected: - void - notifyPayloadReplacementNotFound(Operation *op, ValueRange values, - DiagnosedSilenceableFailure &&diag) override; + void notifyPayloadReplacementNotFound( + Operation *op, ValueRange values, + DiagnosedSilenceableFailure &&diag) override { +// Merge potentially existing diags and store the result in the listener. +
[llvm-branch-commits] [mlir] [mlir][Transform] Mapping update rules for `apply_conversion_patterns` (PR #84140)
llvmbot wrote: @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes This commit adds a new attribute to `transform.apply_conversion_patterns` that lets users specify how op handles should be updated if a tracked op is replaced during a dialect conversion. `find_replacements` is a dictionary attribute that specifies what kind of op should be considered for a tracked replaced op of a certain kind. E.g., `"arith.mulsi_extended" => "llvm.mul"` means that a tracked `arith.mulsi_extended` op should be updated to a newly created `llvm.mul` op in the transform state. The op must have been created in the same conversion pattern that replaced the `arith.mulsi_extended`. The current handle update mechanism is often not good enough because a pattern may create multiple ops and an op may not be directly replaced with the equivalent lower-level op. E.g., the lowering pattern for `arith.mulsi_extended` creates multiple ops and it is unclear which op should be considered as a replacement. Such information can now be injected by the users. (This mechanism will likely evolve over time.) `find_replacements` is available only for `transform.apply_conversion_patterns` but not for `transform.apply_patterns` at the moment. Conversion patterns are typically written in such a way that each pattern lowers exactly one op. In fact, the dialect conversion asserts that a conversion pattern either replaced or in-place modified the root op. It is unclear if the `find_replacements` mechanism is suitable for regular rewrite patterns. --- Patch is 20.26 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/84140.diff 6 Files Affected: - (modified) mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h (+39-12) - (modified) mlir/include/mlir/Dialect/Transform/IR/TransformOps.td (+11) - (modified) mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp (+4-42) - (modified) mlir/lib/Dialect/Transform/IR/TransformOps.cpp (+141-1) - (modified) mlir/test/Dialect/Transform/ops-invalid.mlir (+22) - (modified) mlir/test/Dialect/Transform/test-pattern-application.mlir (+39) ``diff diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h index 32724ff4b98e8e..5db1a2c28fd414 100644 --- a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h @@ -1026,7 +1026,7 @@ class TrackingListener : public RewriterBase::Listener, /// Return the transform op in which this TrackingListener is used. TransformOpInterface getTransformOp() const { return transformOp; } -private: +protected: friend class TransformRewriter; void notifyOperationErased(Operation *op) override; @@ -1034,6 +1034,7 @@ class TrackingListener : public RewriterBase::Listener, void notifyOperationReplaced(Operation *op, ValueRange newValues) override; using Listener::notifyOperationReplaced; +private: /// The transform op in which this TrackingListener is used. TransformOpInterface transformOp; @@ -1047,23 +1048,48 @@ class TrackingListener : public RewriterBase::Listener, /// A specialized listener that keeps track of cases in which no replacement /// payload could be found. The error state of this listener must be checked /// before the end of its lifetime. -class ErrorCheckingTrackingListener : public TrackingListener { +template +class ErrorCheckingTrackingListener : public TrackingListenerTy { public: - using transform::TrackingListener::TrackingListener; + using TrackingListenerTy::TrackingListenerTy; - ~ErrorCheckingTrackingListener() override; + ~ErrorCheckingTrackingListener() override { +// The state of the ErrorCheckingTrackingListener must be checked and reset +// if there was an error. This is to prevent errors from accidentally being +// missed. +assert(status.succeeded() && "listener state was not checked"); + } /// Check and return the current error state of this listener. Afterwards, /// resets the error state to "success". - DiagnosedSilenceableFailure checkAndResetError(); + DiagnosedSilenceableFailure checkAndResetError() { +DiagnosedSilenceableFailure s = std::move(status); +status = DiagnosedSilenceableFailure::success(); +errorCounter = 0; +return s; + } /// Return "true" if this tracking listener had a failure. - bool failed() const; + bool failed() const { return !status.succeeded(); } protected: - void - notifyPayloadReplacementNotFound(Operation *op, ValueRange values, - DiagnosedSilenceableFailure &&diag) override; + void notifyPayloadReplacementNotFound( + Operation *op, ValueRange values, + DiagnosedSilenceableFailure &&diag) override { +// Merge potentially existing diags and store the result in the listener. +SmallVector diags; +diag.takeDiag
[llvm-branch-commits] [mlir] 10361ae - Revert "Revert "[mlir][py] better support for arith.constant construction" (#…"
Author: Oleksandr "Alex" Zinenko Date: 2024-03-06T09:58:39+01:00 New Revision: 10361aebde0e8fe9fdd1fbae2155d11ca84c5dbe URL: https://github.com/llvm/llvm-project/commit/10361aebde0e8fe9fdd1fbae2155d11ca84c5dbe DIFF: https://github.com/llvm/llvm-project/commit/10361aebde0e8fe9fdd1fbae2155d11ca84c5dbe.diff LOG: Revert "Revert "[mlir][py] better support for arith.constant construction" (#…" This reverts commit 96fc54828a0e72e60f90d237e571b47cad5bab87. Added: Modified: mlir/python/mlir/dialects/arith.py mlir/test/python/dialects/arith_dialect.py Removed: diff --git a/mlir/python/mlir/dialects/arith.py b/mlir/python/mlir/dialects/arith.py index 61c6917393f1f9..83a50c7ef244f1 100644 --- a/mlir/python/mlir/dialects/arith.py +++ b/mlir/python/mlir/dialects/arith.py @@ -5,6 +5,8 @@ from ._arith_ops_gen import * from ._arith_ops_gen import _Dialect from ._arith_enum_gen import * +from array import array as _array +from typing import overload try: from ..ir import * @@ -43,13 +45,30 @@ def _is_float_type(type: Type): class ConstantOp(ConstantOp): """Specialization for the constant op class.""" +@overload +def __init__(self, value: Attribute, *, loc=None, ip=None): +... + +@overload def __init__( -self, result: Type, value: Union[int, float, Attribute], *, loc=None, ip=None +self, result: Type, value: Union[int, float, _array], *, loc=None, ip=None ): +... + +def __init__(self, result, value, *, loc=None, ip=None): +if value is None: +assert isinstance(result, Attribute) +super().__init__(result, loc=loc, ip=ip) +return + if isinstance(value, int): super().__init__(IntegerAttr.get(result, value), loc=loc, ip=ip) elif isinstance(value, float): super().__init__(FloatAttr.get(result, value), loc=loc, ip=ip) +elif isinstance(value, _array) and value.typecode in ["i", "l"]: +super().__init__(DenseIntElementsAttr.get(value, type=result)) +elif isinstance(value, _array) and value.typecode in ["f", "d"]: +super().__init__(DenseFPElementsAttr.get(value, type=result)) else: super().__init__(value, loc=loc, ip=ip) @@ -79,6 +98,6 @@ def literal_value(self) -> Union[int, float]: def constant( -result: Type, value: Union[int, float, Attribute], *, loc=None, ip=None +result: Type, value: Union[int, float, Attribute, _array], *, loc=None, ip=None ) -> Value: return _get_op_result_or_op_results(ConstantOp(result, value, loc=loc, ip=ip)) diff --git a/mlir/test/python/dialects/arith_dialect.py b/mlir/test/python/dialects/arith_dialect.py index 8bb80eed2b8105..ef0e1620bba990 100644 --- a/mlir/test/python/dialects/arith_dialect.py +++ b/mlir/test/python/dialects/arith_dialect.py @@ -4,6 +4,7 @@ from mlir.ir import * import mlir.dialects.arith as arith import mlir.dialects.func as func +from array import array def run(f): @@ -92,3 +93,40 @@ def __str__(self): b = a * a # CHECK: ArithValue(%2 = arith.mulf %cst_1, %cst_1 : f64) print(b) + + +# CHECK-LABEL: TEST: testArrayConstantConstruction +@run +def testArrayConstantConstruction(): +with Context(), Location.unknown(): +module = Module.create() +with InsertionPoint(module.body): +i32_array = array("i", [1, 2, 3, 4]) +i32 = IntegerType.get_signless(32) +vec_i32 = VectorType.get([2, 2], i32) +arith.constant(vec_i32, i32_array) +arith.ConstantOp(vec_i32, DenseIntElementsAttr.get(i32_array, type=vec_i32)) + +i64_array = array("l", [5, 6, 7, 8]) +i64 = IntegerType.get_signless(64) +vec_i64 = VectorType.get([1, 4], i64) +arith.constant(vec_i64, i64_array) +arith.ConstantOp(vec_i64, DenseIntElementsAttr.get(i64_array, type=vec_i64)) + +f32_array = array("f", [1.0, 2.0, 3.0, 4.0]) +f32 = F32Type.get() +vec_f32 = VectorType.get([4, 1], f32) +arith.constant(vec_f32, f32_array) +arith.ConstantOp(vec_f32, DenseFPElementsAttr.get(f32_array, type=vec_f32)) + +f64_array = array("d", [1.0, 2.0, 3.0, 4.0]) +f64 = F64Type.get() +vec_f64 = VectorType.get([2, 1, 2], f64) +arith.constant(vec_f64, f64_array) +arith.ConstantOp(vec_f64, DenseFPElementsAttr.get(f64_array, type=vec_f64)) + +# CHECK-COUNT-2: arith.constant dense<[{{\[}}1, 2], [3, 4]]> : vector<2x2xi32> +# CHECK-COUNT-2: arith.constant dense<[{{\[}}5, 6, 7, 8]]> : vector<1x4xi64> +# CHECK-COUNT-2: arith.constant dense<[{{\[}}1.00e+00], [2.00e+00], [3.00e+00], [4.00e+00]]> : vector<4x1xf32> +# CHECK-COUNT-2: arith.constant dense<[{{
[llvm-branch-commits] [llvm] release/18.x: [InstCombine] Fix infinite loop in select equivalence fold (#84036) (PR #84141)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/84141 Backport 9f45c5e1a65a1abf4920b617d36ed05e73c04bea Requested by: @nikic >From f91bdecdc077ac80f870ab3e3780433eb1fd257f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 6 Mar 2024 09:33:51 +0100 Subject: [PATCH] [InstCombine] Fix infinite loop in select equivalence fold (#84036) When replacing with a non-constant, it's possible that the result of the simplification is actually more complicated than the original, and may result in an infinite combine loop. Mitigate the issue by requiring that either the replacement or simplification result is constant, which should ensure that it's simpler. While this check is crude, it does not appear to cause optimization regressions in real-world code in practice. Fixes https://github.com/llvm/llvm-project/issues/83127. (cherry picked from commit 9f45c5e1a65a1abf4920b617d36ed05e73c04bea) --- .../InstCombine/InstCombineSelect.cpp | 9 - llvm/test/Transforms/InstCombine/select.ll| 38 ++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 21bfc91148bfeb..9f220ec003ec33 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1284,7 +1284,11 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel, isGuaranteedNotToBeUndefOrPoison(CmpRHS, SQ.AC, &Sel, &DT)) { if (Value *V = simplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, SQ, /* AllowRefinement */ true)) - return replaceOperand(Sel, Swapped ? 2 : 1, V); + // Require either the replacement or the simplification result to be a + // constant to avoid infinite loops. + // FIXME: Make this check more precise. + if (isa(CmpRHS) || isa(V)) +return replaceOperand(Sel, Swapped ? 2 : 1, V); // Even if TrueVal does not simplify, we can directly replace a use of // CmpLHS with CmpRHS, as long as the instruction is not used anywhere @@ -1302,7 +1306,8 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel, isGuaranteedNotToBeUndefOrPoison(CmpLHS, SQ.AC, &Sel, &DT)) if (Value *V = simplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, SQ, /* AllowRefinement */ true)) - return replaceOperand(Sel, Swapped ? 2 : 1, V); + if (isa(CmpLHS) || isa(V)) +return replaceOperand(Sel, Swapped ? 2 : 1, V); auto *FalseInst = dyn_cast(FalseVal); if (!FalseInst) diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index c5f1b77c6d7404..b7e743c14a52ca 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -2849,12 +2849,14 @@ define i8 @select_replacement_sub(i8 %x, i8 %y, i8 %z) { ret i8 %sel } +; FIXME: This is safe to fold. define i8 @select_replacement_shift_noundef(i8 %x, i8 %y, i8 %z) { ; CHECK-LABEL: @select_replacement_shift_noundef( ; CHECK-NEXT:[[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1 ; CHECK-NEXT:call void @use_i8(i8 noundef [[SHR]]) ; CHECK-NEXT:[[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]] -; CHECK-NEXT:[[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z:%.*]] +; CHECK-NEXT:[[SHL:%.*]] = shl i8 [[Y]], 1 +; CHECK-NEXT:[[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]] ; CHECK-NEXT:ret i8 [[SEL]] ; %shr = lshr exact i8 %x, 1 @@ -2904,6 +2906,40 @@ define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) { ret i32 %sel } +define i8 @select_replacement_loop3(i32 noundef %x) { +; CHECK-LABEL: @select_replacement_loop3( +; CHECK-NEXT:[[TRUNC:%.*]] = trunc i32 [[X:%.*]] to i8 +; CHECK-NEXT:[[REV:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TRUNC]]) +; CHECK-NEXT:[[EXT:%.*]] = zext i8 [[REV]] to i32 +; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[EXT]], [[X]] +; CHECK-NEXT:[[SEL:%.*]] = select i1 [[CMP]], i8 [[TRUNC]], i8 0 +; CHECK-NEXT:ret i8 [[SEL]] +; + %trunc = trunc i32 %x to i8 + %rev = call i8 @llvm.bitreverse.i8(i8 %trunc) + %ext = zext i8 %rev to i32 + %cmp = icmp eq i32 %ext, %x + %sel = select i1 %cmp, i8 %trunc, i8 0 + ret i8 %sel +} + +define i16 @select_replacement_loop4(i16 noundef %p_12) { +; CHECK-LABEL: @select_replacement_loop4( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ult i16 [[P_12:%.*]], 2 +; CHECK-NEXT:[[AND1:%.*]] = and i16 [[P_12]], 1 +; CHECK-NEXT:[[AND2:%.*]] = select i1 [[CMP1]], i16 [[AND1]], i16 0 +; CHECK-NEXT:[[CMP2:%.*]] = icmp eq i16 [[AND2]], [[P_12]] +; CHECK-NEXT:[[AND3:%.*]] = select i1 [[CMP2]], i16 [[AND1]], i16 0 +; CHECK-NEXT:ret i16 [[AND3]] +; + %cmp1 = icmp ult i16 %p_12, 2 + %and1 = and i16 %p_12, 1 + %and2 = select i1 %cmp1, i16 %and1, i16 0 + %cmp2 = icmp eq i16 %an
[llvm-branch-commits] [llvm] release/18.x: [InstCombine] Fix infinite loop in select equivalence fold (#84036) (PR #84141)
https://github.com/llvmbot milestoned https://github.com/llvm/llvm-project/pull/84141 ___ 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] release/18.x: [InstCombine] Fix infinite loop in select equivalence fold (#84036) (PR #84141)
llvmbot wrote: @llvm/pr-subscribers-llvm-transforms Author: None (llvmbot) Changes Backport 9f45c5e1a65a1abf4920b617d36ed05e73c04bea Requested by: @nikic --- Full diff: https://github.com/llvm/llvm-project/pull/84141.diff 2 Files Affected: - (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+7-2) - (modified) llvm/test/Transforms/InstCombine/select.ll (+37-1) ``diff diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 21bfc91148bfeb..9f220ec003ec33 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1284,7 +1284,11 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel, isGuaranteedNotToBeUndefOrPoison(CmpRHS, SQ.AC, &Sel, &DT)) { if (Value *V = simplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, SQ, /* AllowRefinement */ true)) - return replaceOperand(Sel, Swapped ? 2 : 1, V); + // Require either the replacement or the simplification result to be a + // constant to avoid infinite loops. + // FIXME: Make this check more precise. + if (isa(CmpRHS) || isa(V)) +return replaceOperand(Sel, Swapped ? 2 : 1, V); // Even if TrueVal does not simplify, we can directly replace a use of // CmpLHS with CmpRHS, as long as the instruction is not used anywhere @@ -1302,7 +1306,8 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel, isGuaranteedNotToBeUndefOrPoison(CmpLHS, SQ.AC, &Sel, &DT)) if (Value *V = simplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, SQ, /* AllowRefinement */ true)) - return replaceOperand(Sel, Swapped ? 2 : 1, V); + if (isa(CmpLHS) || isa(V)) +return replaceOperand(Sel, Swapped ? 2 : 1, V); auto *FalseInst = dyn_cast(FalseVal); if (!FalseInst) diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index c5f1b77c6d7404..b7e743c14a52ca 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -2849,12 +2849,14 @@ define i8 @select_replacement_sub(i8 %x, i8 %y, i8 %z) { ret i8 %sel } +; FIXME: This is safe to fold. define i8 @select_replacement_shift_noundef(i8 %x, i8 %y, i8 %z) { ; CHECK-LABEL: @select_replacement_shift_noundef( ; CHECK-NEXT:[[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1 ; CHECK-NEXT:call void @use_i8(i8 noundef [[SHR]]) ; CHECK-NEXT:[[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]] -; CHECK-NEXT:[[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z:%.*]] +; CHECK-NEXT:[[SHL:%.*]] = shl i8 [[Y]], 1 +; CHECK-NEXT:[[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]] ; CHECK-NEXT:ret i8 [[SEL]] ; %shr = lshr exact i8 %x, 1 @@ -2904,6 +2906,40 @@ define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) { ret i32 %sel } +define i8 @select_replacement_loop3(i32 noundef %x) { +; CHECK-LABEL: @select_replacement_loop3( +; CHECK-NEXT:[[TRUNC:%.*]] = trunc i32 [[X:%.*]] to i8 +; CHECK-NEXT:[[REV:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TRUNC]]) +; CHECK-NEXT:[[EXT:%.*]] = zext i8 [[REV]] to i32 +; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[EXT]], [[X]] +; CHECK-NEXT:[[SEL:%.*]] = select i1 [[CMP]], i8 [[TRUNC]], i8 0 +; CHECK-NEXT:ret i8 [[SEL]] +; + %trunc = trunc i32 %x to i8 + %rev = call i8 @llvm.bitreverse.i8(i8 %trunc) + %ext = zext i8 %rev to i32 + %cmp = icmp eq i32 %ext, %x + %sel = select i1 %cmp, i8 %trunc, i8 0 + ret i8 %sel +} + +define i16 @select_replacement_loop4(i16 noundef %p_12) { +; CHECK-LABEL: @select_replacement_loop4( +; CHECK-NEXT:[[CMP1:%.*]] = icmp ult i16 [[P_12:%.*]], 2 +; CHECK-NEXT:[[AND1:%.*]] = and i16 [[P_12]], 1 +; CHECK-NEXT:[[AND2:%.*]] = select i1 [[CMP1]], i16 [[AND1]], i16 0 +; CHECK-NEXT:[[CMP2:%.*]] = icmp eq i16 [[AND2]], [[P_12]] +; CHECK-NEXT:[[AND3:%.*]] = select i1 [[CMP2]], i16 [[AND1]], i16 0 +; CHECK-NEXT:ret i16 [[AND3]] +; + %cmp1 = icmp ult i16 %p_12, 2 + %and1 = and i16 %p_12, 1 + %and2 = select i1 %cmp1, i16 %and1, i16 0 + %cmp2 = icmp eq i16 %and2, %p_12 + %and3 = select i1 %cmp2, i16 %and1, i16 0 + ret i16 %and3 +} + define ptr @select_replacement_gep_inbounds(ptr %base, i64 %offset) { ; CHECK-LABEL: @select_replacement_gep_inbounds( ; CHECK-NEXT:[[GEP:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], i64 [[OFFSET:%.*]] `` https://github.com/llvm/llvm-project/pull/84141 ___ 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] release/18.x: [InstCombine] Fix infinite loop in select equivalence fold (#84036) (PR #84141)
https://github.com/dtcxzyw approved this pull request. https://github.com/llvm/llvm-project/pull/84141 ___ 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] [RISCV] Support select optimization (PR #80124)
@@ -101,6 +101,11 @@ static cl::opt EnableMISchedLoadClustering( cl::desc("Enable load clustering in the machine scheduler"), cl::init(false)); +static cl::opt +EnableSelectOpt("riscv-select-opt", cl::Hidden, wangpc-pp wrote: @topperc WDYT? https://github.com/llvm/llvm-project/pull/80124 ___ 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] 2217cac - [mlir][py] better support for arith.constant construction
Author: Alex Zinenko Date: 2024-02-28T12:53:53Z New Revision: 2217caceac600f5c0e84a0d6a55ec036e13ebf6a URL: https://github.com/llvm/llvm-project/commit/2217caceac600f5c0e84a0d6a55ec036e13ebf6a DIFF: https://github.com/llvm/llvm-project/commit/2217caceac600f5c0e84a0d6a55ec036e13ebf6a.diff LOG: [mlir][py] better support for arith.constant construction Arithmetic constants for vector types can be constructed from objects implementing Python buffer protocol such as `array.array`. Note that until Python 3.12, there is no typing support for buffer protocol implementers, so the annotations use array explicitly. Added: Modified: mlir/python/mlir/dialects/arith.py mlir/test/python/dialects/arith_dialect.py Removed: diff --git a/mlir/python/mlir/dialects/arith.py b/mlir/python/mlir/dialects/arith.py index 61c6917393f1f9..83a50c7ef244f1 100644 --- a/mlir/python/mlir/dialects/arith.py +++ b/mlir/python/mlir/dialects/arith.py @@ -5,6 +5,8 @@ from ._arith_ops_gen import * from ._arith_ops_gen import _Dialect from ._arith_enum_gen import * +from array import array as _array +from typing import overload try: from ..ir import * @@ -43,13 +45,30 @@ def _is_float_type(type: Type): class ConstantOp(ConstantOp): """Specialization for the constant op class.""" +@overload +def __init__(self, value: Attribute, *, loc=None, ip=None): +... + +@overload def __init__( -self, result: Type, value: Union[int, float, Attribute], *, loc=None, ip=None +self, result: Type, value: Union[int, float, _array], *, loc=None, ip=None ): +... + +def __init__(self, result, value, *, loc=None, ip=None): +if value is None: +assert isinstance(result, Attribute) +super().__init__(result, loc=loc, ip=ip) +return + if isinstance(value, int): super().__init__(IntegerAttr.get(result, value), loc=loc, ip=ip) elif isinstance(value, float): super().__init__(FloatAttr.get(result, value), loc=loc, ip=ip) +elif isinstance(value, _array) and value.typecode in ["i", "l"]: +super().__init__(DenseIntElementsAttr.get(value, type=result)) +elif isinstance(value, _array) and value.typecode in ["f", "d"]: +super().__init__(DenseFPElementsAttr.get(value, type=result)) else: super().__init__(value, loc=loc, ip=ip) @@ -79,6 +98,6 @@ def literal_value(self) -> Union[int, float]: def constant( -result: Type, value: Union[int, float, Attribute], *, loc=None, ip=None +result: Type, value: Union[int, float, Attribute, _array], *, loc=None, ip=None ) -> Value: return _get_op_result_or_op_results(ConstantOp(result, value, loc=loc, ip=ip)) diff --git a/mlir/test/python/dialects/arith_dialect.py b/mlir/test/python/dialects/arith_dialect.py index 8bb80eed2b8105..ef0e1620bba990 100644 --- a/mlir/test/python/dialects/arith_dialect.py +++ b/mlir/test/python/dialects/arith_dialect.py @@ -4,6 +4,7 @@ from mlir.ir import * import mlir.dialects.arith as arith import mlir.dialects.func as func +from array import array def run(f): @@ -92,3 +93,40 @@ def __str__(self): b = a * a # CHECK: ArithValue(%2 = arith.mulf %cst_1, %cst_1 : f64) print(b) + + +# CHECK-LABEL: TEST: testArrayConstantConstruction +@run +def testArrayConstantConstruction(): +with Context(), Location.unknown(): +module = Module.create() +with InsertionPoint(module.body): +i32_array = array("i", [1, 2, 3, 4]) +i32 = IntegerType.get_signless(32) +vec_i32 = VectorType.get([2, 2], i32) +arith.constant(vec_i32, i32_array) +arith.ConstantOp(vec_i32, DenseIntElementsAttr.get(i32_array, type=vec_i32)) + +i64_array = array("l", [5, 6, 7, 8]) +i64 = IntegerType.get_signless(64) +vec_i64 = VectorType.get([1, 4], i64) +arith.constant(vec_i64, i64_array) +arith.ConstantOp(vec_i64, DenseIntElementsAttr.get(i64_array, type=vec_i64)) + +f32_array = array("f", [1.0, 2.0, 3.0, 4.0]) +f32 = F32Type.get() +vec_f32 = VectorType.get([4, 1], f32) +arith.constant(vec_f32, f32_array) +arith.ConstantOp(vec_f32, DenseFPElementsAttr.get(f32_array, type=vec_f32)) + +f64_array = array("d", [1.0, 2.0, 3.0, 4.0]) +f64 = F64Type.get() +vec_f64 = VectorType.get([2, 1, 2], f64) +arith.constant(vec_f64, f64_array) +arith.ConstantOp(vec_f64, DenseFPElementsAttr.get(f64_array, type=vec_f64)) + +# CHECK-COUNT-2: arith.constant dense<[{{\[}}1, 2], [3, 4]]> : vector<2x2xi32> +# CHECK-COUNT-2: arith.constant dense<[{{\[}}5, 6, 7, 8]]> : vector<1x4xi64> +# CHECK-COUNT-2: ari
[llvm-branch-commits] [mlir] 1ccfb41 - printf debugging
Author: Alex Zinenko Date: 2024-03-06T10:49:17Z New Revision: 1ccfb41ab32ac27b32919438a11806bd688a030d URL: https://github.com/llvm/llvm-project/commit/1ccfb41ab32ac27b32919438a11806bd688a030d DIFF: https://github.com/llvm/llvm-project/commit/1ccfb41ab32ac27b32919438a11806bd688a030d.diff LOG: printf debugging Added: Modified: mlir/lib/IR/BuiltinAttributes.cpp Removed: diff --git a/mlir/lib/IR/BuiltinAttributes.cpp b/mlir/lib/IR/BuiltinAttributes.cpp index 89b1ed67f5d067..2f3798ed54f2f3 100644 --- a/mlir/lib/IR/BuiltinAttributes.cpp +++ b/mlir/lib/IR/BuiltinAttributes.cpp @@ -1084,6 +1084,11 @@ bool DenseElementsAttr::isValidRawBuffer(ShapedType type, return rawBufferWidth == llvm::alignTo<8>(numElements); } + llvm::errs() << "storage width: " << storageWidth + << " rawBufferWidth: " << rawBufferWidth + << " numElements: " << numElements << "\n"; + type.dump(); + // All other types are 8-bit aligned, so we can just check the buffer width // to know if only a single initializer element was passed in. if (rawBufferWidth == storageWidth) { ___ 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)
ChuanqiXu9 wrote: @ilya-biryukov hi, the functional and performance test on the root side looks good: https://github.com/root-project/root/pull/14495#issuecomment-1980589145 Could you try to test this within google internals? Also if your projects implements new ExternalASTSource, you need to handle that like I did in root: https://github.com/ChuanqiXu9/root/commit/570fd783875671d346c7cdc0d98a8a9afcad05a4 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] [llvm] release/18.x: [X86][Inline] Skip inline asm in inlining target feature check (#83820) (PR #84029)
phoebewang wrote: Risk is minimum, LGTM. https://github.com/llvm/llvm-project/pull/84029 ___ 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] release/18.x: [X86]: Add FPCW as a rounding control register (PR #84058)
phoebewang wrote: I don't think it worth backport. The x87 usage is not very common nowadays, and the problem is lasting for a while. I'd suggest not do the backport considering it may have sideeffect in the isCall change. https://github.com/llvm/llvm-project/pull/84058 ___ 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] release/18.x: Convert many LivePhysRegs uses to LiveRegUnits (PR #84118)
@@ -313,7 +313,7 @@ MachineBasicBlock::reverse_iterator SIOptimizeExecMasking::findExecCopy( return E; } -// XXX - Seems LivePhysRegs doesn't work correctly since it will incorrectly +// XXX - Seems LiveRegUnits doesn't work correctly since it will incorrectly kparzysz wrote: I think LiveRegUnits fixes this issue, doesn't it? https://github.com/llvm/llvm-project/pull/84118 ___ 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] release/18.x: [X86] Resolve FIXME: Enable PC relative calls on Windows (PR #84185)
https://github.com/AtariDreams created https://github.com/llvm/llvm-project/pull/84185 WinCOFFObjectWriter::RecordRelocation has been able to emit PC relative calls for a while now, but the workaround code has not been removed. We can safely enable it now for Windows. >From ea9ee14e5b73aced6b1cad9cde4dab788a75234f Mon Sep 17 00:00:00 2001 From: Rose Date: Tue, 5 Mar 2024 15:03:23 -0500 Subject: [PATCH] [X86] Resolve FIXME: WinCOFFObjectWriter::RecordRelocation can emit PC-relative calls This has been true for a while now, but this check has not been removed. --- llvm/lib/Target/X86/X86Subtarget.cpp | 5 + llvm/test/CodeGen/X86/call-imm.ll| 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 07f535685e8f97..74d9b1bd327ea1 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -238,10 +238,7 @@ X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV, /// Return true if the subtarget allows calls to immediate address. bool X86Subtarget::isLegalToCallImmediateAddr() const { - // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32 - // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does, - // the following check for Win32 should be removed. - if (Is64Bit || isTargetWin32()) + if (Is64Bit) return false; return isTargetELF() || TM.getRelocationModel() == Reloc::Static; } diff --git a/llvm/test/CodeGen/X86/call-imm.ll b/llvm/test/CodeGen/X86/call-imm.ll index b8f5a0cb9b4287..5628dc3faddc08 100644 --- a/llvm/test/CodeGen/X86/call-imm.ll +++ b/llvm/test/CodeGen/X86/call-imm.ll @@ -2,6 +2,7 @@ ; RUN: llc < %s -mtriple=i386-apple-darwin -relocation-model=pic | FileCheck -check-prefix X86PIC %s ; RUN: llc < %s -mtriple=i386-pc-linux -relocation-model=dynamic-no-pic | FileCheck -check-prefix X86DYN %s ; RUN: llc < %s -mtriple=i386-pc-win32 -relocation-model=static | FileCheck -check-prefix X86WINSTA %s +; RUN: llc < %s -mtriple=i386-pc-win32 -relocation-model=pic | FileCheck -check-prefix X86WINPIC %s ; Call to immediate is not safe on x86-64 unless we *know* that the ; call will be within 32-bits pcrel from the dest immediate. @@ -21,5 +22,6 @@ entry: ; X86STA: {{call.*12345678}} ; X86PIC-NOT: {{call.*12345678}} ; X86DYN: {{call.*12345678}} -; X86WINSTA: {{call.*[*]%eax}} +; X86WINSTA: {{call.*12345678}} +; X86WINPIC-NOT: {{call.*12345678}} ; X64: {{call.*[*]%rax}} ___ 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] release/18.x: [X86] Resolve FIXME: Enable PC relative calls on Windows (PR #84185)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 Author: AtariDreams (AtariDreams) Changes WinCOFFObjectWriter::RecordRelocation has been able to emit PC relative calls for a while now, but the workaround code has not been removed. We can safely enable it now for Windows. --- Full diff: https://github.com/llvm/llvm-project/pull/84185.diff 2 Files Affected: - (modified) llvm/lib/Target/X86/X86Subtarget.cpp (+1-4) - (modified) llvm/test/CodeGen/X86/call-imm.ll (+3-1) ``diff diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 07f535685e8f97..74d9b1bd327ea1 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -238,10 +238,7 @@ X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV, /// Return true if the subtarget allows calls to immediate address. bool X86Subtarget::isLegalToCallImmediateAddr() const { - // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32 - // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does, - // the following check for Win32 should be removed. - if (Is64Bit || isTargetWin32()) + if (Is64Bit) return false; return isTargetELF() || TM.getRelocationModel() == Reloc::Static; } diff --git a/llvm/test/CodeGen/X86/call-imm.ll b/llvm/test/CodeGen/X86/call-imm.ll index b8f5a0cb9b4287..5628dc3faddc08 100644 --- a/llvm/test/CodeGen/X86/call-imm.ll +++ b/llvm/test/CodeGen/X86/call-imm.ll @@ -2,6 +2,7 @@ ; RUN: llc < %s -mtriple=i386-apple-darwin -relocation-model=pic | FileCheck -check-prefix X86PIC %s ; RUN: llc < %s -mtriple=i386-pc-linux -relocation-model=dynamic-no-pic | FileCheck -check-prefix X86DYN %s ; RUN: llc < %s -mtriple=i386-pc-win32 -relocation-model=static | FileCheck -check-prefix X86WINSTA %s +; RUN: llc < %s -mtriple=i386-pc-win32 -relocation-model=pic | FileCheck -check-prefix X86WINPIC %s ; Call to immediate is not safe on x86-64 unless we *know* that the ; call will be within 32-bits pcrel from the dest immediate. @@ -21,5 +22,6 @@ entry: ; X86STA: {{call.*12345678}} ; X86PIC-NOT: {{call.*12345678}} ; X86DYN: {{call.*12345678}} -; X86WINSTA: {{call.*[*]%eax}} +; X86WINSTA: {{call.*12345678}} +; X86WINPIC-NOT: {{call.*12345678}} ; X64: {{call.*[*]%rax}} `` https://github.com/llvm/llvm-project/pull/84185 ___ 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] release/18.x: [X86] Resolve FIXME: Enable PC relative calls on Windows (PR #84185)
RKSimon wrote: Now that 18.1 has been released - we shouldn't be merging anything that isn't just a regression from 17.x I've tried to find the release policy for this in case 18.2 is now allow further merges but I can't find anything? https://github.com/llvm/llvm-project/pull/84185 ___ 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] release/18.x: Convert many LivePhysRegs uses to LiveRegUnits (PR #84118)
https://github.com/AtariDreams closed https://github.com/llvm/llvm-project/pull/84118 ___ 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] release/18.x: Convert many LivePhysRegs uses to LiveRegUnits (PR #84118)
https://github.com/AtariDreams reopened https://github.com/llvm/llvm-project/pull/84118 ___ 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] release/18.x: [X86]: Add FPCW as a rounding control register (PR #84058)
https://github.com/AtariDreams closed https://github.com/llvm/llvm-project/pull/84058 ___ 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][x86] Support -mtls-dialect for x86_64 targets (PR #84086)
https://github.com/ilovepi closed https://github.com/llvm/llvm-project/pull/84086 ___ 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] 0c81122 - [mlir][py] better support for arith.constant construction
Author: Alex Zinenko Date: 2024-03-06T18:30:09Z New Revision: 0c81122420979a28d16beddaed85413fd533c324 URL: https://github.com/llvm/llvm-project/commit/0c81122420979a28d16beddaed85413fd533c324 DIFF: https://github.com/llvm/llvm-project/commit/0c81122420979a28d16beddaed85413fd533c324.diff LOG: [mlir][py] better support for arith.constant construction Arithmetic constants for vector types can be constructed from objects implementing Python buffer protocol such as `array.array`. Note that until Python 3.12, there is no typing support for buffer protocol implementers, so the annotations use array explicitly. Added: Modified: mlir/python/mlir/dialects/arith.py mlir/test/python/dialects/arith_dialect.py Removed: diff --git a/mlir/python/mlir/dialects/arith.py b/mlir/python/mlir/dialects/arith.py index 61c6917393f1f9..92da5df9bce665 100644 --- a/mlir/python/mlir/dialects/arith.py +++ b/mlir/python/mlir/dialects/arith.py @@ -5,6 +5,8 @@ from ._arith_ops_gen import * from ._arith_ops_gen import _Dialect from ._arith_enum_gen import * +from array import array as _array +from typing import overload try: from ..ir import * @@ -43,13 +45,37 @@ def _is_float_type(type: Type): class ConstantOp(ConstantOp): """Specialization for the constant op class.""" +@overload +def __init__(self, value: Attribute, *, loc=None, ip=None): +... + +@overload def __init__( -self, result: Type, value: Union[int, float, Attribute], *, loc=None, ip=None +self, result: Type, value: Union[int, float, _array], *, loc=None, ip=None ): +... + +def __init__(self, result, value, *, loc=None, ip=None): +if value is None: +assert isinstance(result, Attribute) +super().__init__(result, loc=loc, ip=ip) +return + if isinstance(value, int): super().__init__(IntegerAttr.get(result, value), loc=loc, ip=ip) elif isinstance(value, float): super().__init__(FloatAttr.get(result, value), loc=loc, ip=ip) +elif isinstance(value, _array): +if 8 * value.itemsize != result.element_type.width: +raise ValueError( +f"Mismatching array element ({8 * value.itemsize}) and type ({result.element_type.width}) width." +) +if value.typecode in ["i", "l", "q"]: +super().__init__(DenseIntElementsAttr.get(value, type=result)) +elif value.typecode in ["f", "d"]: +super().__init__(DenseFPElementsAttr.get(value, type=result)) +else: +raise ValueError(f'Unsupported typecode: "{value.typecode}".') else: super().__init__(value, loc=loc, ip=ip) @@ -79,6 +105,6 @@ def literal_value(self) -> Union[int, float]: def constant( -result: Type, value: Union[int, float, Attribute], *, loc=None, ip=None +result: Type, value: Union[int, float, Attribute, _array], *, loc=None, ip=None ) -> Value: return _get_op_result_or_op_results(ConstantOp(result, value, loc=loc, ip=ip)) diff --git a/mlir/test/python/dialects/arith_dialect.py b/mlir/test/python/dialects/arith_dialect.py index 8bb80eed2b8105..c9af5e7b46db84 100644 --- a/mlir/test/python/dialects/arith_dialect.py +++ b/mlir/test/python/dialects/arith_dialect.py @@ -4,6 +4,7 @@ from mlir.ir import * import mlir.dialects.arith as arith import mlir.dialects.func as func +from array import array def run(f): @@ -92,3 +93,42 @@ def __str__(self): b = a * a # CHECK: ArithValue(%2 = arith.mulf %cst_1, %cst_1 : f64) print(b) + + +# CHECK-LABEL: TEST: testArrayConstantConstruction +@run +def testArrayConstantConstruction(): +with Context(), Location.unknown(): +module = Module.create() +with InsertionPoint(module.body): +i32_array = array("i", [1, 2, 3, 4]) +i32 = IntegerType.get_signless(32) +vec_i32 = VectorType.get([2, 2], i32) +arith.constant(vec_i32, i32_array) +arith.ConstantOp(vec_i32, DenseIntElementsAttr.get(i32_array, type=vec_i32)) + +# "q" is the equivalent of `long long` in C and requires at least +# 64 bit width integers on both Linux and Windows. +i64_array = array("q", [5, 6, 7, 8]) +i64 = IntegerType.get_signless(64) +vec_i64 = VectorType.get([1, 4], i64) +arith.constant(vec_i64, i64_array) +arith.ConstantOp(vec_i64, DenseIntElementsAttr.get(i64_array, type=vec_i64)) + +f32_array = array("f", [1.0, 2.0, 3.0, 4.0]) +f32 = F32Type.get() +vec_f32 = VectorType.get([4, 1], f32) +arith.constant(vec_f32, f32_array) +arith.ConstantOp(vec_f32, DenseFPElementsAttr.get(f32_array, type=vec_f32)) + +
[llvm-branch-commits] [llvm] Backport #83980 to 18.x (PR #84023)
https://github.com/nikic approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/84023 ___ 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] release/18.x: [InstCombine] Fix miscompilation in PR83947 (#83993) (PR #84021)
nikic wrote: There is a test failure. https://github.com/llvm/llvm-project/pull/84021 ___ 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] release/18.x: [llvm][AArch64] Autoupgrade function attributes from Module attributes. (#82763) (PR #84039)
nikic wrote: Note that a potential regression for this patch was reported at https://github.com/llvm/llvm-project/pull/82763#issuecomment-1981514318. https://github.com/llvm/llvm-project/pull/84039 ___ 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] release/18.x: [llvm][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984) (PR #83540)
xry111 wrote: I have some doubt about this change. To me if the user requests `xvpermi.q` via the `loongarch_lasx_xvpermi_q` intrinsic, we should give her/him the `xvpermi.q` instruction. If (s)he is passing an invalid operand then (s)he is invoking the undefined behavior herself/himself and we don't need to guarantee a thing. So to me we should not merge this and we should revert this change for main. Or am I missing something? @xen0n @heiher @SixWeining @MaskRay https://github.com/llvm/llvm-project/pull/83540 ___ 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] release/18.x: [DSE] Delay deleting non-memory-defs until end of DSE. (#83411) (PR #84227)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/84227 Backport 10f5e983a9e3162a569cbebeb32168716e391340 Requested by: @fhahn >From 7d14f1602c7cc70589420925a569be9968ab Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sat, 2 Mar 2024 12:34:36 + Subject: [PATCH] [DSE] Delay deleting non-memory-defs until end of DSE. (#83411) DSE uses BatchAA, which caches queries using pairs of MemoryLocations. At the moment, DSE may remove instructions that are used as pointers in cached MemoryLocations. If a new instruction used by a new MemoryLoation and this instruction gets allocated at the same address as a previosuly cached and then removed instruction, we may access an incorrect entry in the cache. To avoid this delay removing all instructions except MemoryDefs until the end of DSE. This should avoid removing any values used in BatchAA's cache. Test case by @vporpo from https://github.com/llvm/llvm-project/pull/83181. (Test not precommitted because the results are non-determinstic - memset only sometimes gets removed) PR: https://github.com/llvm/llvm-project/pull/83411 (cherry picked from commit 10f5e983a9e3162a569cbebeb32168716e391340) --- .../Scalar/DeadStoreElimination.cpp | 31 ++- .../batchaa-caching-new-pointers.ll | 189 ++ 2 files changed, 215 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 11a91bfbe5baff..340fba4fb9c5a2 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -857,6 +857,9 @@ struct DSEState { // no longer be captured. bool ShouldIterateEndOfFunctionDSE; + /// Dead instructions to be removed at the end of DSE. + SmallVector ToRemove; + // Class contains self-reference, make sure it's not copied/moved. DSEState(const DSEState &) = delete; DSEState &operator=(const DSEState &) = delete; @@ -1692,7 +1695,8 @@ struct DSEState { return {MaybeDeadAccess}; } - // Delete dead memory defs + /// Delete dead memory defs and recursively add their operands to ToRemove if + /// they became dead. void deleteDeadInstruction(Instruction *SI) { MemorySSAUpdater Updater(&MSSA); SmallVector NowDeadInsts; @@ -1708,8 +1712,11 @@ struct DSEState { salvageKnowledge(DeadInst); // Remove the Instruction from MSSA. - if (MemoryAccess *MA = MSSA.getMemoryAccess(DeadInst)) { -if (MemoryDef *MD = dyn_cast(MA)) { + MemoryAccess *MA = MSSA.getMemoryAccess(DeadInst); + bool IsMemDef = MA && isa(MA); + if (MA) { +if (IsMemDef) { + auto *MD = cast(MA); SkipStores.insert(MD); if (auto *SI = dyn_cast(MD->getMemoryInst())) { if (SI->getValueOperand()->getType()->isPointerTy()) { @@ -1730,13 +1737,21 @@ struct DSEState { // Remove its operands for (Use &O : DeadInst->operands()) if (Instruction *OpI = dyn_cast(O)) { - O = nullptr; + O.set(PoisonValue::get(O->getType())); if (isInstructionTriviallyDead(OpI, &TLI)) NowDeadInsts.push_back(OpI); } EI.removeInstruction(DeadInst); - DeadInst->eraseFromParent(); + // Remove memory defs directly if they don't produce results, but only + // queue other dead instructions for later removal. They may have been + // used as memory locations that have been cached by BatchAA. Removing + // them here may lead to newly created instructions to be allocated at the + // same address, yielding stale cache entries. + if (IsMemDef && DeadInst->getType()->isVoidTy()) +DeadInst->eraseFromParent(); + else +ToRemove.push_back(DeadInst); } } @@ -2233,6 +2248,12 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, MadeChange |= State.eliminateRedundantStoresOfExistingValues(); MadeChange |= State.eliminateDeadWritesAtEndOfFunction(); + + while (!State.ToRemove.empty()) { +Instruction *DeadInst = State.ToRemove.pop_back_val(); +DeadInst->eraseFromParent(); + } + return MadeChange; } } // end anonymous namespace diff --git a/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll b/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll new file mode 100644 index 00..ee9bd6912e2ae4 --- /dev/null +++ b/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll @@ -0,0 +1,189 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt -S -passes=dse < %s | FileCheck %s +; +; DSE kills `store i32 44, ptr %struct.byte.4, align 4` but should not kill +; `call void @llvm.memset.p0.i64(...)` because it has a
[llvm-branch-commits] [llvm] release/18.x: [DSE] Delay deleting non-memory-defs until end of DSE. (#83411) (PR #84227)
https://github.com/llvmbot milestoned https://github.com/llvm/llvm-project/pull/84227 ___ 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] release/18.x: [DSE] Delay deleting non-memory-defs until end of DSE. (#83411) (PR #84227)
llvmbot wrote: @fhahn What do you think about merging this PR to the release branch? https://github.com/llvm/llvm-project/pull/84227 ___ 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] release/18.x: [DSE] Delay deleting non-memory-defs until end of DSE. (#83411) (PR #84227)
llvmbot wrote: @llvm/pr-subscribers-llvm-transforms Author: None (llvmbot) Changes Backport 10f5e983a9e3162a569cbebeb32168716e391340 Requested by: @fhahn --- Full diff: https://github.com/llvm/llvm-project/pull/84227.diff 2 Files Affected: - (modified) llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp (+26-5) - (added) llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll (+189) ``diff diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 11a91bfbe5baff..340fba4fb9c5a2 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -857,6 +857,9 @@ struct DSEState { // no longer be captured. bool ShouldIterateEndOfFunctionDSE; + /// Dead instructions to be removed at the end of DSE. + SmallVector ToRemove; + // Class contains self-reference, make sure it's not copied/moved. DSEState(const DSEState &) = delete; DSEState &operator=(const DSEState &) = delete; @@ -1692,7 +1695,8 @@ struct DSEState { return {MaybeDeadAccess}; } - // Delete dead memory defs + /// Delete dead memory defs and recursively add their operands to ToRemove if + /// they became dead. void deleteDeadInstruction(Instruction *SI) { MemorySSAUpdater Updater(&MSSA); SmallVector NowDeadInsts; @@ -1708,8 +1712,11 @@ struct DSEState { salvageKnowledge(DeadInst); // Remove the Instruction from MSSA. - if (MemoryAccess *MA = MSSA.getMemoryAccess(DeadInst)) { -if (MemoryDef *MD = dyn_cast(MA)) { + MemoryAccess *MA = MSSA.getMemoryAccess(DeadInst); + bool IsMemDef = MA && isa(MA); + if (MA) { +if (IsMemDef) { + auto *MD = cast(MA); SkipStores.insert(MD); if (auto *SI = dyn_cast(MD->getMemoryInst())) { if (SI->getValueOperand()->getType()->isPointerTy()) { @@ -1730,13 +1737,21 @@ struct DSEState { // Remove its operands for (Use &O : DeadInst->operands()) if (Instruction *OpI = dyn_cast(O)) { - O = nullptr; + O.set(PoisonValue::get(O->getType())); if (isInstructionTriviallyDead(OpI, &TLI)) NowDeadInsts.push_back(OpI); } EI.removeInstruction(DeadInst); - DeadInst->eraseFromParent(); + // Remove memory defs directly if they don't produce results, but only + // queue other dead instructions for later removal. They may have been + // used as memory locations that have been cached by BatchAA. Removing + // them here may lead to newly created instructions to be allocated at the + // same address, yielding stale cache entries. + if (IsMemDef && DeadInst->getType()->isVoidTy()) +DeadInst->eraseFromParent(); + else +ToRemove.push_back(DeadInst); } } @@ -2233,6 +2248,12 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, MadeChange |= State.eliminateRedundantStoresOfExistingValues(); MadeChange |= State.eliminateDeadWritesAtEndOfFunction(); + + while (!State.ToRemove.empty()) { +Instruction *DeadInst = State.ToRemove.pop_back_val(); +DeadInst->eraseFromParent(); + } + return MadeChange; } } // end anonymous namespace diff --git a/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll b/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll new file mode 100644 index 00..ee9bd6912e2ae4 --- /dev/null +++ b/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll @@ -0,0 +1,189 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt -S -passes=dse < %s | FileCheck %s +; +; DSE kills `store i32 44, ptr %struct.byte.4, align 4` but should not kill +; `call void @llvm.memset.p0.i64(...)` because it has a clobber read: +; `%ret = load ptr, ptr %struct.byte.8` + + +%struct.type = type { ptr, ptr } + +define ptr @foo(ptr noundef %ptr) { +; CHECK-LABEL: define ptr @foo( +; CHECK-SAME: ptr noundef [[PTR:%.*]]) { +; CHECK-NEXT:[[STRUCT_ALLOCA:%.*]] = alloca [[STRUCT_TYPE:%.*]], align 8 +; CHECK-NEXT:call void @llvm.lifetime.start.p0(i64 56, ptr nonnull [[STRUCT_ALLOCA]]) #[[ATTR6:[0-9]+]] +; CHECK-NEXT:[[STRUCT_BYTE_8:%.*]] = getelementptr inbounds i8, ptr [[STRUCT_ALLOCA]], i64 8 +; CHECK-NEXT:[[TMP1:%.*]] = getelementptr inbounds i8, ptr [[STRUCT_BYTE_8]], i64 4 +; CHECK-NEXT:call void @llvm.memset.p0.i64(ptr noundef nonnull align 4 [[TMP1]], i8 42, i64 4, i1 false) +; CHECK-NEXT:store i32 43, ptr [[STRUCT_BYTE_8]], align 4 +; CHECK-NEXT:[[RET:%.*]] = load ptr, ptr [[STRUCT_BYTE_8]], align 8 +; CHECK-NEXT:call void @llvm.lifetime.end.p0(i64 56, ptr nonnull [[STRUCT_ALLOCA]]) #[[ATTR6]] +; CHECK-NEXT:ret ptr [[RET]] +; + %struct.alloca = alloca %struct.type, align 8 + call void @ll
[llvm-branch-commits] [llvm] release/18.x: [DSE] Delay deleting non-memory-defs until end of DSE. (#83411) (PR #84227)
https://github.com/fhahn approved this pull request. LGTM, thanks! https://github.com/llvm/llvm-project/pull/84227 ___ 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] efe6097 - Revert "[clang-repl] Expose setter for triple in IncrementalCompilerBuilder (…"
Author: Stefan Gränitz Date: 2024-03-07T01:00:03+01:00 New Revision: efe6097aad69aba7d2421880305198bf09226db6 URL: https://github.com/llvm/llvm-project/commit/efe6097aad69aba7d2421880305198bf09226db6 DIFF: https://github.com/llvm/llvm-project/commit/efe6097aad69aba7d2421880305198bf09226db6.diff LOG: Revert "[clang-repl] Expose setter for triple in IncrementalCompilerBuilder (…" This reverts commit 6494f9bb8ac1e6f7526b72ee07f71527b8e66066. Added: Modified: clang/include/clang/Interpreter/Interpreter.h clang/lib/Interpreter/Interpreter.cpp clang/unittests/Interpreter/CMakeLists.txt Removed: clang/unittests/Interpreter/IncrementalCompilerBuilderTest.cpp diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index c8f932e95c4798..292fa566ae7037 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -48,8 +48,6 @@ class IncrementalCompilerBuilder { UserArgs = Args; } - void SetTargetTriple(std::string TT) { TargetTriple = TT; } - // General C++ llvm::Expected> CreateCpp(); @@ -64,12 +62,11 @@ class IncrementalCompilerBuilder { private: static llvm::Expected> - create(std::string TT, std::vector &ClangArgv); + create(std::vector &ClangArgv); llvm::Expected> createCuda(bool device); std::vector UserArgs; - std::optional TargetTriple; llvm::StringRef OffloadArch; llvm::StringRef CudaSDKPath; diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 37696b28976428..9f97a3c6b0be9e 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -132,8 +132,7 @@ CreateCI(const llvm::opt::ArgStringList &Argv) { } // anonymous namespace llvm::Expected> -IncrementalCompilerBuilder::create(std::string TT, - std::vector &ClangArgv) { +IncrementalCompilerBuilder::create(std::vector &ClangArgv) { // If we don't know ClangArgv0 or the address of main() at this point, try // to guess it anyway (it's possible on some platforms). @@ -163,7 +162,8 @@ IncrementalCompilerBuilder::create(std::string TT, TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); - driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags); + driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], +llvm::sys::getProcessTriple(), Diags); Driver.setCheckInputsExist(false); // the input comes from mem buffers llvm::ArrayRef RF = llvm::ArrayRef(ClangArgv); std::unique_ptr Compilation(Driver.BuildCompilation(RF)); @@ -185,8 +185,7 @@ IncrementalCompilerBuilder::CreateCpp() { Argv.push_back("-xc++"); Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); - std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple(); - return IncrementalCompilerBuilder::create(TT, Argv); + return IncrementalCompilerBuilder::create(Argv); } llvm::Expected> @@ -214,8 +213,7 @@ IncrementalCompilerBuilder::createCuda(bool device) { Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); - std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple(); - return IncrementalCompilerBuilder::create(TT, Argv); + return IncrementalCompilerBuilder::create(Argv); } llvm::Expected> diff --git a/clang/unittests/Interpreter/CMakeLists.txt b/clang/unittests/Interpreter/CMakeLists.txt index 0ddedb283e07d1..712641afb976dd 100644 --- a/clang/unittests/Interpreter/CMakeLists.txt +++ b/clang/unittests/Interpreter/CMakeLists.txt @@ -7,7 +7,6 @@ set(LLVM_LINK_COMPONENTS ) add_clang_unittest(ClangReplInterpreterTests - IncrementalCompilerBuilderTest.cpp IncrementalProcessingTest.cpp InterpreterTest.cpp CodeCompletionTest.cpp diff --git a/clang/unittests/Interpreter/IncrementalCompilerBuilderTest.cpp b/clang/unittests/Interpreter/IncrementalCompilerBuilderTest.cpp deleted file mode 100644 index 1cc0223465c8fa..00 --- a/clang/unittests/Interpreter/IncrementalCompilerBuilderTest.cpp +++ /dev/null @@ -1,35 +0,0 @@ -//=== unittests/Interpreter/IncrementalCompilerBuilderTest.cpp ===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===--===// - -#include "clang/Basic/TargetOptions.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Interpreter/Interpreter.h" -#include "llvm/Support/Error.h" -#include "gtest/gtest.h" - -using namespace llvm; -using namespace clang; - -namespace { - -TEST(IncrementalCompilerBuilder, SetCompilerArgs) { - std::vec
[llvm-branch-commits] [llvm] 68d45f8 - Revert "[AMDGPU] Add AMDGPU specific variadic operation MCExprs (#82022)"
Author: Florian Mayer Date: 2024-03-06T19:35:15-08:00 New Revision: 68d45f82080bc423fb9a78dd7112ce2b9ee46e99 URL: https://github.com/llvm/llvm-project/commit/68d45f82080bc423fb9a78dd7112ce2b9ee46e99 DIFF: https://github.com/llvm/llvm-project/commit/68d45f82080bc423fb9a78dd7112ce2b9ee46e99.diff LOG: Revert "[AMDGPU] Add AMDGPU specific variadic operation MCExprs (#82022)" This reverts commit bec2d105c7b8b39c6d090146d076201d1cd61991. Added: Modified: llvm/docs/AMDGPUUsage.rst llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp llvm/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt Removed: llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h llvm/test/MC/AMDGPU/mcexpr_amd.s llvm/test/MC/AMDGPU/mcexpr_amd_err.s diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst index c7cb06ffbef1e0..7f39f69cae60db 100644 --- a/llvm/docs/AMDGPUUsage.rst +++ b/llvm/docs/AMDGPUUsage.rst @@ -1534,25 +1534,6 @@ The AMDGPU backend supports the following calling conventions: === == -AMDGPU MCExpr -- - -As part of the AMDGPU MC layer, AMDGPU provides the following target specific -``MCExpr``\s. - - .. table:: AMDGPU MCExpr types: - :name: amdgpu-mcexpr-table - - === = - MCExpr Operands Return value - === = - ``max(arg, ...)`` 1 or more Variadic signed operation that returns the maximum - value of all its arguments. - - ``or(arg, ...)``1 or more Variadic signed operation that returns the bitwise-or - result of all its arguments. - - === = .. _amdgpu-elf-code-object: diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 16a5d6879ce777..cb4eddfe5320fa 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -7,7 +7,6 @@ //===--===// #include "AMDKernelCodeT.h" -#include "MCTargetDesc/AMDGPUMCExpr.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "MCTargetDesc/AMDGPUTargetStreamer.h" #include "SIDefines.h" @@ -1817,7 +1816,6 @@ class AMDGPUAsmParser : public MCTargetAsmParser { public: void onBeginOfFile() override; - bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override; ParseStatus parseCustomOperand(OperandVector &Operands, unsigned MCK); @@ -8279,59 +8277,6 @@ void AMDGPUAsmParser::onBeginOfFile() { getTargetStreamer().EmitDirectiveAMDGCNTarget(); } -/// Parse AMDGPU specific expressions. -/// -/// expr ::= or(expr, ...) | -/// max(expr, ...) -/// -bool AMDGPUAsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { - using AGVK = AMDGPUVariadicMCExpr::VariadicKind; - - if (isToken(AsmToken::Identifier)) { -StringRef TokenId = getTokenStr(); -AGVK VK = StringSwitch(TokenId) - .Case("max", AGVK::AGVK_Max) - .Case("or", AGVK::AGVK_Or) - .Default(AGVK::AGVK_None); - -if (VK != AGVK::AGVK_None && peekToken().is(AsmToken::LParen)) { - SmallVector Exprs; - uint64_t CommaCount = 0; - lex(); // Eat 'max'/'or' - lex(); // Eat '(' - while (true) { -if (trySkipToken(AsmToken::RParen)) { - if (Exprs.empty()) { -Error(getToken().getLoc(), - "empty " + Twine(TokenId) + " expression"); -return true; - } - if (CommaCount + 1 != Exprs.size()) { -Error(getToken().getLoc(), - "mismatch of commas in " + Twine(TokenId) + " expression"); -return true; - } - Res = AMDGPUVariadicMCExpr::create(VK, Exprs, getContext()); - return false; -} -const MCExpr *Expr; -if (getParser().parseExpression(Expr, EndLoc)) - return true; -Exprs.push_back(Expr); -bool LastTokenWasComma = trySkipToken(AsmToken::Comma); -if (LastTokenWasComma) - CommaCount++; -if (!LastTokenWasComma && !isToken(AsmToken::RParen)) { - Error(getToken().getLoc(), -"unexpected token in " + Twine(TokenId) + " expression"); - return true; -} - } -} - } - return getParser().parsePrimaryExpr(Res, EndLoc, nullptr); -} - ParseStatus AMDGPUAsmParser::pa
[llvm-branch-commits] [clang] [analyzer] Backport deducing "this" crash fix (PR #84194)
https://github.com/Snape3058 edited https://github.com/llvm/llvm-project/pull/84194 ___ 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] release/18.x: [TableGen] Fix wrong codegen of BothFusionPredicateWithMCInstPredicate (#83990) (PR #83999)
wangpc-pp wrote: Ping? https://github.com/llvm/llvm-project/pull/83999 ___ 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] [MSan] Pass -fsanitize-ignorelist to the instrumented libcxxabi (PR #83652)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/83652 ___ 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] [MSan] Pass -fsanitize-ignorelist to the instrumented libcxxabi (PR #83652)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/83652 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits