[llvm-dev] Problem with __builtin_object_size when it depends on a condition

Strahinja Petrovic via llvm-dev llvm-dev at lists.llvm.org
Wed Mar 16 09:39:15 PDT 2016


Optimizer doesn't know how to calculate the object size when it finds 
condition that cannot be eliminated. There is example:

-----------------------------------------------
#include<stdlib.h>
#define STATIC_BUF_SIZE 10
#define LARGER_BUF_SIZE 30

size_t foo(int flag) {
   char *cptr;
   char chararray[LARGER_BUF_SIZE];
   char chararray2[STATIC_BUF_SIZE];
   if(flag)
     cptr = chararray2;
    else
     cptr = chararray;

   return  __builtin_object_size(cptr, 2);
}

int main() {
   size_t ret;
   ret = foo(0);
   printf("\n%d\n", ret);
   return 0;
}
----------------------------------------------
  If you try to compile this example with clang (trunk version) with 
option -fno-inline the result will be -1. Without option -fno-inline 
result will be correct (30). When foo function is inlined into main, 
condition is eliminated and compiler knows to calculate correct object 
size. Compiler should be able to calculate object size in both cases 
(with/without inlining foo function). In case when condition can't be 
eliminated compiler should calculate object size depending on second 
argument of __builtin_object_size function (taking minimum or maximum 
value from condition). In this example, the result should be 10 with 
-fno-inline.

  If I replace the llvm.objectsize with the constant in foo() depending 
on the second argument, the result will be correct with -fno-inline 
(10), but incorrect without the flag. This is because foo() is inlined, 
the condition can be eliminated, and the result should be 30.

  I resolved this problem by adding third argument in llvm.objectsize 
intrinsic. When I calculate the result based on condition, I put it in 
the third argument. If there is no inlining, condition will not get 
eliminated, and this will be the final result. When there is inlining, 
condition will be  eliminated after inlining and the llvm.objectsize 
will be replaced with a constant.
  With this approach, I get the correct result in both cases (with and 
without -fno-inline).

  I would like to have a discussion about this approach because I am 
changing the IR (because of adding third argument to 
__builtin_object_size function). Do you have some comments ?



More information about the llvm-dev mailing list