Community
cancel
Showing results for 
Search instead for 
Did you mean: 
SomeScientist
Beginner
58 Views

Compiler bug?

I am a PhD student and am working at classification of code fragments on a binary level. For that, I used the Intel compiler to compile several open source projects. While analyzing the code, I stumbled upon an interesting code snippet I cannot find another explanation than a potential bug.

It resides inside the function exp_J, which is called by exp. The disassembled code is a bit lengthy, so I will only highlight the main point of interest. There is one basic block that has an in-degree of zero. This should only happen on very specific occasions, such as exception handling. The respective code is

cmp ecx, 80000000h <-- this basic block is never executed
jb short loc_80A0CD2
cmp ecx, 0C086232Bh
jb loc_80A0DCB
ja short loc_80A0CD9
mov edx, [esp+80h]
cmp edx, 0FEFA39EFh
jb loc_80A0DCB
jmp short loc_80A0CD9


I would be happy for any response regarding this matter. 

0 Kudos
5 Replies
TimP
Black Belt
58 Views

Without optimization, dead code branches are to be expected. I don't know which combination of optimizations is likely to be most effective at eliminating them.  In the long distant past, some compilers had ability to report self-detection of dead code, but this proved unpopular.

In this case, apparently you are examining run-time library functions which may have been written at a low enough level (intrinsics, asm?) that the compiler might be less likely than otherwise to work them out.  It's also possible that your linked call sequence doesn't call an entry point which might be used in some other build.

 

Kittur_G_Intel
Employee
58 Views

BTW, compiling with -ipo (inter procedural optimization) helps detect and eliminate dead code as well which you can try?

_Kittur

Kittur_G_Intel
Employee
58 Views

Also, if you can attach a small reproducer I can file the issue with the developers to investigate as well, thanks.

_Kittur

jimdempseyatthecove
Black Belt
58 Views

The bug is likely not that of the compiler (assuming dead code elimination not enabled as per Tim's response).

Rather the bug likely resides with the programmer's source code containing bad code for the target platform. Examples:

if(j >= LowestNegativeNumber) { ...} // stupid statement (you can't fix stupid)

// program taken from 64-bit platform and ported to 32-bit platform
if(j >= 0x80000000) {...} // works when j is int64_t

Note, the "dead code" was the "test and branch" for impossible condition (branch never taken)

Did Sebastian receive a warning (assuming appropriate warning option specified)?

Jim Dempsey

SomeScientist
Beginner
58 Views

Thank you very much for your answers. I found some time to look further into the issue. For that, I wrote the following test program (actually, I made my research assistant do the work ;-) ):

 

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{

   if(argc < 2) {
      printf("argument for exp() is needed\n");
      printf("call %s <the xth power>\n", *argv);
      return EXIT_FAILURE;
   }

   double power = atof(argv[1]);
   double result = exp(power);

   printf("The exponential value of %lf is %lf\n", power, result);

   return EXIT_SUCCESS;
}

"We" compiled the code with "-O1 -g". Here, we could further pinpoint the original error. The culprit is found in libimf.a. If you extract it, you can find the file exp_wmt.o, having the public function exp.J (exp_J). I'll post again some instructions of the erroneous basic block:

.text:080001C2 jmp     loc_80002EB
.text:080001C7 ; ---------------------------------------------------------------------------
.text:080001C7 cmp     ecx, 80000000h <-- never executed
.text:080001CD jb      short loc_80001F2
.text:080001CF cmp     ecx, 0C086232Bh

As the code resides in a static library, I doubt it is subject to further compiler optimizations. I still think this is a bug.

Reply