-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[llvm-c] Create a 128 bit floating point constant from 2 64 bit values #164381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-llvm-ir Author: peter mckinna (demoitem) ChangesThis change adds the ability to create a 128 bit floating point value from 2 64 bit integer values. Full diff: https://github.com/llvm/llvm-project/pull/164381.diff 2 Files Affected:
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();
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs tests.
I also think it would make more sense to make this a generic bitwise initializer for FP constants, rather than specific to fp128. That will also work for things like ppc_fp128, and generally to more reliably create specific FP values, even if they're special. (Like, I wouldn't expect the API taking a double to reliably create an sNaN with a specific payload.)
|
I'm not sure where to place these tests, ie Core.cpp tests in general. I agree a generic initializer would make more sense but that kind of C++ expertise is a bit beyond me I'm afraid. |
In this case probably https://github.com/llvm/llvm-project/blob/main/llvm/unittests/IR/ConstantsTest.cpp.
I think it would look similar to what you have now, but accept the type as an argument and call |
llvm/include/llvm-c/Core.h
Outdated
|
|
||
| /** | ||
| * Obtain a constant for a floating point FP128 value from 2 64 bit values. | ||
| * (112 bit mantissa) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation should probably state the endianness of the values.
types and add a testcase
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
|
I have changed the function to what I think you have in mind. And added a testcase. It only really |
|
ping |
llvm/lib/IR/Core.cpp
Outdated
|
|
||
| LLVMValueRef LLVMConstFP128(LLVMTypeRef Ty, const uint64_t N[2]) { | ||
| Type *T = unwrap(Ty); | ||
| assert(T->getPrimitiveSizeInBits() == 128 && "Ty size should be 128"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| assert(T->getPrimitiveSizeInBits() == 128 && "Ty size should be 128"); | |
| assert(T->getScalarSizeInBits() == 128 && "Ty size should be 128"); |
To allow vector of float.
llvm/lib/IR/Core.cpp
Outdated
| 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)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than hardcoding 128 here, we can use the size of the float (e.g. via getScalarSizeInBits). The corresponding size of the array would be divideCeil(SizeInBits, 64). Then this would work for all sizes of floats.
|
Changed the function as per your comments. Any other tweaks? |
This change adds the ability to create a 128 bit floating point value from 2 64 bit integer values.
Some language frontends have already parsed a floating point string into a proper 128 bit quad value
and need to get the llvm value directly.