[llvm] [LoongArch] Support llvm.lround intrinsics with i32 return type. (PR #114733)

Zhaoxin Yang via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 3 20:48:42 PST 2024


https://github.com/ylzsx created https://github.com/llvm/llvm-project/pull/114733

This is needed by flang, similar to RISCV-64 in D147195.

>From cf10cf97c76d8fb54155a46bf3953c813351bf9b Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Thu, 31 Oct 2024 18:08:21 +0800
Subject: [PATCH] [LoongArch] Support llvm.lround intrinsics with i32 return
 type.

This is needed by flang, similar to RISCV-64 in D147195.
---
 .../LoongArch/LoongArchISelLowering.cpp       | 13 ++++++++++++
 llvm/test/CodeGen/LoongArch/double-lround.ll  | 20 +++++++++++++++++++
 llvm/test/CodeGen/LoongArch/float-lround.ll   | 20 +++++++++++++++++++
 3 files changed, 53 insertions(+)
 create mode 100644 llvm/test/CodeGen/LoongArch/double-lround.ll
 create mode 100644 llvm/test/CodeGen/LoongArch/float-lround.ll

diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 6bee00d1ce3823..7bea9bdcfb8c1a 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -143,6 +143,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::BITREVERSE, MVT::i32, Custom);
     setOperationAction(ISD::BSWAP, MVT::i32, Custom);
     setOperationAction({ISD::UDIV, ISD::UREM}, MVT::i32, Custom);
+    setOperationAction(ISD::LROUND, MVT::i32, Custom);
   }
 
   // Set operations for LA32 only.
@@ -3103,6 +3104,18 @@ void LoongArchTargetLowering::ReplaceNodeResults(
     replaceINTRINSIC_WO_CHAINResults(N, Results, DAG, Subtarget);
     break;
   }
+  case ISD::LROUND: {
+    SDValue Op0 = N->getOperand(0);
+    RTLIB::Libcall LC =
+        Op0.getValueType() == MVT::f64 ? RTLIB::LROUND_F64 : RTLIB::LROUND_F32;
+    MakeLibCallOptions CallOptions;
+    EVT OpVT = Op0.getValueType();
+    CallOptions.setTypeListBeforeSoften(OpVT, MVT::i64, true);
+    SDValue Result = makeLibCall(DAG, LC, MVT::i64, Op0, CallOptions, DL).first;
+    Result = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Result);
+    Results.push_back(Result);
+    break;
+  }
   }
 }
 
diff --git a/llvm/test/CodeGen/LoongArch/double-lround.ll b/llvm/test/CodeGen/LoongArch/double-lround.ll
new file mode 100644
index 00000000000000..e90a7ce29e5a0b
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/double-lround.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch64 --mattr=-f,-d %s -o - \
+; RUN:   | FileCheck -check-prefix=LA64S %s
+
+declare i32 @llvm.lround.i32.f64(double)
+
+;; We support lround with i32 as return type on LoongArch64. This is needed by flang.
+define i32 @lround_i32_f64(double %a) nounwind {
+; LA64S-LABEL: lround_i32_f64:
+; LA64S:       # %bb.0:
+; LA64S-NEXT:    addi.d $sp, $sp, -16
+; LA64S-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64S-NEXT:    bl %plt(lround)
+; LA64S-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64S-NEXT:    addi.d $sp, $sp, 16
+; LA64S-NEXT:    ret
+
+  %1 = call i32 @llvm.lround.i32.f64(double %a)
+  ret i32 %1
+}
diff --git a/llvm/test/CodeGen/LoongArch/float-lround.ll b/llvm/test/CodeGen/LoongArch/float-lround.ll
new file mode 100644
index 00000000000000..a17ba4e3e5d926
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/float-lround.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch64 --mattr=-f,-d %s -o - \
+; RUN:   | FileCheck -check-prefix=LA64S %s
+
+declare i32 @llvm.lround.i32.f32(float)
+
+; We support lround with i32 as return type on LoongArch64. This is needed by flang.
+define i32 @lround_i32_f32(float %a) nounwind {
+; LA64S-LABEL: lround_i32_f32:
+; LA64S:       # %bb.0:
+; LA64S-NEXT:    addi.d $sp, $sp, -16
+; LA64S-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64S-NEXT:    bl %plt(lroundf)
+; LA64S-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64S-NEXT:    addi.d $sp, $sp, 16
+; LA64S-NEXT:    ret
+
+  %1 = call i32 @llvm.lround.i32.f32(float %a)
+  ret i32 %1
+}



More information about the llvm-commits mailing list