[LLVMdev] Related constant folding of floating point values

Mark Lacey mark.lacey at apple.com
Wed Oct 9 07:43:04 PDT 2013


Hi Arsen,

On Oct 9, 2013, at 4:53 AM, Arsen Hakobyan <artinetstudio at gmail.com> wrote:

> Hi all,
> 
> I have the following test case:
> #define FLT_EPSILON   1.19209290E-7 
> 
> int err = -1;
> int main()
> {
> float a = 8.1;
> if (((a - 8.1) >= FLT_EPSILON) || ((a - 8.1) <= -FLT_EPSILON)) {    //I am
> using FLT_EPSILON to check whether (a != 2.0).

It’s not clear what this comment refers to, but it doesn’t seem to be related to this code.

>    err = 1;
>  } else {
>    err = 0;
>  }
>  return 0;
> }
> 
> with -O3 optimization level clang generates already incorrect LLVM IR:
> ; Function Attrs: nounwind uwtable
> define i32 @main() #0 {
> entry:
>  store i32 1, i32* @err, align 4, !tbaa !0
>  ret i32 0
> }
> 
> BUT if I change the value of the variable 'a' to be '7.1'. then a correct IR 
> is generated:
> ...
> entry:
>  store i32 0, i32* @err, align 4, !tbaa !0
>  ret i32 0
> ...
> 
> 
> I have already investigated the issue and found that during the EarlyCSE
> transformation it seems replaces the FPExt instruction with an incorrect
> hexadecimal value:
> The LLVM IR generated with O0 opt. level is:
> ...
>  store float 0x4020333340000000, float* %a, align 4
>  %0 = load float* %a, align 4
>  %conv = fpext float %0 to double
>  %sub = fsub double %conv, 8.100000e+00
>  %cmp = fcmp oge double %sub, 0x3E8000000102F4FD
>  br i1 %cmp, label %if.then, label %lor.lhs.false
> 
> lor.lhs.false:                                    ; preds = %entry
>  %1 = load float* %a, align 4
>  %conv2 = fpext float %1 to double
>  %sub3 = fsub double %conv2, 8.100000e+00
>  %cmp4 = fcmp ole double %sub3, 0xBE8000000102F4FD
>  br i1 %cmp4, label %if.then, label %if.else
> ...
> 
> during the transformation the %conv is replaced with "double
> 0x4020333340000000" and then the result of comparison is resolved
> incorrectly. 
> 
> Is not this a bug?

No. The issue is that you are taking a double (8.1), converting it to float, and then subtracting the original double from it. The rounding error introduced from the conversion is larger than the epsilon value that you are comparing to, so the first comparison (a-8.1 >= FLT_EPSILON) is always true.

Mark

> I have also searched for a similar issue in llvm bug list, but could not
> found anything.
> 
> Thank you,
> Arsen
> 
> 
> 
> --
> View this message in context: http://llvm.1065342.n5.nabble.com/Related-constant-folding-of-floating-point-values-tp61897.html
> Sent from the LLVM - Dev mailing list archive at Nabble.com.
> _______________________________________________
> 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