[Mlir-commits] [mlir] [mlir][Vector] add vector.insert canonicalization pattern for vectors created from ub.poison (PR #142944)
Yang Bai
llvmlistbot at llvm.org
Mon Jun 30 08:33:17 PDT 2025
https://github.com/yangtetris updated https://github.com/llvm/llvm-project/pull/142944
>From c511a4ebea4895b707c6a6827ed7f4a54975fa02 Mon Sep 17 00:00:00 2001
From: Yang Bai <yangb at nvidia.com>
Date: Thu, 5 Jun 2025 03:43:23 -0700
Subject: [PATCH 1/7] add vector.insert canonicalization pattern for vectors
created from ub.poison
---
mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 174 +++++++++++++++++----
mlir/test/Dialect/Vector/canonicalize.mlir | 32 ++++
2 files changed, 177 insertions(+), 29 deletions(-)
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index fcfb401fd9867..253d148072dc0 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -3149,6 +3149,42 @@ LogicalResult InsertOp::verify() {
return success();
}
+// Calculate the linearized position for inserting elements and extract values
+// from the source attribute. Returns the starting position in the destination
+// vector where elements should be inserted.
+static int64_t calculateInsertPositionAndExtractValues(
+ VectorType destTy, const ArrayRef<int64_t> &positions, Attribute srcAttr,
+ SmallVector<Attribute> &valueToInsert) {
+ llvm::SmallVector<int64_t> completePositions(destTy.getRank(), 0);
+ copy(positions, completePositions.begin());
+ int64_t insertBeginPosition =
+ linearize(completePositions, computeStrides(destTy.getShape()));
+
+ Type destEltType = destTy.getElementType();
+
+ /// Converts the expected type to an IntegerAttr if there's
+ /// a mismatch.
+ auto convertIntegerAttr = [](Attribute attr, Type expectedType) -> Attribute {
+ if (auto intAttr = mlir::dyn_cast<IntegerAttr>(attr)) {
+ if (intAttr.getType() != expectedType)
+ return IntegerAttr::get(expectedType, intAttr.getInt());
+ }
+ return attr;
+ };
+
+ // The `convertIntegerAttr` method specifically handles the case
+ // for `llvm.mlir.constant` which can hold an attribute with a
+ // different type than the return type.
+ if (auto denseSource = llvm::dyn_cast<DenseElementsAttr>(srcAttr)) {
+ for (auto value : denseSource.getValues<Attribute>())
+ valueToInsert.push_back(convertIntegerAttr(value, destEltType));
+ } else {
+ valueToInsert.push_back(convertIntegerAttr(srcAttr, destEltType));
+ }
+
+ return insertBeginPosition;
+}
+
namespace {
// If insertOp is only inserting unit dimensions it can be transformed to a
@@ -3191,6 +3227,109 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
}
};
+// Pattern to optimize a chain of constant insertions into a poison vector.
+//
+// This pattern identifies chains of vector.insert operations that:
+// 1. Start from an ub.poison operation.
+// 2. Insert only constant values at static positions.
+// 3. Completely initialize all elements in the resulting vector.
+//
+// When these conditions are met, the entire chain can be replaced with a
+// single arith.constant operation containing a dense elements attribute.
+//
+// Example transformation:
+// %poison = ub.poison : vector<2xi32>
+// %0 = vector.insert %c1, %poison[0] : i32 into vector<2xi32>
+// %1 = vector.insert %c2, %0[1] : i32 into vector<2xi32>
+// ->
+// %result = arith.constant dense<[1, 2]> : vector<2xi32>
+
+// TODO: Support the case where only some elements of the poison vector are set.
+// Currently, MLIR doesn't support partial poison vectors.
+
+class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
+public:
+ using OpRewritePattern::OpRewritePattern;
+ LogicalResult matchAndRewrite(InsertOp op,
+ PatternRewriter &rewriter) const override {
+
+ VectorType destTy = op.getDestVectorType();
+ if (destTy.isScalable())
+ return failure();
+ // Check if the result is used as the dest operand of another vector.insert
+ // Only care about the last op in a chain of insertions.
+ for (Operation *user : op.getResult().getUsers())
+ if (auto insertOp = dyn_cast<InsertOp>(user))
+ if (insertOp.getDest() == op.getResult())
+ return failure();
+
+ InsertOp firstInsertOp;
+ InsertOp previousInsertOp = op;
+ SmallVector<InsertOp> chainInsertOps;
+ SmallVector<Attribute> srcAttrs;
+ while (previousInsertOp) {
+ // Dynamic position is not supported.
+ if (previousInsertOp.hasDynamicPosition())
+ return failure();
+
+ // The inserted content must be constant.
+ chainInsertOps.push_back(previousInsertOp);
+ srcAttrs.push_back(Attribute());
+ matchPattern(previousInsertOp.getValueToStore(),
+ m_Constant(&srcAttrs.back()));
+ if (!srcAttrs.back())
+ return failure();
+
+ // An insertion at poison index makes the entire chain poisoned.
+ if (is_contained(previousInsertOp.getStaticPosition(),
+ InsertOp::kPoisonIndex))
+ return failure();
+
+ firstInsertOp = previousInsertOp;
+ previousInsertOp = previousInsertOp.getDest().getDefiningOp<InsertOp>();
+ }
+
+ if (!firstInsertOp.getDest().getDefiningOp<ub::PoisonOp>())
+ return failure();
+
+ // Need to make sure all elements are initialized.
+ int64_t vectorSize = destTy.getNumElements();
+ int64_t initializedCount = 0;
+ SmallVector<bool> initialized(vectorSize, false);
+ SmallVector<Attribute> initValues(vectorSize);
+
+ for (auto [insertOp, srcAttr] : llvm::zip(chainInsertOps, srcAttrs)) {
+ // Calculate the linearized position for inserting elements, as well as
+ // convert the source attribute to the proper type.
+ SmallVector<Attribute> valueToInsert;
+ int64_t insertBeginPosition = calculateInsertPositionAndExtractValues(
+ destTy, insertOp.getStaticPosition(), srcAttr, valueToInsert);
+ for (auto index :
+ llvm::seq<int64_t>(insertBeginPosition,
+ insertBeginPosition + valueToInsert.size())) {
+ if (initialized[index])
+ continue;
+
+ initialized[index] = true;
+ ++initializedCount;
+ initValues[index] = valueToInsert[index - insertBeginPosition];
+ }
+ // If all elements in the vector have been initialized, we can stop
+ // processing the remaining insert operations in the chain.
+ if (initializedCount == vectorSize)
+ break;
+ }
+
+ // some positions are not initialized.
+ if (initializedCount != vectorSize)
+ return failure();
+
+ auto newAttr = DenseElementsAttr::get(destTy, initValues);
+ rewriter.replaceOpWithNewOp<arith::ConstantOp>(op, destTy, newAttr);
+ return success();
+ }
+};
+
} // namespace
static Attribute
@@ -3217,35 +3356,11 @@ foldDenseElementsAttrDestInsertOp(InsertOp insertOp, Attribute srcAttr,
!insertOp->hasOneUse())
return {};
- // Calculate the linearized position of the continuous chunk of elements to
- // insert.
- llvm::SmallVector<int64_t> completePositions(destTy.getRank(), 0);
- copy(insertOp.getStaticPosition(), completePositions.begin());
- int64_t insertBeginPosition =
- linearize(completePositions, computeStrides(destTy.getShape()));
-
+ // Calculate the linearized position for inserting elements, as well as
+ // convert the source attribute to the proper type.
SmallVector<Attribute> insertedValues;
- Type destEltType = destTy.getElementType();
-
- /// Converts the expected type to an IntegerAttr if there's
- /// a mismatch.
- auto convertIntegerAttr = [](Attribute attr, Type expectedType) -> Attribute {
- if (auto intAttr = mlir::dyn_cast<IntegerAttr>(attr)) {
- if (intAttr.getType() != expectedType)
- return IntegerAttr::get(expectedType, intAttr.getInt());
- }
- return attr;
- };
-
- // The `convertIntegerAttr` method specifically handles the case
- // for `llvm.mlir.constant` which can hold an attribute with a
- // different type than the return type.
- if (auto denseSource = llvm::dyn_cast<DenseElementsAttr>(srcAttr)) {
- for (auto value : denseSource.getValues<Attribute>())
- insertedValues.push_back(convertIntegerAttr(value, destEltType));
- } else {
- insertedValues.push_back(convertIntegerAttr(srcAttr, destEltType));
- }
+ int64_t insertBeginPosition = calculateInsertPositionAndExtractValues(
+ destTy, insertOp.getStaticPosition(), srcAttr, insertedValues);
auto allValues = llvm::to_vector(denseDst.getValues<Attribute>());
copy(insertedValues, allValues.begin() + insertBeginPosition);
@@ -3256,7 +3371,8 @@ foldDenseElementsAttrDestInsertOp(InsertOp insertOp, Attribute srcAttr,
void InsertOp::getCanonicalizationPatterns(RewritePatternSet &results,
MLIRContext *context) {
- results.add<InsertToBroadcast, BroadcastFolder, InsertSplatToSplat>(context);
+ results.add<InsertToBroadcast, BroadcastFolder, InsertSplatToSplat,
+ InsertConstantToPoison>(context);
}
OpFoldResult vector::InsertOp::fold(FoldAdaptor adaptor) {
diff --git a/mlir/test/Dialect/Vector/canonicalize.mlir b/mlir/test/Dialect/Vector/canonicalize.mlir
index a06a9f67d54dc..36f3d7196bb93 100644
--- a/mlir/test/Dialect/Vector/canonicalize.mlir
+++ b/mlir/test/Dialect/Vector/canonicalize.mlir
@@ -2320,6 +2320,38 @@ func.func @insert_2d_constant() -> (vector<2x3xi32>, vector<2x3xi32>, vector<2x3
// -----
+// CHECK-LABEL: func.func @fully_insert_scalar_constant_to_poison_vector
+// CHECK: %[[VAL0:.+]] = arith.constant dense<[10, 20]> : vector<2xi64>
+// CHECK-NEXT: return %[[VAL0]]
+func.func @fully_insert_scalar_constant_to_poison_vector() -> vector<2xi64> {
+ %poison = ub.poison : vector<2xi64>
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %e0 = arith.constant 10 : i64
+ %e1 = arith.constant 20 : i64
+ %v1 = vector.insert %e0, %poison[%c0] : i64 into vector<2xi64>
+ %v2 = vector.insert %e1, %v1[%c1] : i64 into vector<2xi64>
+ return %v2 : vector<2xi64>
+}
+
+// -----
+
+// CHECK-LABEL: func.func @fully_insert_vector_constant_to_poison_vector
+// CHECK: %[[VAL0:.+]] = arith.constant dense<{{\[\[1, 2, 3\], \[4, 5, 6\]\]}}> : vector<2x3xi64>
+// CHECK-NEXT: return %[[VAL0]]
+func.func @fully_insert_vector_constant_to_poison_vector() -> vector<2x3xi64> {
+ %poison = ub.poison : vector<2x3xi64>
+ %cv0 = arith.constant dense<[1, 2, 3]> : vector<3xi64>
+ %cv1 = arith.constant dense<[4, 5, 6]> : vector<3xi64>
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %v1 = vector.insert %cv0, %poison[%c0] : vector<3xi64> into vector<2x3xi64>
+ %v2 = vector.insert %cv1, %v1[%c1] : vector<3xi64> into vector<2x3xi64>
+ return %v2 : vector<2x3xi64>
+}
+
+// -----
+
// CHECK-LABEL: func.func @insert_2d_splat_constant
// CHECK-DAG: %[[ACST:.*]] = arith.constant dense<0> : vector<2x3xi32>
// CHECK-DAG: %[[BCST:.*]] = arith.constant dense<{{\[\[99, 0, 0\], \[0, 0, 0\]\]}}> : vector<2x3xi32>
>From bba3d6c97c5d23862a75ea60d40cfba467c5932e Mon Sep 17 00:00:00 2001
From: Yang Bai <yangb at nvidia.com>
Date: Wed, 25 Jun 2025 02:08:19 -0700
Subject: [PATCH 2/7] refine comments & add hasOneUse check
---
mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 53 +++++++++++++-----------
1 file changed, 29 insertions(+), 24 deletions(-)
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index 253d148072dc0..e744b877f64bf 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -3153,8 +3153,8 @@ LogicalResult InsertOp::verify() {
// from the source attribute. Returns the starting position in the destination
// vector where elements should be inserted.
static int64_t calculateInsertPositionAndExtractValues(
- VectorType destTy, const ArrayRef<int64_t> &positions, Attribute srcAttr,
- SmallVector<Attribute> &valueToInsert) {
+ VectorType destTy, ArrayRef<int64_t> positions, Attribute srcAttr,
+ SmallVectorImpl<Attribute> &valueToInsert) {
llvm::SmallVector<int64_t> completePositions(destTy.getRank(), 0);
copy(positions, completePositions.begin());
int64_t insertBeginPosition =
@@ -3227,26 +3227,25 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
}
};
-// Pattern to optimize a chain of constant insertions into a poison vector.
-//
-// This pattern identifies chains of vector.insert operations that:
-// 1. Start from an ub.poison operation.
-// 2. Insert only constant values at static positions.
-// 3. Completely initialize all elements in the resulting vector.
-//
-// When these conditions are met, the entire chain can be replaced with a
-// single arith.constant operation containing a dense elements attribute.
-//
-// Example transformation:
-// %poison = ub.poison : vector<2xi32>
-// %0 = vector.insert %c1, %poison[0] : i32 into vector<2xi32>
-// %1 = vector.insert %c2, %0[1] : i32 into vector<2xi32>
-// ->
-// %result = arith.constant dense<[1, 2]> : vector<2xi32>
-
-// TODO: Support the case where only some elements of the poison vector are set.
-// Currently, MLIR doesn't support partial poison vectors.
-
+/// Pattern to optimize a chain of constant insertions into a poison vector.
+///
+/// This pattern identifies chains of vector.insert operations that:
+/// 1. Start from an ub.poison operation.
+/// 2. Insert only constant values at static positions.
+/// 3. Completely initialize all elements in the resulting vector.
+/// 4. All intermediate insert operations have only one use.
+///
+/// When these conditions are met, the entire chain can be replaced with a
+/// single arith.constant operation containing a dense elements attribute.
+///
+/// Example transformation:
+/// %poison = ub.poison : vector<2xi32>
+/// %0 = vector.insert %c1, %poison[0] : i32 into vector<2xi32>
+/// %1 = vector.insert %c2, %0[1] : i32 into vector<2xi32>
+/// ->
+/// %result = arith.constant dense<[1, 2]> : vector<2xi32>
+/// TODO: Support the case where only some elements of the poison vector are
+/// set. Currently, MLIR doesn't support partial poison vectors.
class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
public:
using OpRewritePattern::OpRewritePattern;
@@ -3287,12 +3286,18 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
firstInsertOp = previousInsertOp;
previousInsertOp = previousInsertOp.getDest().getDefiningOp<InsertOp>();
+
+ // Check that intermediate inserts have only one use to avoid an explosion
+ // of constants.
+ if (previousInsertOp && !previousInsertOp->hasOneUse())
+ return failure();
}
if (!firstInsertOp.getDest().getDefiningOp<ub::PoisonOp>())
return failure();
- // Need to make sure all elements are initialized.
+ // Currently, MLIR doesn't support partial poison vectors, so we can only
+ // optimize when the entire vector is completely initialized.
int64_t vectorSize = destTy.getNumElements();
int64_t initializedCount = 0;
SmallVector<bool> initialized(vectorSize, false);
@@ -3320,7 +3325,7 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
break;
}
- // some positions are not initialized.
+ // Some positions are not initialized.
if (initializedCount != vectorSize)
return failure();
>From 9701de857422398c531290262299212988b2166a Mon Sep 17 00:00:00 2001
From: Yang Bai <yangb at nvidia.com>
Date: Thu, 26 Jun 2025 08:10:39 -0700
Subject: [PATCH 3/7] use from_elements to replace arith.constant
---
mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 126 +++++++++++++----------
1 file changed, 69 insertions(+), 57 deletions(-)
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index e744b877f64bf..cc0812f925036 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -3149,39 +3149,16 @@ LogicalResult InsertOp::verify() {
return success();
}
-// Calculate the linearized position for inserting elements and extract values
-// from the source attribute. Returns the starting position in the destination
-// vector where elements should be inserted.
-static int64_t calculateInsertPositionAndExtractValues(
- VectorType destTy, ArrayRef<int64_t> positions, Attribute srcAttr,
- SmallVectorImpl<Attribute> &valueToInsert) {
+// Calculate the linearized position of the continuous chunk of elements to
+// insert, based on the shape of the value to insert and the positions to insert
+// at.
+static int64_t calculateInsertPosition(VectorType destTy,
+ ArrayRef<int64_t> positions) {
llvm::SmallVector<int64_t> completePositions(destTy.getRank(), 0);
copy(positions, completePositions.begin());
int64_t insertBeginPosition =
linearize(completePositions, computeStrides(destTy.getShape()));
- Type destEltType = destTy.getElementType();
-
- /// Converts the expected type to an IntegerAttr if there's
- /// a mismatch.
- auto convertIntegerAttr = [](Attribute attr, Type expectedType) -> Attribute {
- if (auto intAttr = mlir::dyn_cast<IntegerAttr>(attr)) {
- if (intAttr.getType() != expectedType)
- return IntegerAttr::get(expectedType, intAttr.getInt());
- }
- return attr;
- };
-
- // The `convertIntegerAttr` method specifically handles the case
- // for `llvm.mlir.constant` which can hold an attribute with a
- // different type than the return type.
- if (auto denseSource = llvm::dyn_cast<DenseElementsAttr>(srcAttr)) {
- for (auto value : denseSource.getValues<Attribute>())
- valueToInsert.push_back(convertIntegerAttr(value, destEltType));
- } else {
- valueToInsert.push_back(convertIntegerAttr(srcAttr, destEltType));
- }
-
return insertBeginPosition;
}
@@ -3231,7 +3208,7 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
///
/// This pattern identifies chains of vector.insert operations that:
/// 1. Start from an ub.poison operation.
-/// 2. Insert only constant values at static positions.
+/// 2. Only insert values at static positions.
/// 3. Completely initialize all elements in the resulting vector.
/// 4. All intermediate insert operations have only one use.
///
@@ -3265,7 +3242,6 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
InsertOp firstInsertOp;
InsertOp previousInsertOp = op;
SmallVector<InsertOp> chainInsertOps;
- SmallVector<Attribute> srcAttrs;
while (previousInsertOp) {
// Dynamic position is not supported.
if (previousInsertOp.hasDynamicPosition())
@@ -3273,22 +3249,12 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
// The inserted content must be constant.
chainInsertOps.push_back(previousInsertOp);
- srcAttrs.push_back(Attribute());
- matchPattern(previousInsertOp.getValueToStore(),
- m_Constant(&srcAttrs.back()));
- if (!srcAttrs.back())
- return failure();
-
- // An insertion at poison index makes the entire chain poisoned.
- if (is_contained(previousInsertOp.getStaticPosition(),
- InsertOp::kPoisonIndex))
- return failure();
firstInsertOp = previousInsertOp;
previousInsertOp = previousInsertOp.getDest().getDefiningOp<InsertOp>();
// Check that intermediate inserts have only one use to avoid an explosion
- // of constants.
+ // of vectors.
if (previousInsertOp && !previousInsertOp->hasOneUse())
return failure();
}
@@ -3301,23 +3267,50 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
int64_t vectorSize = destTy.getNumElements();
int64_t initializedCount = 0;
SmallVector<bool> initialized(vectorSize, false);
- SmallVector<Attribute> initValues(vectorSize);
-
- for (auto [insertOp, srcAttr] : llvm::zip(chainInsertOps, srcAttrs)) {
- // Calculate the linearized position for inserting elements, as well as
- // convert the source attribute to the proper type.
- SmallVector<Attribute> valueToInsert;
- int64_t insertBeginPosition = calculateInsertPositionAndExtractValues(
- destTy, insertOp.getStaticPosition(), srcAttr, valueToInsert);
+ SmallVector<Value> elements(vectorSize);
+
+ for (auto insertOp : chainInsertOps) {
+ // The insert op folder will fold an insert at poison index into a
+ // ub.poison, which truncates the insert chain's backward traversal.
+ if (is_contained(previousInsertOp.getStaticPosition(),
+ InsertOp::kPoisonIndex))
+ return failure();
+
+ // Calculate the linearized position for inserting elements.
+ int64_t insertBeginPosition =
+ calculateInsertPosition(destTy, insertOp.getStaticPosition());
+
+ // The valueToStore operand may be a vector or a scalar. Need to handle
+ // both cases.
+ SmallVector<Value> elementsToInsert;
+ int64_t elementsToInsertSize = 1;
+ if (auto srcVectorType =
+ llvm::dyn_cast<VectorType>(insertOp.getValueToStoreType())) {
+
+ elementsToInsertSize = srcVectorType.getNumElements();
+ elementsToInsert.reserve(elementsToInsertSize);
+ SmallVector<int64_t> strides = computeStrides(srcVectorType.getShape());
+ // Get all elements from the vector in row-major order.
+ for (int64_t linearIdx = 0; linearIdx < elementsToInsertSize;
+ linearIdx++) {
+ SmallVector<int64_t> position = delinearize(linearIdx, strides);
+ Value extractedElement = rewriter.create<vector::ExtractOp>(
+ insertOp.getLoc(), insertOp.getValueToStore(), position);
+ elementsToInsert.push_back(extractedElement);
+ }
+ } else {
+ elementsToInsert.push_back(insertOp.getValueToStore());
+ }
+
for (auto index :
llvm::seq<int64_t>(insertBeginPosition,
- insertBeginPosition + valueToInsert.size())) {
+ insertBeginPosition + elementsToInsertSize)) {
if (initialized[index])
continue;
initialized[index] = true;
++initializedCount;
- initValues[index] = valueToInsert[index - insertBeginPosition];
+ elements[index] = elementsToInsert[index - insertBeginPosition];
}
// If all elements in the vector have been initialized, we can stop
// processing the remaining insert operations in the chain.
@@ -3329,8 +3322,7 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
if (initializedCount != vectorSize)
return failure();
- auto newAttr = DenseElementsAttr::get(destTy, initValues);
- rewriter.replaceOpWithNewOp<arith::ConstantOp>(op, destTy, newAttr);
+ rewriter.replaceOpWithNewOp<vector::FromElementsOp>(op, destTy, elements);
return success();
}
};
@@ -3361,11 +3353,31 @@ foldDenseElementsAttrDestInsertOp(InsertOp insertOp, Attribute srcAttr,
!insertOp->hasOneUse())
return {};
- // Calculate the linearized position for inserting elements, as well as
- // convert the source attribute to the proper type.
+ // Calculate the linearized position for inserting elements.
+ int64_t insertBeginPosition =
+ calculateInsertPosition(destTy, insertOp.getStaticPosition());
SmallVector<Attribute> insertedValues;
- int64_t insertBeginPosition = calculateInsertPositionAndExtractValues(
- destTy, insertOp.getStaticPosition(), srcAttr, insertedValues);
+ Type destEltType = destTy.getElementType();
+
+ /// Converts the expected type to an IntegerAttr if there's
+ /// a mismatch.
+ auto convertIntegerAttr = [](Attribute attr, Type expectedType) -> Attribute {
+ if (auto intAttr = mlir::dyn_cast<IntegerAttr>(attr)) {
+ if (intAttr.getType() != expectedType)
+ return IntegerAttr::get(expectedType, intAttr.getInt());
+ }
+ return attr;
+ };
+
+ // The `convertIntegerAttr` method specifically handles the case
+ // for `llvm.mlir.constant` which can hold an attribute with a
+ // different type than the return type.
+ if (auto denseSource = llvm::dyn_cast<DenseElementsAttr>(srcAttr)) {
+ for (auto value : denseSource.getValues<Attribute>())
+ insertedValues.push_back(convertIntegerAttr(value, destEltType));
+ } else {
+ insertedValues.push_back(convertIntegerAttr(srcAttr, destEltType));
+ }
auto allValues = llvm::to_vector(denseDst.getValues<Attribute>());
copy(insertedValues, allValues.begin() + insertBeginPosition);
>From 27bb0053f343ae4f9fd53ee6120bf126a04da9d3 Mon Sep 17 00:00:00 2001
From: Yang Bai <yangb at nvidia.com>
Date: Thu, 26 Jun 2025 08:43:53 -0700
Subject: [PATCH 4/7] update doc
---
mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index cc0812f925036..54fe1752149c1 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -3220,7 +3220,7 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
/// %0 = vector.insert %c1, %poison[0] : i32 into vector<2xi32>
/// %1 = vector.insert %c2, %0[1] : i32 into vector<2xi32>
/// ->
-/// %result = arith.constant dense<[1, 2]> : vector<2xi32>
+/// %result = vector.from_elements %c1, %c2 : vector<2xi32>
/// TODO: Support the case where only some elements of the poison vector are
/// set. Currently, MLIR doesn't support partial poison vectors.
class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
>From b3e98508f8954aab9ddd5f1e3ee594af2eb8cdc7 Mon Sep 17 00:00:00 2001
From: Yang Bai <yangb at nvidia.com>
Date: Thu, 26 Jun 2025 09:51:15 -0700
Subject: [PATCH 5/7] fix typo and update test
---
mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 12 +++++-------
.../Conversion/ConvertToSPIRV/vector-unroll.mlir | 12 ++++--------
2 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index 54fe1752149c1..912f690df358e 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -3204,7 +3204,7 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
}
};
-/// Pattern to optimize a chain of constant insertions into a poison vector.
+/// Pattern to optimize a chain of insertions into a poison vector.
///
/// This pattern identifies chains of vector.insert operations that:
/// 1. Start from an ub.poison operation.
@@ -3213,7 +3213,7 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
/// 4. All intermediate insert operations have only one use.
///
/// When these conditions are met, the entire chain can be replaced with a
-/// single arith.constant operation containing a dense elements attribute.
+/// single vector.from_elements operation.
///
/// Example transformation:
/// %poison = ub.poison : vector<2xi32>
@@ -3223,7 +3223,7 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
/// %result = vector.from_elements %c1, %c2 : vector<2xi32>
/// TODO: Support the case where only some elements of the poison vector are
/// set. Currently, MLIR doesn't support partial poison vectors.
-class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
+class InsertToPoison final : public OpRewritePattern<InsertOp> {
public:
using OpRewritePattern::OpRewritePattern;
LogicalResult matchAndRewrite(InsertOp op,
@@ -3247,7 +3247,6 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
if (previousInsertOp.hasDynamicPosition())
return failure();
- // The inserted content must be constant.
chainInsertOps.push_back(previousInsertOp);
firstInsertOp = previousInsertOp;
@@ -3272,8 +3271,7 @@ class InsertConstantToPoison final : public OpRewritePattern<InsertOp> {
for (auto insertOp : chainInsertOps) {
// The insert op folder will fold an insert at poison index into a
// ub.poison, which truncates the insert chain's backward traversal.
- if (is_contained(previousInsertOp.getStaticPosition(),
- InsertOp::kPoisonIndex))
+ if (is_contained(insertOp.getStaticPosition(), InsertOp::kPoisonIndex))
return failure();
// Calculate the linearized position for inserting elements.
@@ -3389,7 +3387,7 @@ foldDenseElementsAttrDestInsertOp(InsertOp insertOp, Attribute srcAttr,
void InsertOp::getCanonicalizationPatterns(RewritePatternSet &results,
MLIRContext *context) {
results.add<InsertToBroadcast, BroadcastFolder, InsertSplatToSplat,
- InsertConstantToPoison>(context);
+ InsertToPoison>(context);
}
OpFoldResult vector::InsertOp::fold(FoldAdaptor adaptor) {
diff --git a/mlir/test/Conversion/ConvertToSPIRV/vector-unroll.mlir b/mlir/test/Conversion/ConvertToSPIRV/vector-unroll.mlir
index d68ba44ee8840..c85f4334ff2e5 100644
--- a/mlir/test/Conversion/ConvertToSPIRV/vector-unroll.mlir
+++ b/mlir/test/Conversion/ConvertToSPIRV/vector-unroll.mlir
@@ -83,20 +83,16 @@ func.func @vaddi_reduction(%arg0 : vector<8xi32>, %arg1 : vector<8xi32>) -> (i32
// CHECK-LABEL: @transpose
// CHECK-SAME: (%[[ARG0:.+]]: vector<3xi32>, %[[ARG1:.+]]: vector<3xi32>)
func.func @transpose(%arg0 : vector<2x3xi32>) -> (vector<3x2xi32>) {
- // CHECK: %[[UB:.*]] = ub.poison : vector<2xi32>
// CHECK: %[[EXTRACT0:.*]] = vector.extract %[[ARG0]][0] : i32 from vector<3xi32>
- // CHECK: %[[INSERT0:.*]]= vector.insert %[[EXTRACT0]], %[[UB]] [0] : i32 into vector<2xi32>
// CHECK: %[[EXTRACT1:.*]] = vector.extract %[[ARG1]][0] : i32 from vector<3xi32>
- // CHECK: %[[INSERT1:.*]] = vector.insert %[[EXTRACT1]], %[[INSERT0]][1] : i32 into vector<2xi32>
+ // CHECK: %[[FROM_ELEMENTS0:.*]] = vector.from_elements %[[EXTRACT0]], %[[EXTRACT1]] : vector<2xi32>
// CHECK: %[[EXTRACT2:.*]] = vector.extract %[[ARG0]][1] : i32 from vector<3xi32>
- // CHECK: %[[INSERT2:.*]] = vector.insert %[[EXTRACT2]], %[[UB]] [0] : i32 into vector<2xi32>
// CHECK: %[[EXTRACT3:.*]] = vector.extract %[[ARG1]][1] : i32 from vector<3xi32>
- // CHECK: %[[INSERT3:.*]] = vector.insert %[[EXTRACT3]], %[[INSERT2]] [1] : i32 into vector<2xi32>
+ // CHECK: %[[FROM_ELEMENTS1:.*]] = vector.from_elements %[[EXTRACT2]], %[[EXTRACT3]] : vector<2xi32>
// CHECK: %[[EXTRACT4:.*]] = vector.extract %[[ARG0]][2] : i32 from vector<3xi32>
- // CHECK: %[[INSERT4:.*]] = vector.insert %[[EXTRACT4]], %[[UB]] [0] : i32 into vector<2xi32>
// CHECK: %[[EXTRACT5:.*]] = vector.extract %[[ARG1]][2] : i32 from vector<3xi32>
- // CHECK: %[[INSERT5:.*]] = vector.insert %[[EXTRACT5]], %[[INSERT4]] [1] : i32 into vector<2xi32>
- // CHECK: return %[[INSERT1]], %[[INSERT3]], %[[INSERT5]] : vector<2xi32>, vector<2xi32>, vector<2xi32>
+ // CHECK: %[[FROM_ELEMENTS2:.*]] = vector.from_elements %[[EXTRACT4]], %[[EXTRACT5]] : vector<2xi32>
+ // CHECK: return %[[FROM_ELEMENTS0]], %[[FROM_ELEMENTS1]], %[[FROM_ELEMENTS2]] : vector<2xi32>, vector<2xi32>, vector<2xi32>
%0 = vector.transpose %arg0, [1, 0] : vector<2x3xi32> to vector<3x2xi32>
return %0 : vector<3x2xi32>
}
>From bb8c827a740912a53e9a36b98f61ad4b32530bc1 Mon Sep 17 00:00:00 2001
From: Yang Bai <yangb at nvidia.com>
Date: Fri, 27 Jun 2025 03:19:49 -0700
Subject: [PATCH 6/7] remove ub poison check and fix bugs
---
mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 106 +++++++++++------------
1 file changed, 52 insertions(+), 54 deletions(-)
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index 912f690df358e..1c2f08fcc55e6 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -3155,11 +3155,10 @@ LogicalResult InsertOp::verify() {
static int64_t calculateInsertPosition(VectorType destTy,
ArrayRef<int64_t> positions) {
llvm::SmallVector<int64_t> completePositions(destTy.getRank(), 0);
+ assert(positions.size() <= completePositions.size() &&
+ "positions size must be less than or equal to destTy rank");
copy(positions, completePositions.begin());
- int64_t insertBeginPosition =
- linearize(completePositions, computeStrides(destTy.getShape()));
-
- return insertBeginPosition;
+ return linearize(completePositions, computeStrides(destTy.getShape()));
}
namespace {
@@ -3204,13 +3203,12 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
}
};
-/// Pattern to optimize a chain of insertions into a poison vector.
+/// Pattern to optimize a chain of insertions.
///
/// This pattern identifies chains of vector.insert operations that:
-/// 1. Start from an ub.poison operation.
-/// 2. Only insert values at static positions.
-/// 3. Completely initialize all elements in the resulting vector.
-/// 4. All intermediate insert operations have only one use.
+/// 1. Only insert values at static positions.
+/// 2. Completely initialize all elements in the resulting vector.
+/// 3. All intermediate insert operations have only one use.
///
/// When these conditions are met, the entire chain can be replaced with a
/// single vector.from_elements operation.
@@ -3221,9 +3219,7 @@ class InsertSplatToSplat final : public OpRewritePattern<InsertOp> {
/// %1 = vector.insert %c2, %0[1] : i32 into vector<2xi32>
/// ->
/// %result = vector.from_elements %c1, %c2 : vector<2xi32>
-/// TODO: Support the case where only some elements of the poison vector are
-/// set. Currently, MLIR doesn't support partial poison vectors.
-class InsertToPoison final : public OpRewritePattern<InsertOp> {
+class InsertChainFullyInitialized final : public OpRewritePattern<InsertOp> {
public:
using OpRewritePattern::OpRewritePattern;
LogicalResult matchAndRewrite(InsertOp op,
@@ -3239,34 +3235,27 @@ class InsertToPoison final : public OpRewritePattern<InsertOp> {
if (insertOp.getDest() == op.getResult())
return failure();
- InsertOp firstInsertOp;
- InsertOp previousInsertOp = op;
+ InsertOp currentOp = op;
SmallVector<InsertOp> chainInsertOps;
- while (previousInsertOp) {
+ while (currentOp) {
// Dynamic position is not supported.
- if (previousInsertOp.hasDynamicPosition())
+ if (currentOp.hasDynamicPosition())
return failure();
- chainInsertOps.push_back(previousInsertOp);
-
- firstInsertOp = previousInsertOp;
- previousInsertOp = previousInsertOp.getDest().getDefiningOp<InsertOp>();
-
+ chainInsertOps.push_back(currentOp);
+ currentOp = currentOp.getDest().getDefiningOp<InsertOp>();
// Check that intermediate inserts have only one use to avoid an explosion
// of vectors.
- if (previousInsertOp && !previousInsertOp->hasOneUse())
+ if (currentOp && !currentOp->hasOneUse())
return failure();
}
- if (!firstInsertOp.getDest().getDefiningOp<ub::PoisonOp>())
- return failure();
-
- // Currently, MLIR doesn't support partial poison vectors, so we can only
- // optimize when the entire vector is completely initialized.
int64_t vectorSize = destTy.getNumElements();
int64_t initializedCount = 0;
SmallVector<bool> initialized(vectorSize, false);
- SmallVector<Value> elements(vectorSize);
+ SmallVector<int64_t> pendingInsertPos;
+ SmallVector<int64_t> pendingInsertSize;
+ SmallVector<Value> pendingInsertValues;
for (auto insertOp : chainInsertOps) {
// The insert op folder will fold an insert at poison index into a
@@ -3280,46 +3269,55 @@ class InsertToPoison final : public OpRewritePattern<InsertOp> {
// The valueToStore operand may be a vector or a scalar. Need to handle
// both cases.
- SmallVector<Value> elementsToInsert;
- int64_t elementsToInsertSize = 1;
+ int64_t insertSize = 1;
if (auto srcVectorType =
- llvm::dyn_cast<VectorType>(insertOp.getValueToStoreType())) {
+ llvm::dyn_cast<VectorType>(insertOp.getValueToStoreType()))
+ insertSize = srcVectorType.getNumElements();
- elementsToInsertSize = srcVectorType.getNumElements();
- elementsToInsert.reserve(elementsToInsertSize);
- SmallVector<int64_t> strides = computeStrides(srcVectorType.getShape());
- // Get all elements from the vector in row-major order.
- for (int64_t linearIdx = 0; linearIdx < elementsToInsertSize;
- linearIdx++) {
- SmallVector<int64_t> position = delinearize(linearIdx, strides);
- Value extractedElement = rewriter.create<vector::ExtractOp>(
- insertOp.getLoc(), insertOp.getValueToStore(), position);
- elementsToInsert.push_back(extractedElement);
- }
- } else {
- elementsToInsert.push_back(insertOp.getValueToStore());
- }
+ assert(insertBeginPosition + insertSize <= vectorSize &&
+ "insert would overflow the vector");
- for (auto index :
- llvm::seq<int64_t>(insertBeginPosition,
- insertBeginPosition + elementsToInsertSize)) {
+ for (auto index : llvm::seq<int64_t>(insertBeginPosition,
+ insertBeginPosition + insertSize)) {
if (initialized[index])
continue;
-
initialized[index] = true;
++initializedCount;
- elements[index] = elementsToInsert[index - insertBeginPosition];
}
- // If all elements in the vector have been initialized, we can stop
- // processing the remaining insert operations in the chain.
+
+ // Defer the creation of ops before we can make sure the pattern can
+ // succeed.
+ pendingInsertPos.push_back(insertBeginPosition);
+ pendingInsertSize.push_back(insertSize);
+ pendingInsertValues.push_back(insertOp.getValueToStore());
+
if (initializedCount == vectorSize)
break;
}
- // Some positions are not initialized.
+ // Final check: all positions must be initialized
if (initializedCount != vectorSize)
return failure();
+ SmallVector<Value> elements(vectorSize);
+ for (auto [insertBeginPosition, insertSize, valueToStore] :
+ llvm::reverse(llvm::zip(pendingInsertPos, pendingInsertSize,
+ pendingInsertValues))) {
+ if (auto srcVectorType =
+ llvm::dyn_cast<VectorType>(valueToStore.getType())) {
+ SmallVector<int64_t> strides = computeStrides(srcVectorType.getShape());
+ // Get all elements from the vector in row-major order.
+ for (int64_t linearIdx = 0; linearIdx < insertSize; linearIdx++) {
+ SmallVector<int64_t> position = delinearize(linearIdx, strides);
+ Value extractedElement = rewriter.create<vector::ExtractOp>(
+ op.getLoc(), valueToStore, position);
+ elements[insertBeginPosition + linearIdx] = extractedElement;
+ }
+ } else {
+ elements[insertBeginPosition] = valueToStore;
+ }
+ }
+
rewriter.replaceOpWithNewOp<vector::FromElementsOp>(op, destTy, elements);
return success();
}
@@ -3387,7 +3385,7 @@ foldDenseElementsAttrDestInsertOp(InsertOp insertOp, Attribute srcAttr,
void InsertOp::getCanonicalizationPatterns(RewritePatternSet &results,
MLIRContext *context) {
results.add<InsertToBroadcast, BroadcastFolder, InsertSplatToSplat,
- InsertToPoison>(context);
+ InsertChainFullyInitialized>(context);
}
OpFoldResult vector::InsertOp::fold(FoldAdaptor adaptor) {
>From ce818c15657298bf2c7f35d8bbef2b0ceb2b668f Mon Sep 17 00:00:00 2001
From: Yang Bai <yangb at nvidia.com>
Date: Mon, 30 Jun 2025 08:32:44 -0700
Subject: [PATCH 7/7] update test
---
.../MathToLibm/convert-to-libm.mlir | 228 ++++++------------
mlir/test/Dialect/Vector/canonicalize.mlir | 62 ++---
.../Vector/vector-gather-lowering.mlir | 2 +-
.../Vector/vector-warp-distribute.mlir | 2 +-
4 files changed, 104 insertions(+), 190 deletions(-)
diff --git a/mlir/test/Conversion/MathToLibm/convert-to-libm.mlir b/mlir/test/Conversion/MathToLibm/convert-to-libm.mlir
index 08354dbf280c1..26b54566cb2cd 100644
--- a/mlir/test/Conversion/MathToLibm/convert-to-libm.mlir
+++ b/mlir/test/Conversion/MathToLibm/convert-to-libm.mlir
@@ -79,21 +79,17 @@ func.func @absf_caller(%float: f32, %double: f64) -> (f32, f64) {
// CHECK-LABEL: func @absf_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @fabsf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @fabsf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @fabs(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @fabs(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @absf_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.absf %float : vector<2xf32>
@@ -116,21 +112,17 @@ func.func @acos_caller(%float: f32, %double: f64) -> (f32, f64) {
// CHECK-LABEL: func @acos_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @acosf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @acosf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @acos(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @acos(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @acos_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.acos %float : vector<2xf32>
@@ -153,21 +145,17 @@ func.func @acosh_caller(%float: f32, %double: f64) -> (f32, f64) {
// CHECK-LABEL: func @acosh_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @acoshf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @acoshf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @acosh(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @acosh(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @acosh_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.acosh %float : vector<2xf32>
@@ -190,21 +178,17 @@ func.func @asin_caller(%float: f32, %double: f64) -> (f32, f64) {
// CHECK-LABEL: func @asin_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @asinf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @asinf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @asin(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @asin(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @asin_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.asin %float : vector<2xf32>
@@ -227,21 +211,17 @@ func.func @asinh_caller(%float: f32, %double: f64) -> (f32, f64) {
// CHECK-LABEL: func @asinh_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @asinhf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @asinhf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @asinh(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @asinh(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @asinh_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.asinh %float : vector<2xf32>
@@ -274,21 +254,17 @@ func.func @atan_caller(%float: f32, %double: f64, %half: f16, %bfloat: bf16) ->
// CHECK-LABEL: func @atan_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @atanf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @atanf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @atan(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @atan(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @atan_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.atan %float : vector<2xf32>
@@ -321,21 +297,17 @@ func.func @atanh_caller(%float: f32, %double: f64, %half: f16, %bfloat: bf16) ->
// CHECK-LABEL: func @atanh_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @atanhf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @atanhf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @atanh(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @atanh(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @atanh_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.atanh %float : vector<2xf32>
@@ -419,23 +391,19 @@ func.func @erf_caller(%float: f32, %double: f64) -> (f32, f64) {
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
func.func @erf_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
- // CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
- // CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @erff(%[[IN0_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @erff(%[[IN1_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+ // CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
%float_result = math.erf %float : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @erf(%[[IN0_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @erf(%[[IN1_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
+ // CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
%double_result = math.erf %double : vector<2xf64>
- // CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+ // CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
return %float_result, %double_result : vector<2xf32>, vector<2xf64>
}
@@ -459,21 +427,17 @@ func.func @exp_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vec
// CHECK-LABEL: func @exp_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @expf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @expf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @exp(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @exp(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @exp2_caller
@@ -496,21 +460,17 @@ func.func @exp2_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (ve
// CHECK-LABEL: func @exp2_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @exp2f(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @exp2f(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @exp2(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @exp2(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @log_caller
@@ -533,21 +493,17 @@ func.func @log_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vec
// CHECK-LABEL: func @log_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @logf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @logf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @log(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @log(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @log2_caller
@@ -570,21 +526,17 @@ func.func @log2_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (ve
// CHECK-LABEL: func @log2_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @log2f(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @log2f(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @log2(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @log2(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @log10_caller
@@ -607,21 +559,17 @@ func.func @log10_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (v
// CHECK-LABEL: func @log10_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @log10f(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @log10f(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @log10(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @log10(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @expm1_caller
@@ -644,21 +592,17 @@ func.func @expm1_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (v
// CHECK-LABEL: func @expm1_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @expm1f(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @expm1f(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @expm1(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @expm1(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @expm1_multidim_vec_caller(%float: vector<2x2xf32>) -> (vector<2x2xf32>) {
@@ -667,20 +611,16 @@ func.func @expm1_multidim_vec_caller(%float: vector<2x2xf32>) -> (vector<2x2xf32
}
// CHECK-LABEL: func @expm1_multidim_vec_caller(
// CHECK-SAME: %[[VAL:.*]]: vector<2x2xf32>
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2x2xf32>
// CHECK: %[[IN0_0_F32:.*]] = vector.extract %[[VAL]][0, 0] : f32 from vector<2x2xf32>
// CHECK: %[[OUT0_0_F32:.*]] = call @expm1f(%[[IN0_0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_1:.*]] = vector.insert %[[OUT0_0_F32]], %[[CVF]] [0, 0] : f32 into vector<2x2xf32>
// CHECK: %[[IN0_1_F32:.*]] = vector.extract %[[VAL]][0, 1] : f32 from vector<2x2xf32>
// CHECK: %[[OUT0_1_F32:.*]] = call @expm1f(%[[IN0_1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_2:.*]] = vector.insert %[[OUT0_1_F32]], %[[VAL_1]] [0, 1] : f32 into vector<2x2xf32>
// CHECK: %[[IN1_0_F32:.*]] = vector.extract %[[VAL]][1, 0] : f32 from vector<2x2xf32>
// CHECK: %[[OUT1_0_F32:.*]] = call @expm1f(%[[IN1_0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_3:.*]] = vector.insert %[[OUT1_0_F32]], %[[VAL_2]] [1, 0] : f32 into vector<2x2xf32>
// CHECK: %[[IN1_1_F32:.*]] = vector.extract %[[VAL]][1, 1] : f32 from vector<2x2xf32>
// CHECK: %[[OUT1_1_F32:.*]] = call @expm1f(%[[IN1_1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_4:.*]] = vector.insert %[[OUT1_1_F32]], %[[VAL_3]] [1, 1] : f32 into vector<2x2xf32>
-// CHECK: return %[[VAL_4]] : vector<2x2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_0_F32]], %[[OUT0_1_F32]], %[[OUT1_0_F32]], %[[OUT1_1_F32]] : vector<2x2xf32>
+// CHECK: return %[[RES_F32]] : vector<2x2xf32>
// CHECK: }
// CHECK-LABEL: func @fma_caller(
@@ -704,29 +644,25 @@ func.func @fma_vec_caller(%float_a: vector<2xf32>, %float_b: vector<2xf32>, %flo
// CHECK-SAME: %[[VAL_0A:.*]]: vector<2xf32>, %[[VAL_0B:.*]]: vector<2xf32>, %[[VAL_0C:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1A:.*]]: vector<2xf64>, %[[VAL_1B:.*]]: vector<2xf64>, %[[VAL_1C:.*]]: vector<2xf64>
// CHECK-SAME: ) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32A:.*]] = vector.extract %[[VAL_0A]][0] : f32 from vector<2xf32>
// CHECK: %[[IN0_F32B:.*]] = vector.extract %[[VAL_0B]][0] : f32 from vector<2xf32>
// CHECK: %[[IN0_F32C:.*]] = vector.extract %[[VAL_0C]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @fmaf(%[[IN0_F32A]], %[[IN0_F32B]], %[[IN0_F32C]]) : (f32, f32, f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32A:.*]] = vector.extract %[[VAL_0A]][1] : f32 from vector<2xf32>
// CHECK: %[[IN1_F32B:.*]] = vector.extract %[[VAL_0B]][1] : f32 from vector<2xf32>
// CHECK: %[[IN1_F32C:.*]] = vector.extract %[[VAL_0C]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @fmaf(%[[IN1_F32A]], %[[IN1_F32B]], %[[IN1_F32C]]) : (f32, f32, f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64A:.*]] = vector.extract %[[VAL_1A]][0] : f64 from vector<2xf64>
// CHECK: %[[IN0_F64B:.*]] = vector.extract %[[VAL_1B]][0] : f64 from vector<2xf64>
// CHECK: %[[IN0_F64C:.*]] = vector.extract %[[VAL_1C]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @fma(%[[IN0_F64A]], %[[IN0_F64B]], %[[IN0_F64C]]) : (f64, f64, f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64A:.*]] = vector.extract %[[VAL_1A]][1] : f64 from vector<2xf64>
// CHECK: %[[IN1_F64B:.*]] = vector.extract %[[VAL_1B]][1] : f64 from vector<2xf64>
// CHECK: %[[IN1_F64C:.*]] = vector.extract %[[VAL_1C]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @fma(%[[IN1_F64A]], %[[IN1_F64B]], %[[IN1_F64C]]) : (f64, f64, f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @round_caller
@@ -814,23 +750,19 @@ func.func @sin_caller(%float: f32, %double: f64) -> (f32, f64) {
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
func.func @round_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
- // CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
- // CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @roundf(%[[IN0_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @roundf(%[[IN1_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+ // CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
%float_result = math.round %float : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @round(%[[IN0_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @round(%[[IN1_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
+ // CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
%double_result = math.round %double : vector<2xf64>
- // CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+ // CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
return %float_result, %double_result : vector<2xf32>, vector<2xf64>
}
@@ -838,23 +770,19 @@ func.func @round_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (v
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
func.func @roundeven_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
- // CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
- // CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @roundevenf(%[[IN0_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @roundevenf(%[[IN1_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+ // CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
%float_result = math.roundeven %float : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @roundeven(%[[IN0_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @roundeven(%[[IN1_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
+ // CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
%double_result = math.roundeven %double : vector<2xf64>
- // CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+ // CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
return %float_result, %double_result : vector<2xf32>, vector<2xf64>
}
@@ -862,23 +790,19 @@ func.func @roundeven_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
func.func @trunc_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
- // CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
- // CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @truncf(%[[IN0_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @truncf(%[[IN1_F32]]) : (f32) -> f32
- // CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+ // CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
%float_result = math.trunc %float : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @trunc(%[[IN0_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @trunc(%[[IN1_F64]]) : (f64) -> f64
- // CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
+ // CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
%double_result = math.trunc %double : vector<2xf64>
- // CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+ // CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
return %float_result, %double_result : vector<2xf32>, vector<2xf64>
}
@@ -907,21 +831,17 @@ func.func @tan_caller(%float: f32, %double: f64, %half: f16, %bfloat: bf16) -> (
// CHECK-LABEL: func @tan_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @tanf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @tanf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @tan(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @tan(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
func.func @tan_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
%float_result = math.tan %float : vector<2xf32>
@@ -985,21 +905,17 @@ func.func @sqrt_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (ve
// CHECK-LABEL: func @sqrt_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @sqrtf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @sqrtf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @sqrt(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @sqrt(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @rsqrt_caller
@@ -1022,21 +938,17 @@ func.func @rsqrt_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (v
// CHECK-LABEL: func @rsqrt_vec_caller(
// CHECK-SAME: %[[VAL_0:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @rsqrtf(%[[IN0_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @rsqrtf(%[[IN1_F32]]) : (f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @rsqrt(%[[IN0_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @rsqrt(%[[IN1_F64]]) : (f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
// CHECK-LABEL: func @powf_caller(
@@ -1060,23 +972,19 @@ func.func @powf_vec_caller(%float_a: vector<2xf32>, %float_b: vector<2xf32>, %do
// CHECK-SAME: %[[VAL_0A:.*]]: vector<2xf32>, %[[VAL_0B:.*]]: vector<2xf32>,
// CHECK-SAME: %[[VAL_1A:.*]]: vector<2xf64>, %[[VAL_1B:.*]]: vector<2xf64>
// CHECK-SAME: ) -> (vector<2xf32>, vector<2xf64>) {
-// CHECK-DAG: %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
-// CHECK-DAG: %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
// CHECK: %[[IN0_F32A:.*]] = vector.extract %[[VAL_0A]][0] : f32 from vector<2xf32>
// CHECK: %[[IN0_F32B:.*]] = vector.extract %[[VAL_0B]][0] : f32 from vector<2xf32>
// CHECK: %[[OUT0_F32:.*]] = call @powf(%[[IN0_F32A]], %[[IN0_F32B]]) : (f32, f32) -> f32
-// CHECK: %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
// CHECK: %[[IN1_F32A:.*]] = vector.extract %[[VAL_0A]][1] : f32 from vector<2xf32>
// CHECK: %[[IN1_F32B:.*]] = vector.extract %[[VAL_0B]][1] : f32 from vector<2xf32>
// CHECK: %[[OUT1_F32:.*]] = call @powf(%[[IN1_F32A]], %[[IN1_F32B]]) : (f32, f32) -> f32
-// CHECK: %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
+// CHECK: %[[RES_F32:.*]] = vector.from_elements %[[OUT0_F32]], %[[OUT1_F32]] : vector<2xf32>
// CHECK: %[[IN0_F64A:.*]] = vector.extract %[[VAL_1A]][0] : f64 from vector<2xf64>
// CHECK: %[[IN0_F64B:.*]] = vector.extract %[[VAL_1B]][0] : f64 from vector<2xf64>
// CHECK: %[[OUT0_F64:.*]] = call @pow(%[[IN0_F64A]], %[[IN0_F64B]]) : (f64, f64) -> f64
-// CHECK: %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
// CHECK: %[[IN1_F64A:.*]] = vector.extract %[[VAL_1A]][1] : f64 from vector<2xf64>
// CHECK: %[[IN1_F64B:.*]] = vector.extract %[[VAL_1B]][1] : f64 from vector<2xf64>
// CHECK: %[[OUT1_F64:.*]] = call @pow(%[[IN1_F64A]], %[[IN1_F64B]]) : (f64, f64) -> f64
-// CHECK: %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
-// CHECK: return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
+// CHECK: %[[RES_F64:.*]] = vector.from_elements %[[OUT0_F64]], %[[OUT1_F64]] : vector<2xf64>
+// CHECK: return %[[RES_F32]], %[[RES_F64]] : vector<2xf32>, vector<2xf64>
// CHECK: }
diff --git a/mlir/test/Dialect/Vector/canonicalize.mlir b/mlir/test/Dialect/Vector/canonicalize.mlir
index 36f3d7196bb93..1d9817f83f695 100644
--- a/mlir/test/Dialect/Vector/canonicalize.mlir
+++ b/mlir/test/Dialect/Vector/canonicalize.mlir
@@ -566,40 +566,40 @@ func.func @insert_extract_transpose_2d(
// -----
// CHECK-LABEL: insert_extract_chain
-// CHECK-SAME: %[[V234:[a-zA-Z0-9]*]]: vector<2x3x4xf32>
+// CHECK-SAME: %[[V334:[a-zA-Z0-9]*]]: vector<3x3x4xf32>
// CHECK-SAME: %[[V34:[a-zA-Z0-9]*]]: vector<3x4xf32>
// CHECK-SAME: %[[V4:[a-zA-Z0-9]*]]: vector<4xf32>
-func.func @insert_extract_chain(%v234: vector<2x3x4xf32>, %v34: vector<3x4xf32>, %v4: vector<4xf32>)
+func.func @insert_extract_chain(%v334: vector<3x3x4xf32>, %v34: vector<3x4xf32>, %v4: vector<4xf32>)
-> (vector<4xf32>, vector<4xf32>, vector<3x4xf32>, vector<3x4xf32>) {
// CHECK-NEXT: %[[A34:.*]] = vector.insert
- %A34 = vector.insert %v34, %v234[0]: vector<3x4xf32> into vector<2x3x4xf32>
+ %A34 = vector.insert %v34, %v334[0]: vector<3x4xf32> into vector<3x3x4xf32>
// CHECK-NEXT: %[[B34:.*]] = vector.insert
- %B34 = vector.insert %v34, %A34[1]: vector<3x4xf32> into vector<2x3x4xf32>
+ %B34 = vector.insert %v34, %A34[1]: vector<3x4xf32> into vector<3x3x4xf32>
// CHECK-NEXT: %[[A4:.*]] = vector.insert
- %A4 = vector.insert %v4, %B34[1, 0]: vector<4xf32> into vector<2x3x4xf32>
+ %A4 = vector.insert %v4, %B34[1, 0]: vector<4xf32> into vector<3x3x4xf32>
// CHECK-NEXT: %[[B4:.*]] = vector.insert
- %B4 = vector.insert %v4, %A4[1, 1]: vector<4xf32> into vector<2x3x4xf32>
+ %B4 = vector.insert %v4, %A4[1, 1]: vector<4xf32> into vector<3x3x4xf32>
// Case 2.a. [1, 1] == insertpos ([1, 1])
// Match %A4 insertionpos and fold to its source(i.e. %V4).
- %r0 = vector.extract %B4[1, 1]: vector<4xf32> from vector<2x3x4xf32>
+ %r0 = vector.extract %B4[1, 1]: vector<4xf32> from vector<3x3x4xf32>
// Case 3.a. insertpos ([1]) is a prefix of [1, 0].
// Traverse %B34 to its source(i.e. %V34@[*0*]).
// CHECK-NEXT: %[[R1:.*]] = vector.extract %[[V34]][0]
- %r1 = vector.extract %B34[1, 0]: vector<4xf32> from vector<2x3x4xf32>
+ %r1 = vector.extract %B34[1, 0]: vector<4xf32> from vector<3x3x4xf32>
// Case 4. [1] is a prefix of insertpos ([1, 1]).
// Cannot traverse %B4.
// CHECK-NEXT: %[[R2:.*]] = vector.extract %[[B4]][1]
- %r2 = vector.extract %B4[1]: vector<3x4xf32> from vector<2x3x4xf32>
+ %r2 = vector.extract %B4[1]: vector<3x4xf32> from vector<3x3x4xf32>
// Case 5. [0] is disjoint from insertpos ([1, 1]).
// Traverse %B4 to its dest(i.e. %A4@[0]).
// Traverse %A4 to its dest(i.e. %B34@[0]).
// Traverse %B34 to its dest(i.e. %A34@[0]).
// Match %A34 insertionpos and fold to its source(i.e. %V34).
- %r3 = vector.extract %B4[0]: vector<3x4xf32> from vector<2x3x4xf32>
+ %r3 = vector.extract %B4[0]: vector<3x4xf32> from vector<3x3x4xf32>
// CHECK: return %[[V4]], %[[R1]], %[[R2]], %[[V34]]
return %r0, %r1, %r2, %r3:
@@ -946,8 +946,8 @@ func.func @insert_fold_same_rank(%v: vector<2x2xf32>) -> vector<2x2xf32> {
// CHECK-LABEL: func @insert_no_fold_scalar_to_0d(
// CHECK-SAME: %[[v:.*]]: vector<f32>)
-// CHECK: %[[extract:.*]] = vector.insert %{{.*}}, %[[v]] [] : f32 into vector<f32>
-// CHECK: return %[[extract]]
+// CHECK: %[[cst:.*]] = arith.constant dense<0.000000e+00> : vector<f32>
+// CHECK: return %[[cst]]
func.func @insert_no_fold_scalar_to_0d(%v: vector<f32>) -> vector<f32> {
%cst = arith.constant 0.000000e+00 : f32
%0 = vector.insert %cst, %v [] : f32 into vector<f32>
@@ -2320,34 +2320,40 @@ func.func @insert_2d_constant() -> (vector<2x3xi32>, vector<2x3xi32>, vector<2x3
// -----
-// CHECK-LABEL: func.func @fully_insert_scalar_constant_to_poison_vector
-// CHECK: %[[VAL0:.+]] = arith.constant dense<[10, 20]> : vector<2xi64>
-// CHECK-NEXT: return %[[VAL0]]
-func.func @fully_insert_scalar_constant_to_poison_vector() -> vector<2xi64> {
- %poison = ub.poison : vector<2xi64>
+// CHECK-LABEL: func.func @fully_insert_scalar_to_vector(
+// CHECK-SAME: %[[ARG0:.+]]: vector<2xi64>)
+// CHECK: %[[CST10:.+]] = arith.constant 10 : i64
+// CHECK: %[[CST20:.+]] = arith.constant 20 : i64
+// CHECK: %[[RES:.+]] = vector.from_elements %[[CST10]], %[[CST20]] : vector<2xi64>
+// CHECK-NEXT: return %[[RES]]
+func.func @fully_insert_scalar_to_vector(%arg0 : vector<2xi64>) -> vector<2xi64> {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%e0 = arith.constant 10 : i64
%e1 = arith.constant 20 : i64
- %v1 = vector.insert %e0, %poison[%c0] : i64 into vector<2xi64>
+ %v1 = vector.insert %e0, %arg0[%c0] : i64 into vector<2xi64>
%v2 = vector.insert %e1, %v1[%c1] : i64 into vector<2xi64>
return %v2 : vector<2xi64>
}
// -----
-// CHECK-LABEL: func.func @fully_insert_vector_constant_to_poison_vector
-// CHECK: %[[VAL0:.+]] = arith.constant dense<{{\[\[1, 2, 3\], \[4, 5, 6\]\]}}> : vector<2x3xi64>
-// CHECK-NEXT: return %[[VAL0]]
-func.func @fully_insert_vector_constant_to_poison_vector() -> vector<2x3xi64> {
- %poison = ub.poison : vector<2x3xi64>
- %cv0 = arith.constant dense<[1, 2, 3]> : vector<3xi64>
- %cv1 = arith.constant dense<[4, 5, 6]> : vector<3xi64>
+// CHECK-LABEL: func.func @fully_insert_vector_to_vector(
+// CHECK-SAME: %[[ARG0:.+]]: vector<2x2xi64>
+// CHECK: %[[CST1:.+]] = arith.constant 1 : i64
+// CHECK: %[[CST2:.+]] = arith.constant 2 : i64
+// CHECK: %[[CST3:.+]] = arith.constant 3 : i64
+// CHECK: %[[CST4:.+]] = arith.constant 4 : i64
+// CHECK: %[[RES:.+]] = vector.from_elements %[[CST1]], %[[CST2]], %[[CST3]], %[[CST4]] : vector<2x2xi64>
+// CHECK-NEXT: return %[[RES]]
+func.func @fully_insert_vector_to_vector(%arg0 : vector<2x2xi64>) -> vector<2x2xi64> {
+ %cv0 = arith.constant dense<[1, 2]> : vector<2xi64>
+ %cv1 = arith.constant dense<[3, 4]> : vector<2xi64>
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
- %v1 = vector.insert %cv0, %poison[%c0] : vector<3xi64> into vector<2x3xi64>
- %v2 = vector.insert %cv1, %v1[%c1] : vector<3xi64> into vector<2x3xi64>
- return %v2 : vector<2x3xi64>
+ %v1 = vector.insert %cv0, %arg0[%c0] : vector<2xi64> into vector<2x2xi64>
+ %v2 = vector.insert %cv1, %v1[%c1] : vector<2xi64> into vector<2x2xi64>
+ return %v2 : vector<2x2xi64>
}
// -----
diff --git a/mlir/test/Dialect/Vector/vector-gather-lowering.mlir b/mlir/test/Dialect/Vector/vector-gather-lowering.mlir
index 5be267c1be984..246aeeb5cfaf6 100644
--- a/mlir/test/Dialect/Vector/vector-gather-lowering.mlir
+++ b/mlir/test/Dialect/Vector/vector-gather-lowering.mlir
@@ -198,7 +198,7 @@ func.func @gather_memref_non_unit_stride_read_more_than_1_element(%base: memref<
// CANON-NOT: scf.if
// CANON: tensor.extract
// CANON: tensor.extract
-// CANON: [[FINAL:%.+]] = vector.insert %{{.+}}, %{{.+}} [1] : f32 into vector<2xf32>
+// CANON: [[FINAL:%.+]] = vector.from_elements %{{.+}}, %{{.+}} : vector<2xf32>
// CANON-NEXT: return [[FINAL]] : vector<2xf32>
func.func @gather_tensor_1d_all_set(%base: tensor<?xf32>, %v: vector<2xindex>, %pass_thru: vector<2xf32>) -> vector<2xf32> {
%mask = arith.constant dense <true> : vector<2xi1>
diff --git a/mlir/test/Dialect/Vector/vector-warp-distribute.mlir b/mlir/test/Dialect/Vector/vector-warp-distribute.mlir
index 38771f2593449..9e83af35c3161 100644
--- a/mlir/test/Dialect/Vector/vector-warp-distribute.mlir
+++ b/mlir/test/Dialect/Vector/vector-warp-distribute.mlir
@@ -1191,7 +1191,7 @@ func.func @vector_insertelement_1d_broadcast(%laneid: index, %pos: index) -> (ve
// CHECK-PROP: %[[VEC:.*]] = "some_def"
// CHECK-PROP: %[[VAL:.*]] = "another_def"
// CHECK-PROP: gpu.yield %[[VEC]], %[[VAL]]
-// CHECK-PROP: vector.insert %[[W]]#1, %[[W]]#0 [] : f32 into vector<f32>
+// CHECK-PROP: vector.splat %[[W]]#1 : vector<f32>
func.func @vector_insertelement_0d(%laneid: index) -> (vector<f32>) {
%r = gpu.warp_execute_on_lane_0(%laneid)[32] -> (vector<f32>) {
%0 = "some_def"() : () -> (vector<f32>)
More information about the Mlir-commits
mailing list