[llvm-branch-commits] [mlir] [mlir][Transforms][NFC] Simplify handling of erased IR (PR #83423)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/83423 The dialect conversion uses a `SingleEraseRewriter` to ensure that an op/block is not erased twice. This can happen during the "commit" phase when an unresolved materialization is inserted into a block and the enclosing op is erased by the user. In that case, the unresolved materialization should not be erased a second time later in the "commit" phase. This problem cannot happen during "rollback", so ops/block can be erased directly without using the rewriter. With this change, the `SingleEraseRewriter` is used only during "commit"/"cleanup". At that point, the dialect conversion is guaranteed to succeed and no rollback can happen. Therefore, it is not necessary to store the number of erased IR objects (because we will never "reset" the rewriter to previous a previous state). >From 6b6c4b1a7dd4943bfe2d97245e8369b9ba63aa20 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Thu, 29 Feb 2024 12:48:28 + Subject: [PATCH] [mlir][Transforms][NFC] Do not use SingleEraseRewriter during rollback --- .../Transforms/Utils/DialectConversion.cpp| 22 +++ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index cac990d498d7d3..9f6468402686bd 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -153,9 +153,9 @@ namespace { /// This is useful when saving and undoing a set of rewrites. struct RewriterState { RewriterState(unsigned numRewrites, unsigned numIgnoredOperations, -unsigned numErased, unsigned numReplacedOps) +unsigned numReplacedOps) : numRewrites(numRewrites), numIgnoredOperations(numIgnoredOperations), -numErased(numErased), numReplacedOps(numReplacedOps) {} +numReplacedOps(numReplacedOps) {} /// The current number of rewrites performed. unsigned numRewrites; @@ -163,9 +163,6 @@ struct RewriterState { /// The current number of ignored operations. unsigned numIgnoredOperations; - /// The current number of erased operations/blocks. - unsigned numErased; - /// The current number of replaced ops that are scheduled for erasure. unsigned numReplacedOps; }; @@ -273,8 +270,9 @@ class CreateBlockRewrite : public BlockRewrite { auto &blockOps = block->getOperations(); while (!blockOps.empty()) blockOps.remove(blockOps.begin()); +block->dropAllUses(); if (block->getParent()) - eraseBlock(block); + block->erase(); else delete block; } @@ -858,7 +856,7 @@ struct ConversionPatternRewriterImpl : public RewriterBase::Listener { void notifyBlockErased(Block *block) override { erased.insert(block); } /// Pointers to all erased operations and blocks. -SetVector erased; +DenseSet erased; }; //======// @@ -1044,7 +1042,7 @@ void CreateOperationRewrite::rollback() { region.getBlocks().remove(region.getBlocks().begin()); } op->dropAllUses(); - eraseOp(op); + op->erase(); } void UnresolvedMaterializationRewrite::rollback() { @@ -1052,7 +1050,7 @@ void UnresolvedMaterializationRewrite::rollback() { for (Value input : op->getOperands()) rewriterImpl.mapping.erase(input); } - eraseOp(op); + op->erase(); } void UnresolvedMaterializationRewrite::cleanup() { eraseOp(op); } @@ -1069,8 +1067,7 @@ void ConversionPatternRewriterImpl::applyRewrites() { // State Management RewriterState ConversionPatternRewriterImpl::getCurrentState() { - return RewriterState(rewrites.size(), ignoredOps.size(), - eraseRewriter.erased.size(), replacedOps.size()); + return RewriterState(rewrites.size(), ignoredOps.size(), replacedOps.size()); } void ConversionPatternRewriterImpl::resetState(RewriterState state) { @@ -1081,9 +1078,6 @@ void ConversionPatternRewriterImpl::resetState(RewriterState state) { while (ignoredOps.size() != state.numIgnoredOperations) ignoredOps.pop_back(); - while (eraseRewriter.erased.size() != state.numErased) -eraseRewriter.erased.pop_back(); - while (replacedOps.size() != state.numReplacedOps) replacedOps.pop_back(); } ___ 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] Simplify handling of erased IR (PR #83423)
llvmbot wrote: @llvm/pr-subscribers-mlir-core @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes The dialect conversion uses a `SingleEraseRewriter` to ensure that an op/block is not erased twice. This can happen during the "commit" phase when an unresolved materialization is inserted into a block and the enclosing op is erased by the user. In that case, the unresolved materialization should not be erased a second time later in the "commit" phase. This problem cannot happen during "rollback", so ops/block can be erased directly without using the rewriter. With this change, the `SingleEraseRewriter` is used only during "commit"/"cleanup". At that point, the dialect conversion is guaranteed to succeed and no rollback can happen. Therefore, it is not necessary to store the number of erased IR objects (because we will never "reset" the rewriter to previous a previous state). --- Full diff: https://github.com/llvm/llvm-project/pull/83423.diff 1 Files Affected: - (modified) mlir/lib/Transforms/Utils/DialectConversion.cpp (+8-14) ``diff diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index cac990d498d7d3..9f6468402686bd 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -153,9 +153,9 @@ namespace { /// This is useful when saving and undoing a set of rewrites. struct RewriterState { RewriterState(unsigned numRewrites, unsigned numIgnoredOperations, -unsigned numErased, unsigned numReplacedOps) +unsigned numReplacedOps) : numRewrites(numRewrites), numIgnoredOperations(numIgnoredOperations), -numErased(numErased), numReplacedOps(numReplacedOps) {} +numReplacedOps(numReplacedOps) {} /// The current number of rewrites performed. unsigned numRewrites; @@ -163,9 +163,6 @@ struct RewriterState { /// The current number of ignored operations. unsigned numIgnoredOperations; - /// The current number of erased operations/blocks. - unsigned numErased; - /// The current number of replaced ops that are scheduled for erasure. unsigned numReplacedOps; }; @@ -273,8 +270,9 @@ class CreateBlockRewrite : public BlockRewrite { auto &blockOps = block->getOperations(); while (!blockOps.empty()) blockOps.remove(blockOps.begin()); +block->dropAllUses(); if (block->getParent()) - eraseBlock(block); + block->erase(); else delete block; } @@ -858,7 +856,7 @@ struct ConversionPatternRewriterImpl : public RewriterBase::Listener { void notifyBlockErased(Block *block) override { erased.insert(block); } /// Pointers to all erased operations and blocks. -SetVector erased; +DenseSet erased; }; //======// @@ -1044,7 +1042,7 @@ void CreateOperationRewrite::rollback() { region.getBlocks().remove(region.getBlocks().begin()); } op->dropAllUses(); - eraseOp(op); + op->erase(); } void UnresolvedMaterializationRewrite::rollback() { @@ -1052,7 +1050,7 @@ void UnresolvedMaterializationRewrite::rollback() { for (Value input : op->getOperands()) rewriterImpl.mapping.erase(input); } - eraseOp(op); + op->erase(); } void UnresolvedMaterializationRewrite::cleanup() { eraseOp(op); } @@ -1069,8 +1067,7 @@ void ConversionPatternRewriterImpl::applyRewrites() { // State Management RewriterState ConversionPatternRewriterImpl::getCurrentState() { - return RewriterState(rewrites.size(), ignoredOps.size(), - eraseRewriter.erased.size(), replacedOps.size()); + return RewriterState(rewrites.size(), ignoredOps.size(), replacedOps.size()); } void ConversionPatternRewriterImpl::resetState(RewriterState state) { @@ -1081,9 +1078,6 @@ void ConversionPatternRewriterImpl::resetState(RewriterState state) { while (ignoredOps.size() != state.numIgnoredOperations) ignoredOps.pop_back(); - while (eraseRewriter.erased.size() != state.numErased) -eraseRewriter.erased.pop_back(); - while (replacedOps.size() != state.numReplacedOps) replacedOps.pop_back(); } `` https://github.com/llvm/llvm-project/pull/83423 ___ 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] Add listener support to dialect conversion (PR #83425)
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/83425 This commit adds listener support to the dialect conversion. Similarly to the greedy pattern rewrite driver, an optional listener can be specified in the configuration object. Listeners are notified only if the dialect conversion succeeds. In case of a failure, where some IR changes are first performed and then rolled back, no notifications are sent. Due to the fact that some kinds of rewrite are reflected in the IR immediately and some in a delayed fashion, there are certain limitations when attaching a listener; these are documented in `ConversionConfig`. To summarize, users are always notified about all rewrites that happened, but the notifications are sent all at once at the very end, and not interleaved with the actual IR changes. This change is in preparation improvements to `transform.apply_conversion_patterns`, which currently invalidates all handles. In the future, it can use a listener to update handles accordingly, similar to `transform.apply_patterns`. >From 216e0b2d62e418cddcb6e4ecf6b07be361141131 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Thu, 29 Feb 2024 12:58:26 + Subject: [PATCH] [mlir][Transforms] Add listener support to dialect conversion --- .../mlir/Transforms/DialectConversion.h | 26 +++ .../Transforms/Utils/DialectConversion.cpp| 174 +- mlir/test/Transforms/test-legalizer.mlir | 71 ++- mlir/test/lib/Dialect/Test/TestPatterns.cpp | 28 ++- 4 files changed, 248 insertions(+), 51 deletions(-) diff --git a/mlir/include/mlir/Transforms/DialectConversion.h b/mlir/include/mlir/Transforms/DialectConversion.h index 84396529eb7c2e..98944b8a1ea648 100644 --- a/mlir/include/mlir/Transforms/DialectConversion.h +++ b/mlir/include/mlir/Transforms/DialectConversion.h @@ -1091,6 +1091,32 @@ struct ConversionConfig { /// IR during an analysis conversion and only pre-existing operations are /// added to the set. DenseSet *legalizableOps = nullptr; + + /// An optional listener that is notified about all IR modifications in case + /// dialect conversion succeeds. If the dialect conversion fails and no IR + /// modifications are visible (i.e., they were all rolled back), no + /// notifications are sent. + /// + /// Note: Notifications are sent in a delayed fashion, when the dialect + /// conversion is guaranteed to succeed. At that point, some IR modifications + /// may already have been materialized. Consequently, operations/blocks that + /// are passed to listener callbacks should not be accessed. (Ops/blocks are + /// guaranteed to be valid pointers and accessing op names is allowed. But + /// there are no guarantees about the state of ops/blocks at the time that a + /// callback is triggered.) + /// + /// Example: Consider a dialect conversion a new op ("test.foo") is created + /// and inserted, and later moved to another block. (Moving ops also triggers + /// "notifyOperationInserted".) + /// + /// (1) notifyOperationInserted: "test.foo" (into block "b1") + /// (2) notifyOperationInserted: "test.foo" (moved to another block "b2") + /// + /// When querying "op->getBlock()" during the first "notifyOperationInserted", + /// "b2" would be returned because "moving an op" is a kind of rewrite that is + /// immediately performed by the dialect conversion (and rolled back upon + /// failure). + RewriterBase::Listener *listener = nullptr; }; //===--===// diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index 9f6468402686bd..0048347cae9314 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -203,14 +203,22 @@ class IRRewrite { /// Roll back the rewrite. Operations may be erased during rollback. virtual void rollback() = 0; - /// Commit the rewrite. Operations may be unlinked from their blocks during - /// the commit phase, but they must not be erased yet. This is because - /// internal dialect conversion state (such as `mapping`) may still be using - /// them. Operations must be erased during cleanup. - virtual void commit() {} + /// Commit the rewrite. At this point, it is certain that the dialect + /// conversion will succeed. All IR modifications, except for operation + /// erasure, must be performed through the given rewriter. + /// + /// Instead of erasing operations, they should merely be unlinked from their + /// blocks during the commit phase and finally be erased during the cleanup + /// phase. This is because internal dialect conversion state (such as + /// `mapping`) may still be using them. + /// + /// Any IR modification that was already performed before the commit phase + /// (e.g., insertion of an op) must be communicated to the listener that may + /// be attache
[llvm-branch-commits] [mlir] [mlir][Transforms] Add listener support to dialect conversion (PR #83425)
llvmbot wrote: @llvm/pr-subscribers-mlir-core Author: Matthias Springer (matthias-springer) Changes This commit adds listener support to the dialect conversion. Similarly to the greedy pattern rewrite driver, an optional listener can be specified in the configuration object. Listeners are notified only if the dialect conversion succeeds. In case of a failure, where some IR changes are first performed and then rolled back, no notifications are sent. Due to the fact that some kinds of rewrite are reflected in the IR immediately and some in a delayed fashion, there are certain limitations when attaching a listener; these are documented in `ConversionConfig`. To summarize, users are always notified about all rewrites that happened, but the notifications are sent all at once at the very end, and not interleaved with the actual IR changes. This change is in preparation improvements to `transform.apply_conversion_patterns`, which currently invalidates all handles. In the future, it can use a listener to update handles accordingly, similar to `transform.apply_patterns`. --- Patch is 24.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/83425.diff 4 Files Affected: - (modified) mlir/include/mlir/Transforms/DialectConversion.h (+26) - (modified) mlir/lib/Transforms/Utils/DialectConversion.cpp (+128-46) - (modified) mlir/test/Transforms/test-legalizer.mlir (+70-1) - (modified) mlir/test/lib/Dialect/Test/TestPatterns.cpp (+24-4) ``diff diff --git a/mlir/include/mlir/Transforms/DialectConversion.h b/mlir/include/mlir/Transforms/DialectConversion.h index 84396529eb7c2e..98944b8a1ea648 100644 --- a/mlir/include/mlir/Transforms/DialectConversion.h +++ b/mlir/include/mlir/Transforms/DialectConversion.h @@ -1091,6 +1091,32 @@ struct ConversionConfig { /// IR during an analysis conversion and only pre-existing operations are /// added to the set. DenseSet *legalizableOps = nullptr; + + /// An optional listener that is notified about all IR modifications in case + /// dialect conversion succeeds. If the dialect conversion fails and no IR + /// modifications are visible (i.e., they were all rolled back), no + /// notifications are sent. + /// + /// Note: Notifications are sent in a delayed fashion, when the dialect + /// conversion is guaranteed to succeed. At that point, some IR modifications + /// may already have been materialized. Consequently, operations/blocks that + /// are passed to listener callbacks should not be accessed. (Ops/blocks are + /// guaranteed to be valid pointers and accessing op names is allowed. But + /// there are no guarantees about the state of ops/blocks at the time that a + /// callback is triggered.) + /// + /// Example: Consider a dialect conversion a new op ("test.foo") is created + /// and inserted, and later moved to another block. (Moving ops also triggers + /// "notifyOperationInserted".) + /// + /// (1) notifyOperationInserted: "test.foo" (into block "b1") + /// (2) notifyOperationInserted: "test.foo" (moved to another block "b2") + /// + /// When querying "op->getBlock()" during the first "notifyOperationInserted", + /// "b2" would be returned because "moving an op" is a kind of rewrite that is + /// immediately performed by the dialect conversion (and rolled back upon + /// failure). + RewriterBase::Listener *listener = nullptr; }; //===--===// diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index 9f6468402686bd..0048347cae9314 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -203,14 +203,22 @@ class IRRewrite { /// Roll back the rewrite. Operations may be erased during rollback. virtual void rollback() = 0; - /// Commit the rewrite. Operations may be unlinked from their blocks during - /// the commit phase, but they must not be erased yet. This is because - /// internal dialect conversion state (such as `mapping`) may still be using - /// them. Operations must be erased during cleanup. - virtual void commit() {} + /// Commit the rewrite. At this point, it is certain that the dialect + /// conversion will succeed. All IR modifications, except for operation + /// erasure, must be performed through the given rewriter. + /// + /// Instead of erasing operations, they should merely be unlinked from their + /// blocks during the commit phase and finally be erased during the cleanup + /// phase. This is because internal dialect conversion state (such as + /// `mapping`) may still be using them. + /// + /// Any IR modification that was already performed before the commit phase + /// (e.g., insertion of an op) must be communicated to the listener that may + /// be attached to the given rewriter. + virtual void commit(RewriterBase &rewriter) {}
[llvm-branch-commits] [mlir] [mlir][Transforms] Add listener support to dialect conversion (PR #83425)
https://github.com/matthias-springer updated https://github.com/llvm/llvm-project/pull/83425 >From 22e8d5ea80b74d687c3e792c512f50b9de81f489 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Thu, 29 Feb 2024 12:58:26 + Subject: [PATCH] [mlir][Transforms] Add listener support to dialect conversion --- .../mlir/Transforms/DialectConversion.h | 26 +++ .../Transforms/Utils/DialectConversion.cpp| 174 +- mlir/test/Transforms/test-legalizer.mlir | 71 ++- mlir/test/lib/Dialect/Test/TestPatterns.cpp | 28 ++- 4 files changed, 248 insertions(+), 51 deletions(-) diff --git a/mlir/include/mlir/Transforms/DialectConversion.h b/mlir/include/mlir/Transforms/DialectConversion.h index 84396529eb7c2e..98944b8a1ea648 100644 --- a/mlir/include/mlir/Transforms/DialectConversion.h +++ b/mlir/include/mlir/Transforms/DialectConversion.h @@ -1091,6 +1091,32 @@ struct ConversionConfig { /// IR during an analysis conversion and only pre-existing operations are /// added to the set. DenseSet *legalizableOps = nullptr; + + /// An optional listener that is notified about all IR modifications in case + /// dialect conversion succeeds. If the dialect conversion fails and no IR + /// modifications are visible (i.e., they were all rolled back), no + /// notifications are sent. + /// + /// Note: Notifications are sent in a delayed fashion, when the dialect + /// conversion is guaranteed to succeed. At that point, some IR modifications + /// may already have been materialized. Consequently, operations/blocks that + /// are passed to listener callbacks should not be accessed. (Ops/blocks are + /// guaranteed to be valid pointers and accessing op names is allowed. But + /// there are no guarantees about the state of ops/blocks at the time that a + /// callback is triggered.) + /// + /// Example: Consider a dialect conversion a new op ("test.foo") is created + /// and inserted, and later moved to another block. (Moving ops also triggers + /// "notifyOperationInserted".) + /// + /// (1) notifyOperationInserted: "test.foo" (into block "b1") + /// (2) notifyOperationInserted: "test.foo" (moved to another block "b2") + /// + /// When querying "op->getBlock()" during the first "notifyOperationInserted", + /// "b2" would be returned because "moving an op" is a kind of rewrite that is + /// immediately performed by the dialect conversion (and rolled back upon + /// failure). + RewriterBase::Listener *listener = nullptr; }; //===--===// diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index 9f6468402686bd..0048347cae9314 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -203,14 +203,22 @@ class IRRewrite { /// Roll back the rewrite. Operations may be erased during rollback. virtual void rollback() = 0; - /// Commit the rewrite. Operations may be unlinked from their blocks during - /// the commit phase, but they must not be erased yet. This is because - /// internal dialect conversion state (such as `mapping`) may still be using - /// them. Operations must be erased during cleanup. - virtual void commit() {} + /// Commit the rewrite. At this point, it is certain that the dialect + /// conversion will succeed. All IR modifications, except for operation + /// erasure, must be performed through the given rewriter. + /// + /// Instead of erasing operations, they should merely be unlinked from their + /// blocks during the commit phase and finally be erased during the cleanup + /// phase. This is because internal dialect conversion state (such as + /// `mapping`) may still be using them. + /// + /// Any IR modification that was already performed before the commit phase + /// (e.g., insertion of an op) must be communicated to the listener that may + /// be attached to the given rewriter. + virtual void commit(RewriterBase &rewriter) {} /// Cleanup operations. Cleanup is called after commit. - virtual void cleanup() {} + virtual void cleanup(RewriterBase &rewriter) {} Kind getKind() const { return kind; } @@ -220,12 +228,6 @@ class IRRewrite { IRRewrite(Kind kind, ConversionPatternRewriterImpl &rewriterImpl) : kind(kind), rewriterImpl(rewriterImpl) {} - /// Erase the given op (unless it was already erased). - void eraseOp(Operation *op); - - /// Erase the given block (unless it was already erased). - void eraseBlock(Block *block); - const ConversionConfig &getConfig() const; const Kind kind; @@ -264,6 +266,12 @@ class CreateBlockRewrite : public BlockRewrite { return rewrite->getKind() == Kind::CreateBlock; } + void commit(RewriterBase &rewriter) override { +// The block was already created and inserted. Just inform the listener. +if (auto *listener = rewriter.getListener()) + lis
[llvm-branch-commits] [mlir] [mlir][Transforms][NFC] Simplify `BlockTypeConversionRewrite` (PR #83286)
https://github.com/jpienaar approved this pull request. https://github.com/llvm/llvm-project/pull/83286 ___ 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] Simplify handling of erased IR (PR #83423)
https://github.com/jpienaar approved this pull request. https://github.com/llvm/llvm-project/pull/83423 ___ 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)
vgvassilev wrote: > @vgvassilev this may be ready to test. I triggered a test here: https://github.com/root-project/root/pull/14495 I still need to verify if I did not screw up bringing your changes back to our builds but locally it crashes quite early with: ``` 0 rootcling_stage1 0x0001091d1c9d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 61 1 rootcling_stage1 0x0001091d221b PrintStackTraceSignalHandler(void*) + 27 2 rootcling_stage1 0x0001091cff06 llvm::sys::RunSignalHandlers() + 134 3 rootcling_stage1 0x0001091d480f SignalHandler(int) + 223 4 libsystem_platform.dylib 0x7ff800ad137d _sigtramp + 29 5 rootcling_stage1 0x000100059595 llvm::SmallVectorTemplateCommon::assertSafeToReferenceAfterResize(void const*, unsigned long) + 37 6 libsystem_c.dylib0x7ff8009c1a49 abort + 126 7 libsystem_c.dylib0x7ff8009c0d30 err + 0 8 rootcling_stage1 0x0001019959f0 llvm::SmallVectorTemplateCommon::operator[](unsigned long) const + 96 9 rootcling_stage1 0x0001017d43d9 clang::ASTReader::ReadString(llvm::SmallVector const&, unsigned int&) + 57 10 rootcling_stage1 0x0001017e0f0b clang::ASTReader::ParseLanguageOptions(llvm::SmallVector const&, bool, clang::ASTReaderListener&, bool) + 27691 11 rootcling_stage1 0x0001017da096 clang::ASTReader::ReadOptionsBlock(llvm::BitstreamCursor&, unsigned int, bool, clang::ASTReaderListener&, std::__1::basic_string, std::__1::allocator>&) + 758 12 rootcling_stage1 0x0001017e2537 clang::ASTReader::ReadControlBlock(clang::serialization::ModuleFile&, llvm::SmallVectorImpl&, clang::serialization::ModuleFile const*, unsigned int) + 2487 13 rootcling_stage1 0x0001017e487e clang::ASTReader::ReadASTCore(llvm::StringRef, clang::serialization::ModuleKind, clang::SourceLocation, clang::serialization::ModuleFile*, llvm::SmallVectorImpl&, long long, long, clang::ASTFileSignature, unsigned int) + 2110 14 rootcling_stage1 0x0001017efae3 clang::ASTReader::ReadAST(llvm::StringRef, clang::serialization::ModuleKind, clang::SourceLocation, unsigned int, llvm::SmallVectorImpl*) + 627 15 rootcling_stage1 0x000101249f53 clang::CompilerInstance::findOrCompileModuleAndReadAST(llvm::StringRef, clang::SourceLocation, clang::SourceLocation, bool) + 1443 16 rootcling_stage1 0x00010124b4be clang::CompilerInstance::loadModule(clang::SourceLocation, llvm::ArrayRef>, clang::Module::NameVisibilityKind, bool) + 1006 17 rootcling_stage1 0x000103f6a144 clang::Preprocessor::HandleHeaderIncludeOrImport(clang::SourceLocation, clang::Token&, clang::Token&, clang::SourceLocation, clang::detail::SearchDirIteratorImpl, clang::FileEntry const*) + 3348 18 rootcling_stage1 0x000103f648ec clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, clang::Token&, clang::detail::SearchDirIteratorImpl, clang::FileEntry const*) + 316 19 rootcling_stage1 0x000103f65064 clang::Preprocessor::HandleDirective(clang::Token&) + 1412 20 rootcling_stage1 0x000103f07de8 clang::Lexer::LexTokenInternal(clang::Token&, bool) + 10120 21 rootcling_stage1 0x000103f032ce clang::Lexer::Lex(clang::Token&) + 270 22 rootcling_stage1 0x000103fd3cbf clang::Preprocessor::Lex(clang::Token&) + 111 23 rootcling_stage1 0x0001005e1669 clang::Parser::ConsumeAnnotationToken() + 169 24 rootcling_stage1 0x0001017ab553 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) + 1475 25 rootcling_stage1 0x000100583b29 clang::Parser::ParseTopLevelDecl() + 57 26 rootcling_stage1 0x0001016b5d67 clang::Parser::ParseLinkage(clang::ParsingDeclSpec&, clang::DeclaratorContext) + 1303 27 rootcling_stage1 0x0001017afa70 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) + 1792 28 rootcling_stage1 0x0001017aef1a clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) + 218 29 rootcling_stage1 0x0001017adeb0 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) + 3920 30 rootcling_stage1 0x0001017ab8f3 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) + 2403 31 rootcling_stage1 0x0001017aaf00 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) + 64 32 rootcling_stage1 0x00010167af3b clang::ParseAST(clang::Sema&, bool, bool) + 459 33 rootcling_stage1 0x00010135a5cc clang::ASTFrontendAction::ExecuteAction() + 300 34 rootcling_stage1 0x000101359dcc c
[llvm-branch-commits] [mlir] 43a5e5d - Revert "[mlir][sparse] Migration to sparse_tensor.print (#83377)"
Author: Mehdi Amini Date: 2024-02-29T15:04:27-08:00 New Revision: 43a5e5da259de724dc310153dc4c219d102bd89a URL: https://github.com/llvm/llvm-project/commit/43a5e5da259de724dc310153dc4c219d102bd89a DIFF: https://github.com/llvm/llvm-project/commit/43a5e5da259de724dc310153dc4c219d102bd89a.diff LOG: Revert "[mlir][sparse] Migration to sparse_tensor.print (#83377)" This reverts commit 1ca65dd74a4370e5788c69e939106b53da13dbf6. Added: Modified: mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_loose.mlir mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_matmul.mlir mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_matmul_slice.mlir mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_matrix_ops.mlir Removed: diff --git a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_loose.mlir b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_loose.mlir index e1f062121b12f9..228d4e5f6f8a1a 100644 --- a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_loose.mlir +++ b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_loose.mlir @@ -10,7 +10,7 @@ // DEFINE: %{compile} = mlir-opt %s --sparsifier="%{sparsifier_opts}" // DEFINE: %{compile_sve} = mlir-opt %s --sparsifier="%{sparsifier_opts_sve}" // DEFINE: %{run_libs} = -shared-libs=%mlir_c_runner_utils,%mlir_runner_utils -// DEFINE: %{run_opts} = -e main -entry-point-result=void +// DEFINE: %{run_opts} = -e entry -entry-point-result=void // DEFINE: %{run} = mlir-cpu-runner %{run_opts} %{run_libs} // DEFINE: %{run_sve} = %mcr_aarch64_cmd --march=aarch64 --mattr="+sve" %{run_opts} %{run_libs} // @@ -28,7 +28,7 @@ }> module { - func.func @main() { + func.func @entry() { %c0 = arith.constant 0 : index %f0 = arith.constant 0.0 : f64 %d = arith.constant dense<[[ 1.0, 2.0, 3.0, 4.0 ], @@ -39,14 +39,19 @@ module { %s = sparse_tensor.convert %d : tensor<5x4xf64> to tensor<5x4xf64, #CSR_hi> // -// CHECK: Sparse Tensor -// CHECK-NEXT: nse = 17 -// CHECK-NEXT: pos[1] : ( 0, 4, 4, 8, 8, 9, 9, 13 -// CHECK-NEXT: crd[1] : ( 0, 1, 2, 3, 0, 1, 2, 3, 2, 0, 1, 2, 3, 0, 1, 2, 3 -// CHECK-NEXT: values : ( 1, 2, 3, 4, 5, 6, 7, 8, 5.5, 9, 10, 11, 12, 13, 14, 15, 16 -// CHECK-NEXT: +// CHECK: ( 0, 4, 4, 8, 8, 9, 9, 13 ) +// CHECK-NEXT: ( 0, 1, 2, 3, 0, 1, 2, 3, 2, 0, 1, 2, 3, 0, 1, 2, 3 ) +// CHECK-NEXT: ( 1, 2, 3, 4, 5, 6, 7, 8, 5.5, 9, 10, 11, 12, 13, 14, 15, 16 ) // -sparse_tensor.print %s : tensor<5x4xf64, #CSR_hi> +%pos = sparse_tensor.positions %s {level = 1 : index } : tensor<5x4xf64, #CSR_hi> to memref +%vecp = vector.transfer_read %pos[%c0], %c0 : memref, vector<8xindex> +vector.print %vecp : vector<8xindex> +%crd = sparse_tensor.coordinates %s {level = 1 : index } : tensor<5x4xf64, #CSR_hi> to memref +%vecc = vector.transfer_read %crd[%c0], %c0 : memref, vector<17xindex> +vector.print %vecc : vector<17xindex> +%val = sparse_tensor.values %s : tensor<5x4xf64, #CSR_hi> to memref +%vecv = vector.transfer_read %val[%c0], %f0 : memref, vector<17xf64> +vector.print %vecv : vector<17xf64> // Release the resources. bufferization.dealloc_tensor %s: tensor<5x4xf64, #CSR_hi> diff --git a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_matmul.mlir b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_matmul.mlir index 863e1c62370e32..fa0dbac269b926 100644 --- a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_matmul.mlir +++ b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_matmul.mlir @@ -10,7 +10,7 @@ // DEFINE: %{compile} = mlir-opt %s --sparsifier="%{sparsifier_opts}" // DEFINE: %{compile_sve} = mlir-opt %s --sparsifier="%{sparsifier_opts_sve}" // DEFINE: %{run_libs} = -shared-libs=%mlir_c_runner_utils,%mlir_runner_utils -// DEFINE: %{run_opts} = -e main -entry-point-result=void +// DEFINE: %{run_opts} = -e entry -entry-point-result=void // DEFINE: %{run} = mlir-cpu-runner %{run_opts} %{run_libs} // DEFINE: %{run_sve} = %mcr_aarch64_cmd --march=aarch64 --mattr="+sve" %{run_opts} %{run_libs} // @@ -90,7 +90,7 @@ module { // // Main driver. // - func.func @main() { + func.func @entry() { %c0 = arith.constant 0 : index // Initialize various matrices, dense for stress testing, @@ -140,94 +140,33 @@ module { %b4 = sparse_tensor.convert %sb : tensor<8x4xf64> to tensor<8x4xf64, #DCSR> // -// Sanity check before going into the computations. -// -// CHECK: Sparse Tensor -// CHECK-NEXT: nse = 32 -// CHECK-NEXT: pos[1] : ( 0, 8, 16, 24, 32 -// CHECK-NEXT: crd[1] : ( 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 -// CHECK-NEXT: values : ( 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2, 8.2, 1.3, 2.3, 3.3, 4.3, 5.3, 6.3
[llvm-branch-commits] [compiler-rt] [compiler-rt] Build libfuzzer sources with the chosen C++ compiler (PR #83090)
https://github.com/vitalybuka approved this pull request. https://github.com/llvm/llvm-project/pull/83090 ___ 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: The error message looks odd since the language options shouldn't be involved. 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] [llvm][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984) (PR #83536)
https://github.com/leecheechen created https://github.com/llvm/llvm-project/pull/83536 For instruction xvpermi.q, only [1:0] and [5:4] bits of operands[3] are used. The unused bits in operands[3] need to be set to 0 to avoid causing undefined behavior. (cherry picked from commit d7c80bba698bded48c1df4b4bb7424a181aa6195) >From b093677cef50398942c7b9505d4c742883ee7f93 Mon Sep 17 00:00:00 2001 From: leecheechen Date: Tue, 27 Feb 2024 15:38:11 +0800 Subject: [PATCH] [llvm][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984) For instruction xvpermi.q, only [1:0] and [5:4] bits of operands[3] are used. The unused bits in operands[3] need to be set to 0 to avoid causing undefined behavior. (cherry picked from commit d7c80bba698bded48c1df4b4bb7424a181aa6195) --- .../LoongArch/LoongArchISelLowering.cpp | 25 +++- .../CodeGen/LoongArch/lasx/intrinsic-permi.ll | 30 +++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 76c1a14fe0156c..3324dd2e8fc217 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -968,6 +968,28 @@ static SDValue checkIntrinsicImmArg(SDValue Op, unsigned ImmOp, return SDValue(); } +static SDValue checkAndModifyXVPERMI_QIntrinsicImmArg(SDValue Op, + SelectionDAG &DAG) { + SDValue Op3 = Op->getOperand(3); + uint64_t Imm = Op3->getAsZExtVal(); + // Check the range of ImmArg. + if (!isUInt<8>(Imm)) { +DAG.getContext()->emitError(Op->getOperationName(0) + +": argument out of range."); +return DAG.getNode(ISD::UNDEF, SDLoc(Op), Op.getValueType()); + } + + // For instruction xvpermi.q, only [1:0] and [5:4] bits of operands[3] + // are used. The unused bits in operands[3] need to be set to 0 to avoid + // causing undefined behavior on LA464. + if ((Imm & 0x33) != Imm) { +Op3 = DAG.getTargetConstant(Imm & 0x33, SDLoc(Op), Op3.getValueType()); +DAG.UpdateNodeOperands(Op.getNode(), Op->getOperand(0), Op->getOperand(1), + Op->getOperand(2), Op3); + } + return SDValue(); +} + SDValue LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { @@ -1225,13 +1247,14 @@ LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::loongarch_lsx_vextrins_d: case Intrinsic::loongarch_lasx_xvshuf4i_d: case Intrinsic::loongarch_lasx_xvpermi_w: - case Intrinsic::loongarch_lasx_xvpermi_q: case Intrinsic::loongarch_lasx_xvbitseli_b: case Intrinsic::loongarch_lasx_xvextrins_b: case Intrinsic::loongarch_lasx_xvextrins_h: case Intrinsic::loongarch_lasx_xvextrins_w: case Intrinsic::loongarch_lasx_xvextrins_d: return checkIntrinsicImmArg<8>(Op, 3, DAG); + case Intrinsic::loongarch_lasx_xvpermi_q: +return checkAndModifyXVPERMI_QIntrinsicImmArg(Op, DAG); case Intrinsic::loongarch_lsx_vrepli_b: case Intrinsic::loongarch_lsx_vrepli_h: case Intrinsic::loongarch_lsx_vrepli_w: diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll index 0d9f9daabc4488..92669d2e589558 100644 --- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll +++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll @@ -36,3 +36,33 @@ entry: %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 1) ret <32 x i8> %res } + +define <32 x i8> @lasx_xvpermi_q_204(<32 x i8> %va, <32 x i8> %vb) nounwind { +; CHECK-LABEL: lasx_xvpermi_q_204: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:xvpermi.q $xr0, $xr1, 0 +; CHECK-NEXT:ret +entry: + %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 204) + ret <32 x i8> %res +} + +define <32 x i8> @lasx_xvpermi_q_221(<32 x i8> %va, <32 x i8> %vb) nounwind { +; CHECK-LABEL: lasx_xvpermi_q_221: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:xvpermi.q $xr0, $xr1, 17 +; CHECK-NEXT:ret +entry: + %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 221) + ret <32 x i8> %res +} + +define <32 x i8> @lasx_xvpermi_q_255(<32 x i8> %va, <32 x i8> %vb) nounwind { +; CHECK-LABEL: lasx_xvpermi_q_255: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:xvpermi.q $xr0, $xr1, 51 +; CHECK-NEXT:ret +entry: + %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 255) + ret <32 x i8> %res +} ___ 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][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984) (PR #83536)
llvmbot wrote: @llvm/pr-subscribers-backend-loongarch Author: None (leecheechen) Changes For instruction xvpermi.q, only [1:0] and [5:4] bits of operands[3] are used. The unused bits in operands[3] need to be set to 0 to avoid causing undefined behavior. (cherry picked from commit d7c80bba698bded48c1df4b4bb7424a181aa6195) --- Full diff: https://github.com/llvm/llvm-project/pull/83536.diff 2 Files Affected: - (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+24-1) - (modified) llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll (+30) ``diff diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 76c1a14fe0156c..3324dd2e8fc217 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -968,6 +968,28 @@ static SDValue checkIntrinsicImmArg(SDValue Op, unsigned ImmOp, return SDValue(); } +static SDValue checkAndModifyXVPERMI_QIntrinsicImmArg(SDValue Op, + SelectionDAG &DAG) { + SDValue Op3 = Op->getOperand(3); + uint64_t Imm = Op3->getAsZExtVal(); + // Check the range of ImmArg. + if (!isUInt<8>(Imm)) { +DAG.getContext()->emitError(Op->getOperationName(0) + +": argument out of range."); +return DAG.getNode(ISD::UNDEF, SDLoc(Op), Op.getValueType()); + } + + // For instruction xvpermi.q, only [1:0] and [5:4] bits of operands[3] + // are used. The unused bits in operands[3] need to be set to 0 to avoid + // causing undefined behavior on LA464. + if ((Imm & 0x33) != Imm) { +Op3 = DAG.getTargetConstant(Imm & 0x33, SDLoc(Op), Op3.getValueType()); +DAG.UpdateNodeOperands(Op.getNode(), Op->getOperand(0), Op->getOperand(1), + Op->getOperand(2), Op3); + } + return SDValue(); +} + SDValue LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { @@ -1225,13 +1247,14 @@ LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::loongarch_lsx_vextrins_d: case Intrinsic::loongarch_lasx_xvshuf4i_d: case Intrinsic::loongarch_lasx_xvpermi_w: - case Intrinsic::loongarch_lasx_xvpermi_q: case Intrinsic::loongarch_lasx_xvbitseli_b: case Intrinsic::loongarch_lasx_xvextrins_b: case Intrinsic::loongarch_lasx_xvextrins_h: case Intrinsic::loongarch_lasx_xvextrins_w: case Intrinsic::loongarch_lasx_xvextrins_d: return checkIntrinsicImmArg<8>(Op, 3, DAG); + case Intrinsic::loongarch_lasx_xvpermi_q: +return checkAndModifyXVPERMI_QIntrinsicImmArg(Op, DAG); case Intrinsic::loongarch_lsx_vrepli_b: case Intrinsic::loongarch_lsx_vrepli_h: case Intrinsic::loongarch_lsx_vrepli_w: diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll index 0d9f9daabc4488..92669d2e589558 100644 --- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll +++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll @@ -36,3 +36,33 @@ entry: %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 1) ret <32 x i8> %res } + +define <32 x i8> @lasx_xvpermi_q_204(<32 x i8> %va, <32 x i8> %vb) nounwind { +; CHECK-LABEL: lasx_xvpermi_q_204: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:xvpermi.q $xr0, $xr1, 0 +; CHECK-NEXT:ret +entry: + %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 204) + ret <32 x i8> %res +} + +define <32 x i8> @lasx_xvpermi_q_221(<32 x i8> %va, <32 x i8> %vb) nounwind { +; CHECK-LABEL: lasx_xvpermi_q_221: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:xvpermi.q $xr0, $xr1, 17 +; CHECK-NEXT:ret +entry: + %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 221) + ret <32 x i8> %res +} + +define <32 x i8> @lasx_xvpermi_q_255(<32 x i8> %va, <32 x i8> %vb) nounwind { +; CHECK-LABEL: lasx_xvpermi_q_255: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:xvpermi.q $xr0, $xr1, 51 +; CHECK-NEXT:ret +entry: + %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 255) + ret <32 x i8> %res +} `` https://github.com/llvm/llvm-project/pull/83536 ___ 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][LoongArch] Improve loongarch_lasx_xvpermi_q instrinsic (#82984) (PR #83536)
https://github.com/leecheechen closed https://github.com/llvm/llvm-project/pull/83536 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits