Skip to content
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

Convert double to ConstantFP #122851

Open
tianboh opened this issue Jan 14, 2025 · 4 comments
Open

Convert double to ConstantFP #122851

tianboh opened this issue Jan 14, 2025 · 4 comments
Labels
floating-point Floating-point math question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

Comments

@tianboh
Copy link

tianboh commented Jan 14, 2025

I want to generate ConstantFP using C++ double. For some reasons, the double is obtained in runtime, and it may not suits “simple constant value”

/// This returns a ConstantFP, or a vector containing a splat of a ConstantFP,
/// for the specified value in the specified type. This should only be used
/// for simple constant values like 2.0/1.0 etc, that are known-valid both as
/// host double and as the target format.
static Constant *get(Type *Ty, double V);

For example, i have a double 233.33, in runtime, the IEEE 754 representation is 0x406D2A8F60000000, if I print it, it is 233.33000183105469. Check IEEE 754 calculator for fun. I know floating point is not continuous, so some values may not have exact representation in IEEE 754 standard. They are encoded to nearest valid doubles instead.

I want to keep some fractional part, so rounding is not enough. But by sacrificing some precision, can I convert my double to ConstantFP?

@topperc
Copy link
Collaborator

topperc commented Jan 14, 2025

You can use it if the Type* is DoubleTy or larger. If you were to use HalfTy or FloatTy, you would lose more bits.

It's a bit weird for a compiler to create a constant like that that's an arbitrary value that didn't appear in the source. I think that's the primary reason for that comment. A compiler might turn A+A into A*2.0 where it would need to create the 2.0 constant that didn't exist.

@tianboh
Copy link
Author

tianboh commented Jan 14, 2025

Thank you for your suggestion 😄! I tried following snippet

double t = foo(); // foo returns 233.33000183105469
Value *Ret = ConstantFP::get(Type::getDoubleTy(Ctx), t);

When I dump Ret, i get

(gdb) p Ret->dump()
float 0x406D2A8F60000000
$2 = void

From what I understand, this hex value is IEEE 754 standard representation for 233.33000183105469. This is semantic correct, but I want this Ret to be a simple simple float(like 233.33), instead of this hex representation. I tried to manipulate t before feeding it to ConstantFP::get()(like (long long)(t * 100)/100.0), but the manipulated values is also not simple constant either.

Any ideas 🤔 ?

@topperc
Copy link
Collaborator

topperc commented Jan 14, 2025

Thank you for your suggestion 😄! I tried following snippet

double t = foo(); // foo returns 233.33000183105469
Value *Ret = ConstantFP::get(Type::getDoubleTy(Ctx), t);

When I dump Ret, i get

(gdb) p Ret->dump()
float 0x406D2A8F60000000
$2 = void

From what I understand, this hex value is IEEE 754 standard representation for 233.33000183105469. This is semantic correct, but I want this Ret to be a simple simple float(like 233.33), instead of this hex representation. I tried to manipulate t before feeding it to ConstantFP::get()(like (long long)(t * 100)/100.0), but the manipulated values is also not simple constant either.

Any ideas 🤔 ?

ConstantFP internally stores its data using APFloat which uses a similar to sign, exponent, mantissa scheme like IEEE. 233.33 can't be represented exactly. The dump function is going to print it very similar to printf on a double.

@dtcxzyw dtcxzyw added question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead! and removed new issue labels Jan 14, 2025
@tianboh
Copy link
Author

tianboh commented Jan 14, 2025

ConstantFP internally stores its data using APFloat which uses a similar to sign, exponent, mantissa scheme like IEEE. 233.33 can't be represented exactly. The dump function is going to print it very similar to printf on a double.

Thank you for clarification. I checked APFloat API, and it is very helpful. I can generate a APFloat using my weird double, and if I dump it, it looks fine. However, when I use this APFloat to generate ConstantFP, it dumps the hex representation again.

double d = foo(); // foo returns 233.33000183105469
APFloat t(d);
t.dump()
Value *Ret = ConstantFP::get(Type::getDoubleTy(Ctx), t);
Ret->dump();

This outputs

233.33000183105469
double 0x406D2A8F60000000

It seems there is still a gap/mismatch between APFloat and ConstantFP. I notice that APFloat has fltSemantics, which indicates underlying encoding semantics. I am sure the underlying encoding of 0x406D2A8F60000000 is IEEE 754 double, can I use this information to cast my APFloat to ConstantFP correctly? Or even further, can i just use this hex generate a legal ConstantFP?

@frederick-vs-ja frederick-vs-ja added the floating-point Floating-point math label Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
floating-point Floating-point math question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!
Projects
None yet
Development

No branches or pull requests

5 participants