[llvm] [llvm-c] Create a 128 bit floating point constant from 2 64 bit values (PR #164381)

peter mckinna via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 2 18:33:18 PST 2025


https://github.com/demoitem updated https://github.com/llvm/llvm-project/pull/164381

>From 624b310dc7325933e197e7b0218e9b353328d1a7 Mon Sep 17 00:00:00 2001
From: peter mckinna <peter.mckinna at gmail.com>
Date: Tue, 21 Oct 2025 20:31:25 +1100
Subject: [PATCH 1/4] Create a 128 bit floating point constant from 2 64 bit
 values

---
 llvm/include/llvm-c/Core.h | 7 +++++++
 llvm/lib/IR/Core.cpp       | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 4e380d9bd5969..c2f68ce2219ba 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2339,6 +2339,13 @@ LLVM_C_ABI LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy,
                                                      const char *Text,
                                                      unsigned SLen);
 
+/**
+ * Obtain a constant for a floating point FP128 value from 2 64 bit values.
+ * (112 bit mantissa)
+ */
+
+LLVMValueRef LLVMConstFP128(LLVMContextRef C, const uint64_t N[2]);
+
 /**
  * Obtain the zero extended value for an integer constant value.
  *
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 27d8294b01264..6246880f0bec4 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1573,6 +1573,13 @@ LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[],
   return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Str, SLen)));
 }
 
+LLVMValueRef LLVMConstFP128(LLVMContextRef C, const uint64_t N[2]) {
+  Type *Ty = Type::getFP128Ty(*unwrap(C));
+  APInt AI(128, ArrayRef<uint64_t>(N, 2));
+  APFloat Quad(APFloat::IEEEquad(), AI);
+  return wrap(ConstantFP::get(Ty, Quad));
+}
+
 unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal) {
   return unwrap<ConstantInt>(ConstantVal)->getZExtValue();
 }

>From 18e65e20690ce64321a9e7c3b90027534c599eee Mon Sep 17 00:00:00 2001
From: peter mckinna <peter.mckinna at gmail.com>
Date: Thu, 23 Oct 2025 09:37:00 +1100
Subject: [PATCH 2/4] Update after review. Extend the function to accept the
 two 128 bit float types and add a testcase

---
 llvm/include/llvm-c/Core.h          |  4 ++--
 llvm/lib/IR/Core.cpp                |  9 +++++----
 llvm/unittests/IR/ConstantsTest.cpp | 14 ++++++++++++++
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index c2f68ce2219ba..ba7cc56aec6c9 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2341,10 +2341,10 @@ LLVM_C_ABI LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy,
 
 /**
  * Obtain a constant for a floating point FP128 value from 2 64 bit values.
- * (112 bit mantissa)
+ * Only the LLVMFP128Type or LLVMPPCFP128Type are accepted. 
  */
 
-LLVMValueRef LLVMConstFP128(LLVMContextRef C, const uint64_t N[2]);
+LLVM_C_ABI LLVMValueRef LLVMConstFP128(LLVMTypeRef Ty, const uint64_t N[2]);
 
 /**
  * Obtain the zero extended value for an integer constant value.
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 6246880f0bec4..da24306d6e263 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1573,11 +1573,12 @@ LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[],
   return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Str, SLen)));
 }
 
-LLVMValueRef LLVMConstFP128(LLVMContextRef C, const uint64_t N[2]) {
-  Type *Ty = Type::getFP128Ty(*unwrap(C));
+LLVMValueRef LLVMConstFP128(LLVMTypeRef Ty, const uint64_t N[2]) {
+  Type *T = unwrap(Ty);
+  assert(T->getPrimitiveSizeInBits() == 128 && "Ty size should be 128");
   APInt AI(128, ArrayRef<uint64_t>(N, 2));
-  APFloat Quad(APFloat::IEEEquad(), AI);
-  return wrap(ConstantFP::get(Ty, Quad));
+  APFloat Quad(T->getFltSemantics(), AI);
+  return wrap(ConstantFP::get(T, Quad));
 }
 
 unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal) {
diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp
index 6376165cbe766..4fb847de228cc 100644
--- a/llvm/unittests/IR/ConstantsTest.cpp
+++ b/llvm/unittests/IR/ConstantsTest.cpp
@@ -835,5 +835,19 @@ TEST(ConstantsTest, BlockAddressCAPITest) {
   EXPECT_EQ(&BB, OutBB);
 }
 
+TEST(ConstantsTest, Float128Test) {
+  LLVMTypeRef Ty128 = LLVMFP128TypeInContext(LLVMGetGlobalContext());
+  LLVMTypeRef TyPPC128 = LLVMPPCFP128TypeInContext(LLVMGetGlobalContext());
+  LLVMBuilderRef Builder = LLVMCreateBuilder();
+  uint64_t n[2] = {0x4000000000000000, 0x0}; //+2
+  uint64_t m[2] = {0xC000000000000000, 0x0}; //-2
+  LLVMValueRef val1 = LLVMConstFP128(Ty128, n);
+  LLVMValueRef val2 = LLVMConstFP128(Ty128, m);
+  LLVMValueRef val3 = LLVMBuildFAdd(Builder, val1, val2, "test");
+  EXPECT_TRUE(val3 != nullptr);
+  LLVMValueRef val4 = LLVMConstFP128(TyPPC128, n);
+  EXPECT_TRUE(val4 != nullptr);
+}
+
 } // end anonymous namespace
 } // end namespace llvm

>From 07e834c8ae92dc1abcbce916b8c909eab92d8e5b Mon Sep 17 00:00:00 2001
From: peter mckinna <peter.mckinna at gmail.com>
Date: Thu, 23 Oct 2025 09:57:40 +1100
Subject: [PATCH 3/4] Fix formatting

---
 llvm/include/llvm-c/Core.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index ba7cc56aec6c9..52bb03a605999 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2341,7 +2341,7 @@ LLVM_C_ABI LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy,
 
 /**
  * Obtain a constant for a floating point FP128 value from 2 64 bit values.
- * Only the LLVMFP128Type or LLVMPPCFP128Type are accepted. 
+ * Only the LLVMFP128Type or LLVMPPCFP128Type are accepted.
  */
 
 LLVM_C_ABI LLVMValueRef LLVMConstFP128(LLVMTypeRef Ty, const uint64_t N[2]);

>From c1c5d61634c0c58c79e1d66b5bfc660744090c90 Mon Sep 17 00:00:00 2001
From: peter mckinna <peter.mckinna at gmail.com>
Date: Mon, 3 Nov 2025 13:31:23 +1100
Subject: [PATCH 4/4] Further changes per review

---
 llvm/lib/IR/Core.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index da24306d6e263..de00a4f9c2a39 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1575,8 +1575,9 @@ LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[],
 
 LLVMValueRef LLVMConstFP128(LLVMTypeRef Ty, const uint64_t N[2]) {
   Type *T = unwrap(Ty);
-  assert(T->getPrimitiveSizeInBits() == 128 && "Ty size should be 128");
-  APInt AI(128, ArrayRef<uint64_t>(N, 2));
+  unsigned SB = T->getScalarSizeInBits();
+  assert(SB == 128 && "Ty size should be 128");
+  APInt AI(SB, ArrayRef<uint64_t>(N, divideCeil(SB, 64)));
   APFloat Quad(T->getFltSemantics(), AI);
   return wrap(ConstantFP::get(T, Quad));
 }



More information about the llvm-commits mailing list