[LLVMdev] Wrong float value stored in LLVM IR code

Daniel Sanders Daniel.Sanders at imgtec.com
Wed Jun 18 05:29:19 PDT 2014


Is the problem that the store and the fcmp have different single-precision constants to eachother, or is it that neither constant is what you expected?

If it's the latter, then the constants look correct to me. Hexadecimal floating point values in LLVM-IR are in double precision format for both single and double precision values. When used for a single-precision constant, the double-precision constant must be convertible to single-precision without rounding. See the paragraph starting 'The one non-intuitive notation ...' at http://llvm.org/docs/LangRef.html#simple-constants.

I'm not sure why the store and fcmp constants differ though. 3.141592 isn't exactly representable in single precision but I would have expected both constants to be rounded the same way. 

> -----Original Message-----
> From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu]
> On Behalf Of Adrian Ortega
> Sent: 18 June 2014 04:59
> To: llvmdev at cs.uiuc.edu
> Subject: [LLVMdev] Wrong float value stored in LLVM IR code
> 
> Hi everyone,
> 
> I'm learning how to use LLVM API and JIT engine and I've come across with an
> issue I haven't been able to figure out.
> 
> The problem I'm having is that the wrong float is being stored  in a float global
> variable.
> 
> The code snippet I use to generate the float value is as follow:
> 
>      llvm::Type* type = // initialize with the global variable type;
>      std::string real_value = // initialized with the float value from std input.
>      ...
>      return ConstantFP::get(type,real_value);
> 
> I am using the code snippet above to store a float and double value, the
> double value works, the float value not. This can be seen with the following
> LLVM IR I am generating:
> 
> What the functions do is just:
>   1. backup current value of global variable
>   2. store new value
>   3. call a C function which returns the value of the global variable in that same
> module
>   4. Compare against the value used in step 2
>   5. restore the initial value
>   6. return true or false if the values were equal.
> 
> /**
>    float gfloat = 3.141592;
> */
> define i32 @test_getgfloat_0() {
> block_test_getgfloat_0:
>    %0 = load float* @gfloat
>    store float 0x400921FB00000000, float* @gfloat // wrong value stored
>    %1 = call float @getgfloat()
>    %2 = fcmp oeq float %1, 0x400921FA00000000 // wrong value stored
>    %3 = zext i1 %2 to i32
>    store float %0, float* @gfloat
>    ret i32 %3
> }
> 
> /**
>    double gdouble = 2.52340;
>   */
> define i32 @test_getdouble_0() {
> block_test_getdouble_0:
>    %0 = load double* @gdouble
>    store double 2.523400e+00, double* @gdouble // correct value stored
>    %1 = call double @getdouble()
>    %2 = fcmp oeq double %1, 2.523400e+00 // correct value stored
>    %3 = zext i1 %2 to i32
>    store double %0, double* @gdouble
>    ret i32 %3
> }
> 
> Do you have any idea of why I'm having this problem?
> 
> Thank you.
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list