[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