# [LLVMdev] question on constant folding

Nick Lewycky nicholas at mxc.ca
Tue Jun 10 22:54:04 PDT 2008

```It's not about constant folding. The optimizing part of this is
"Canonicalize Induction Variables", which as with all of LLVM's loop
optimizations, work on integers only.

The reason is that float point math is very difficult to model. You can
not, for example, transform this:

double sum = 0;
for (unsigned i = 0; i < j; ++i)
my_double += 0.00001;

into:

my_double = 0.00001 * j;

because the addition in floating point math may not actually change the
value. Consider 1000000 + 0.0000001. A float doesn't have enough
precision, so the result will equal 1000000, making the result of the
loop entirely different than if you were to rewrite it with multiplication.

If you're interested in tackling this, the core loop analysis that needs
to learn how floats work is "Scalar Evolution Analysis" in
lib/Analysis/ScalarEvolution.cpp.

Nick

Seung Jae Lee wrote:
> Hello, LLVMers.
>
> I have a quick question for constant folding.
> When I treated a code twice by changing the data type from 'floating point' to 'integer,'
> What I found was:
> optimization is done better for the code having int's.
> E.g.,  for this simple code:
> -------------------------------------------------------------
> double foo() {
>
>   double i,j;
>   double sum = 0;
>   for (i=0; i<100; i++) {
>     sum +=  i;
>     for (j=0; j<100; j++)
>       sum += 2;
>   }
>
>   return sum;
> }
> -------------------------------------------------------------
>
> \$llvm-gcc -O4 -emit-llvm foo.c  -c -o foo.bc
> \$opt -std-compile-opts -reg2mem foo.bc -o foo_optimized.bc
>
> gave me a really long LLVM IR code with many basic blocks..
>
> However, when I just changed the types to 'long' as follows:
> -------------------------------------------------------------
> long foo() {
>
>   long i,j;
>   long sum = 0;
>   for (i=0; i<100; i++)
>   {
>     sum +=  i;
>     for (j=0; j<100; j++)
>       sum += 2;
>   }
>
>   return sum;
> }
> -------------------------------------------------------------
>
> This code simply gave me:
> -------------------------------------------------------------
> define i32 @foo() nounwind  {
>         %"reg2mem alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
>         ret i32 24950
> }
> -------------------------------------------------------------
>
> Could you anybody tell me why interger type code shows the better performance in constant folding with LLVM?
>