[mlir][Vector] Fix vector.extract lowering to llvm for 0-d vectors by Groverkss · Pull Request #117731 · llvm/llvm-project (original) (raw)

@llvm/pr-subscribers-mlir

Author: Kunwar Grover (Groverkss)

Changes

The current implementation of lowering to llvm for vector.extract incorrectly assumes that if the number of indices is zero, the operation can be folded away. This PR removes this condition and relies on the folder to do it instead.

This PR also unifies the logic for scalar extracts and slice extracts, which as a side effect also enables vector.extract lowering for n-d vector.extract with dynamic inner most dimension. (This was only prevented by a conservative check in the old implementation)


Full diff: https://github.com/llvm/llvm-project/pull/117731.diff

2 Files Affected:

diff --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp index 58ca84c8d7bca6..3f47b20cdb577b 100644 --- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp +++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp @@ -1096,43 +1096,50 @@ class VectorExtractOpConversion SmallVector positionVec = getMixedValues( adaptor.getStaticPosition(), adaptor.getDynamicPosition(), rewriter); - // Extract entire vector. Should be handled by folder, but just to be safe. - ArrayRef position(positionVec); - if (position.empty()) { - rewriter.replaceOp(extractOp, adaptor.getVector()); - return success(); - }

// -----

-func.func @extract_scalar_from_vec_2d_f32_dynamic_idx(%arg0: vector<1x16xf32>, %arg1: index) -> f32 { +func.func @extract_scalar_from_vec_2d_f32_inner_dynamic_idx(%arg0: vector<1x16xf32>, %arg1: index) -> f32 { %0 = vector.extract %arg0[0, %arg1]: f32 from vector<1x16xf32> return %0 : f32 }

-// Multi-dim vectors are not supported but this test shouldn't crash. +// Multi-dim vectors are supported if the inner most dimension is dynamic.

-// CHECK-LABEL: @extract_scalar_from_vec_2d_f32_dynamic_idx( -// CHECK: vector.extract +// CHECK-LABEL: @extract_scalar_from_vec_2d_f32_inner_dynamic_idx( +// CHECK: llvm.extractvalue +// CHECK: llvm.extractelement

-func.func @extract_scalar_from_vec_2d_f32_dynamic_idx_scalable(%arg0: vector<1x[16]xf32>, %arg1: index) -> f32 { +func.func @extract_scalar_from_vec_2d_f32_inner_dynamic_idx_scalable(%arg0: vector<1x[16]xf32>, %arg1: index) -> f32 { %0 = vector.extract %arg0[0, %arg1]: f32 from vector<1x[16]xf32> return %0 : f32 }

-// Multi-dim vectors are not supported but this test shouldn't crash. +// Multi-dim vectors are supported if the inner most dimension is dynamic. + +// CHECK-LABEL: @extract_scalar_from_vec_2d_f32_inner_dynamic_idx_scalable( +// CHECK: llvm.extractvalue +// CHECK: llvm.extractelement + +// -----

-// CHECK-LABEL: @extract_scalar_from_vec_2d_f32_dynamic_idx_scalable( +func.func @extract_scalar_from_vec_2d_f32_outer_dynamic_idx(%arg0: vector<1x16xf32>, %arg1: index) -> f32 {

+func.func @extract_scalar_from_vec_2d_f32_outer_dynamic_idx_scalable(%arg0: vector<1x[16]xf32>, %arg1: index) -> f32 {

+// CHECK: %[[T1:.]] = llvm.mlir.constant(0 : index) : i64 +// CHECK: %[[T2:.]] = llvm.extractelement %[[T0]][%[[T1]] : i64] : vector<1xi64> +// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : i64 to index +// CHECK: return %[[T3]] : index + // -----

func.func @insertelement_into_vec_0d_f32(%arg0: f32, %arg1: vector) -> vector {