[llvm] r366039 - [PowerPC] Support fp128 libcalls

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 14 22:02:32 PDT 2019


Author: maskray
Date: Sun Jul 14 22:02:32 2019
New Revision: 366039

URL: http://llvm.org/viewvc/llvm-project?rev=366039&view=rev
Log:
[PowerPC] Support fp128 libcalls

On PowerPC, IEEE 754 quadruple-precision libcall names use "kf" instead of "tf".

In libgcc, libgcc/config/rs6000/float128-sed converts TF names to KF
names. This patch implements its 24 substitution rules.

Reviewed By: hfinkel

Differential Revision: https://reviews.llvm.org/D64282

Added:
    llvm/trunk/test/CodeGen/PowerPC/fp128-libcalls.ll
Modified:
    llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp

Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=366039&r1=366038&r2=366039&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Sun Jul 14 22:02:32 2019
@@ -123,6 +123,34 @@ void TargetLoweringBase::InitLibcalls(co
   for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC)
     setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C);
 
+  // For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
+  if (TT.getArch() == Triple::ppc || TT.isPPC64()) {
+    setLibcallName(RTLIB::ADD_F128, "__addkf3");
+    setLibcallName(RTLIB::SUB_F128, "__subkf3");
+    setLibcallName(RTLIB::MUL_F128, "__mulkf3");
+    setLibcallName(RTLIB::DIV_F128, "__divkf3");
+    setLibcallName(RTLIB::FPEXT_F32_F128, "__extendsfkf2");
+    setLibcallName(RTLIB::FPEXT_F64_F128, "__extenddfkf2");
+    setLibcallName(RTLIB::FPROUND_F128_F32, "__trunckfsf2");
+    setLibcallName(RTLIB::FPROUND_F128_F64, "__trunckfdf2");
+    setLibcallName(RTLIB::FPTOSINT_F128_I32, "__fixkfsi");
+    setLibcallName(RTLIB::FPTOSINT_F128_I64, "__fixkfdi");
+    setLibcallName(RTLIB::FPTOUINT_F128_I32, "__fixunskfsi");
+    setLibcallName(RTLIB::FPTOUINT_F128_I64, "__fixunskfdi");
+    setLibcallName(RTLIB::SINTTOFP_I32_F128, "__floatsikf");
+    setLibcallName(RTLIB::SINTTOFP_I64_F128, "__floatdikf");
+    setLibcallName(RTLIB::UINTTOFP_I32_F128, "__floatunsikf");
+    setLibcallName(RTLIB::UINTTOFP_I64_F128, "__floatundikf");
+    setLibcallName(RTLIB::OEQ_F128, "__eqkf2");
+    setLibcallName(RTLIB::UNE_F128, "__nekf2");
+    setLibcallName(RTLIB::OGE_F128, "__gekf2");
+    setLibcallName(RTLIB::OLT_F128, "__ltkf2");
+    setLibcallName(RTLIB::OLE_F128, "__lekf2");
+    setLibcallName(RTLIB::OGT_F128, "__gtkf2");
+    setLibcallName(RTLIB::UO_F128, "__unordkf2");
+    setLibcallName(RTLIB::O_F128, "__unordkf2");
+  }
+
   // A few names are different on particular architectures or environments.
   if (TT.isOSDarwin()) {
     // For f16/f32 conversions, Darwin uses the standard naming scheme, instead

Added: llvm/trunk/test/CodeGen/PowerPC/fp128-libcalls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fp128-libcalls.ll?rev=366039&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/fp128-libcalls.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/fp128-libcalls.ll Sun Jul 14 22:02:32 2019
@@ -0,0 +1,164 @@
+; RUN: llc < %s -O2 -mtriple=powerpc-linux-musl | FileCheck %s
+; RUN: llc < %s -O2 -mtriple=powerpc64-linux-musl | FileCheck %s
+; RUN: llc < %s -O2 -mtriple=powerpc64le-linux-musl | FileCheck %s
+
+define fp128 @addkf3(fp128 %a, fp128 %b) {
+; CHECK-LABEL: addkf3:
+; CHECK: __addkf3
+  %1 = fadd fp128 %a, %b
+  ret fp128 %1
+}
+
+define fp128 @subkf3(fp128 %a, fp128 %b) {
+; CHECK-LABEL: subkf3:
+; CHECK: __subkf3
+  %1 = fsub fp128 %a, %b
+  ret fp128 %1
+}
+
+define fp128 @mulkf3(fp128 %a, fp128 %b) {
+; CHECK-LABEL: mulkf3:
+; CHECK: __mulkf3
+  %1 = fmul fp128 %a, %b
+  ret fp128 %1
+}
+
+define fp128 @divkf3(fp128 %a, fp128 %b) {
+; CHECK-LABEL: divkf3:
+; CHECK: __divkf3
+  %1 = fdiv fp128 %a, %b
+  ret fp128 %1
+}
+
+define fp128 @extendsfkf2(float %a) {
+; CHECK-LABEL: extendsfkf2:
+; CHECK: __extendsfkf2
+  %1 = fpext float %a to fp128
+  ret fp128 %1
+}
+
+define fp128 @extenddfkf2(double %a) {
+; CHECK-LABEL: extenddfkf2:
+; CHECK: __extenddfkf2
+  %1 = fpext double %a to fp128
+  ret fp128 %1
+}
+
+define float @trunckfsf2(fp128 %a) {
+; CHECK-LABEL: trunckfsf2:
+; CHECK: __trunckfsf2
+  %1 = fptrunc fp128 %a to float
+  ret float %1
+}
+
+define double @trunckfdf2(fp128 %a) {
+; CHECK-LABEL: trunckfdf2:
+; CHECK: __trunckfdf2
+  %1 = fptrunc fp128 %a to double
+  ret double %1
+}
+
+define i32 @fixkfsi(fp128 %a) {
+; CHECK-LABEL: fixkfsi:
+; CHECK: __fixkfsi
+  %1 = fptosi fp128 %a to i32
+  ret i32 %1
+}
+
+define i64 @fixkfdi(fp128 %a) {
+; CHECK-LABEL: fixkfdi:
+; CHECK: __fixkfdi
+  %1 = fptosi fp128 %a to i64
+  ret i64 %1
+}
+
+define i32 @fixunskfsi(fp128 %a) {
+; CHECK-LABEL: fixunskfsi:
+; CHECK: __fixunskfsi
+  %1 = fptoui fp128 %a to i32
+  ret i32 %1
+}
+
+define i64 @fixunskfdi(fp128 %a) {
+; CHECK-LABEL: fixunskfdi:
+; CHECK: __fixunskfdi
+  %1 = fptoui fp128 %a to i64
+  ret i64 %1
+}
+
+define fp128 @floatsikf(i32 %a) {
+; CHECK-LABEL: floatsikf:
+; CHECK: __floatsikf
+  %1 = sitofp i32 %a to fp128
+  ret fp128 %1
+}
+
+define fp128 @floatdikf(i64 %a) {
+; CHECK-LABEL: floatdikf:
+; CHECK: __floatdikf
+  %1 = sitofp i64 %a to fp128
+  ret fp128 %1
+}
+
+define fp128 @floatunsikf(i32 %a) {
+; CHECK-LABEL: floatunsikf:
+; CHECK: __floatunsikf
+  %1 = uitofp i32 %a to fp128
+  ret fp128 %1
+}
+
+define fp128 @floatundikf(i64 %a) {
+; CHECK-LABEL: floatundikf:
+; CHECK: __floatundikf
+  %1 = uitofp i64 %a to fp128
+  ret fp128 %1
+}
+
+define i1 @test_eqkf2(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_eqkf2:
+; CHECK: __eqkf2
+  %1 = fcmp oeq fp128 %a, %b
+  ret i1 %1
+}
+
+define i1 @test_nekf2(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_nekf2:
+; CHECK: __nekf2
+  %1 = fcmp une fp128 %a, %b
+  ret i1 %1
+}
+
+define i1 @test_gekf2(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_gekf2:
+; CHECK: __gekf2
+  %1 = fcmp oge fp128 %a, %b
+  ret i1 %1
+}
+
+define i1 @test_ltkf2(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_ltkf2:
+; CHECK: __ltkf2
+  %1 = fcmp olt fp128 %a, %b
+  ret i1 %1
+}
+
+define i1 @test_lekf2(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_lekf2:
+; CHECK: __lekf2
+  %1 = fcmp ole fp128 %a, %b
+  ret i1 %1
+}
+
+define i1 @test_gtkf2(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_gtkf2:
+; CHECK: __gtkf2
+  %1 = fcmp ogt fp128 %a, %b
+  ret i1 %1
+}
+
+define i1 @test_unordkf2(fp128 %a, fp128 %b) {
+; CHECK-LABEL: test_unordkf2:
+; CHECK: __unordkf2
+  %1 = fcmp uno fp128 %a, %b
+  ret i1 %1
+}




More information about the llvm-commits mailing list