[Mlir-commits] [mlir] [MLIR][LLVMIR] Extend llrint, lrint, lround for vectors of float (PR #136225)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Apr 17 16:34:56 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Bruno Cardoso Lopes (bcardosolopes)

<details>
<summary>Changes</summary>

Matching langref. Note that `llround` is different than the rest.

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


3 Files Affected:

- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td (+7-5) 
- (modified) mlir/test/Target/LLVMIR/Import/intrinsic.ll (+33-13) 
- (modified) mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir (+26-3) 


``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index ab928c9e2d0e7..bc85881c94cd9 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -153,16 +153,18 @@ def LLVM_PowOp : LLVM_BinarySameArgsIntrOpF<"pow">;
 def LLVM_PowIOp : LLVM_PowFI<"powi">;
 def LLVM_RintOp : LLVM_UnaryIntrOpF<"rint">;
 def LLVM_NearbyintOp : LLVM_UnaryIntrOpF<"nearbyint">;
-class LLVM_IntRoundIntrOpBase<string func> :
+class LLVM_IntRoundIntrOpBase<string func, Type element = LLVM_AnyFloat> :
         LLVM_OneResultIntrOp<func, [0], [0], [Pure]> {
-  let arguments = (ins LLVM_AnyFloat:$val);
+  let arguments = (ins element:$val);
   let assemblyFormat = "`(` operands `)` attr-dict `:` "
       "functional-type(operands, results)";
 }
-def LLVM_LroundOp : LLVM_IntRoundIntrOpBase<"lround">;
+class LLVM_IntRoundIntrVecOrFloatOpBase<string func> :
+  LLVM_IntRoundIntrOpBase<func, LLVM_ScalarOrVectorOf<LLVM_AnyFloat>>;
+def LLVM_LroundOp : LLVM_IntRoundIntrVecOrFloatOpBase<"lround">;
 def LLVM_LlroundOp : LLVM_IntRoundIntrOpBase<"llround">;
-def LLVM_LrintOp : LLVM_IntRoundIntrOpBase<"lrint">;
-def LLVM_LlrintOp : LLVM_IntRoundIntrOpBase<"llrint">;
+def LLVM_LrintOp : LLVM_IntRoundIntrVecOrFloatOpBase<"lrint">;
+def LLVM_LlrintOp : LLVM_IntRoundIntrVecOrFloatOpBase<"llrint">;
 def LLVM_BitReverseOp : LLVM_UnaryIntrOpI<"bitreverse">;
 def LLVM_ByteSwapOp : LLVM_UnaryIntrOpI<"bswap">;
 def LLVM_CountLeadingZerosOp : LLVM_CountZerosIntrOp<"ctlz">;
diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
index b0a36939d8c48..36afa84a031f4 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
@@ -235,15 +235,23 @@ define void @nearbyint_test(float %0, double %1, <8 x float> %2, <8 x double> %3
   ret void
 }
 ; CHECK-LABEL: llvm.func @lround_test
-define void @lround_test(float %0, double %1) {
+define void @lround_test(float %0, double %1, <2 x float> %2, <2 x double> %3) {
   ; CHECK: llvm.intr.lround(%{{.*}}) : (f32) -> i32
-  %3 = call i32 @llvm.lround.i32.f32(float %0)
+  %5 = call i32 @llvm.lround.i32.f32(float %0)
   ; CHECK: llvm.intr.lround(%{{.*}}) : (f32) -> i64
-  %4 = call i64 @llvm.lround.i64.f32(float %0)
+  %6 = call i64 @llvm.lround.i64.f32(float %0)
   ; CHECK: llvm.intr.lround(%{{.*}}) : (f64) -> i32
-  %5 = call i32 @llvm.lround.i32.f64(double %1)
+  %7 = call i32 @llvm.lround.i32.f64(double %1)
   ; CHECK: llvm.intr.lround(%{{.*}}) : (f64) -> i64
-  %6 = call i64 @llvm.lround.i64.f64(double %1)
+  %8 = call i64 @llvm.lround.i64.f64(double %1)
+  ; CHECK: llvm.intr.lround(%{{.*}}) : (vector<2xf32>) -> vector<2xi32>
+  %9 = call <2 x i32> @llvm.lround.v2i32.v2f32(<2 x float> %2)
+  ; CHECK: llvm.intr.lround(%{{.*}}) : (vector<2xf64>) -> vector<2xi32>
+  %10 = call <2 x i32> @llvm.lround.v2i32.v2f64(<2 x double> %3)
+  ; CHECK: llvm.intr.lround(%{{.*}}) : (vector<2xf32>) -> vector<2xi64>
+  %11 = call <2 x i64> @llvm.lround.v2i64.v2f32(<2 x float> %2)
+  ; CHECK: llvm.intr.lround(%{{.*}}) : (vector<2xf64>) -> vector<2xi64>
+  %12 = call <2 x i64> @llvm.lround.v2i64.v2f64(<2 x double> %3)
   ret void
 }
 ; CHECK-LABEL: llvm.func @llround_test
@@ -255,23 +263,35 @@ define void @llround_test(float %0, double %1) {
   ret void
 }
 ; CHECK-LABEL: llvm.func @lrint_test
-define void @lrint_test(float %0, double %1) {
+define void @lrint_test(float %0, double %1, <2 x float> %2, <2 x double> %3) {
   ; CHECK: llvm.intr.lrint(%{{.*}}) : (f32) -> i32
-  %3 = call i32 @llvm.lrint.i32.f32(float %0)
+  %5 = call i32 @llvm.lrint.i32.f32(float %0)
   ; CHECK: llvm.intr.lrint(%{{.*}}) : (f32) -> i64
-  %4 = call i64 @llvm.lrint.i64.f32(float %0)
+  %6 = call i64 @llvm.lrint.i64.f32(float %0)
   ; CHECK: llvm.intr.lrint(%{{.*}}) : (f64) -> i32
-  %5 = call i32 @llvm.lrint.i32.f64(double %1)
+  %7 = call i32 @llvm.lrint.i32.f64(double %1)
   ; CHECK: llvm.intr.lrint(%{{.*}}) : (f64) -> i64
-  %6 = call i64 @llvm.lrint.i64.f64(double %1)
+  %8 = call i64 @llvm.lrint.i64.f64(double %1)
+  ; CHECK: llvm.intr.lrint(%{{.*}}) : (vector<2xf32>) -> vector<2xi32>
+  %9 = call <2 x i32> @llvm.lrint.v2i32.v2f32(<2 x float> %2)
+  ; CHECK: llvm.intr.lrint(%{{.*}}) : (vector<2xf64>) -> vector<2xi32>
+  %10 = call <2 x i32> @llvm.lrint.v2i32.v2f64(<2 x double> %3)
+  ; CHECK: llvm.intr.lrint(%{{.*}}) : (vector<2xf32>) -> vector<2xi64>
+  %11 = call <2 x i64> @llvm.lrint.v2i64.v2f32(<2 x float> %2)
+  ; CHECK: llvm.intr.lrint(%{{.*}}) : (vector<2xf64>) -> vector<2xi64>
+  %12 = call <2 x i64> @llvm.lrint.v2i64.v2f64(<2 x double> %3)
   ret void
 }
 ; CHECK-LABEL: llvm.func @llrint_test
-define void @llrint_test(float %0, double %1) {
+define void @llrint_test(float %0, double %1, <2 x float> %2, <2 x double> %3) {
   ; CHECK: llvm.intr.llrint(%{{.*}}) : (f32) -> i64
-  %3 = call i64 @llvm.llrint.i64.f32(float %0)
+  %5 = call i64 @llvm.llrint.i64.f32(float %0)
   ; CHECK: llvm.intr.llrint(%{{.*}}) : (f64) -> i64
-  %4 = call i64 @llvm.llrint.i64.f64(double %1)
+  %6 = call i64 @llvm.llrint.i64.f64(double %1)
+  ; CHECK: llvm.intr.llrint(%{{.*}}) : (vector<2xf32>) -> vector<2xi64>
+  %7 = call <2 x i64> @llvm.llrint.v2i64.v2f32(<2 x float> %2)
+  ; CHECK: llvm.intr.llrint(%{{.*}}) : (vector<2xf64>) -> vector<2xi64>
+  %8 = call <2 x i64> @llvm.llrint.v2i64.v2f64(<2 x double> %3)
   ret void
 }
 
diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
index 8088dec811e13..ba12140c59b35 100644
--- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -242,7 +242,8 @@ llvm.func @nearbyint_test(%arg0 : f32, %arg1 : f64, %arg2 : vector<8xf32>, %arg3
 }
 
 // CHECK-LABEL: @lround_test
-llvm.func @lround_test(%arg0 : f32, %arg1 : f64) {
+llvm.func @lround_test(%arg0 : f32, %arg1 : f64,
+                       %arg2 : vector<2xf32>, %arg3 : vector<2xf64>) {
   // CHECK: call i32 @llvm.lround.i32.f32
   "llvm.intr.lround"(%arg0) : (f32) -> i32
   // CHECK: call i64 @llvm.lround.i64.f32
@@ -251,6 +252,14 @@ llvm.func @lround_test(%arg0 : f32, %arg1 : f64) {
   "llvm.intr.lround"(%arg1) : (f64) -> i32
   // CHECK: call i64 @llvm.lround.i64.f64
   "llvm.intr.lround"(%arg1) : (f64) -> i64
+  // CHECK: call <2 x i32> @llvm.lround.v2i32.v2f32
+  "llvm.intr.lround"(%arg2) : (vector<2xf32>) -> vector<2xi32>
+  // CHECK: call <2 x i32> @llvm.lround.v2i32.v2f64
+  "llvm.intr.lround"(%arg3) : (vector<2xf64>) -> vector<2xi32>
+  // CHECK: call <2 x i64> @llvm.lround.v2i64.v2f32
+  "llvm.intr.lround"(%arg2) : (vector<2xf32>) -> vector<2xi64>
+  // CHECK: call <2 x i64> @llvm.lround.v2i64.v2f64
+  "llvm.intr.lround"(%arg3) : (vector<2xf64>) -> vector<2xi64>
   llvm.return
 }
 
@@ -264,7 +273,8 @@ llvm.func @llround_test(%arg0 : f32, %arg1 : f64) {
 }
 
 // CHECK-LABEL: @lrint_test
-llvm.func @lrint_test(%arg0 : f32, %arg1 : f64) {
+llvm.func @lrint_test(%arg0 : f32, %arg1 : f64,
+                      %arg2 : vector<2xf32>, %arg3 : vector<2xf64>) {
   // CHECK: call i32 @llvm.lrint.i32.f32
   "llvm.intr.lrint"(%arg0) : (f32) -> i32
   // CHECK: call i64 @llvm.lrint.i64.f32
@@ -273,15 +283,28 @@ llvm.func @lrint_test(%arg0 : f32, %arg1 : f64) {
   "llvm.intr.lrint"(%arg1) : (f64) -> i32
   // CHECK: call i64 @llvm.lrint.i64.f64
   "llvm.intr.lrint"(%arg1) : (f64) -> i64
+  // CHECK: call <2 x i32> @llvm.lrint.v2i32.v2f32
+  "llvm.intr.lrint"(%arg2) : (vector<2xf32>) -> vector<2xi32>
+  // CHECK: call <2 x i32> @llvm.lrint.v2i32.v2f64
+  "llvm.intr.lrint"(%arg3) : (vector<2xf64>) -> vector<2xi32>
+  // CHECK: call <2 x i64> @llvm.lrint.v2i64.v2f32
+  "llvm.intr.lrint"(%arg2) : (vector<2xf32>) -> vector<2xi64>
+  // CHECK: call <2 x i64> @llvm.lrint.v2i64.v2f64
+  "llvm.intr.lrint"(%arg3) : (vector<2xf64>) -> vector<2xi64>
   llvm.return
 }
 
 // CHECK-LABEL: @llrint_test
-llvm.func @llrint_test(%arg0 : f32, %arg1 : f64) {
+llvm.func @llrint_test(%arg0 : f32, %arg1 : f64,
+                       %arg2 : vector<2xf32>, %arg3 : vector<2xf64>) {
   // CHECK: call i64 @llvm.llrint.i64.f32
   "llvm.intr.llrint"(%arg0) : (f32) -> i64
   // CHECK: call i64 @llvm.llrint.i64.f64
   "llvm.intr.llrint"(%arg1) : (f64) -> i64
+  // CHECK: call <2 x i64> @llvm.llrint.v2i64.v2f32
+  "llvm.intr.llrint"(%arg2) : (vector<2xf32>) -> vector<2xi64>
+  // CHECK: call <2 x i64> @llvm.llrint.v2i64.v2f64
+  "llvm.intr.llrint"(%arg3) : (vector<2xf64>) -> vector<2xi64>
   llvm.return
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/136225


More information about the Mlir-commits mailing list