0

I am using GCC version 4.2.4. The issue explained below can't be reproduced on Gcc 4.6.x and these are the only two versions I tested.

I have an header file that defines enumerations, Header: abc.h

enum test
{
    VALUE_1 = 1,
    VALUE_2 = 2,

    VALUE_MAX = 0xFFFF,
};

This header is included in a few source files and each source file creates an object (.o) at compilation time. And there are few source file that don't reference to any of the enumerations in abc.h.

The issue I am seeing is that if I add a new constant (VALUE_3) in abc.h, then the binary md5sum of the objects that don't use any enumerations also gets changes. This only happen when i apply optimizaions and not otherwise at compilation.

I suspect that it has something to do with flags -ftree-vrp and -ftree-dominator-opts that gets enabled with optimizations. using these flags with -fno still cause some of the objects to change but prevents other few from changing (that gets changes with these flags).

Another interesting obsevation is that the md5sum comes out to be same for even or odd number of enumerations.

Can anyone please help me understand that what's going on in the back end and is there any way to avoid binary change to maintain md5sum when there is no actual code change for that specific object.

Thanks in advance.

Edited:

For one object, following is the diff. For other objects there are few other changes as well (in mov etc instructions) . As you can see only the operand registers in some instructions are swapped. I want to understand the reason and how to avoid it with optimizations.

# diff test.o.1 test.o.2
1548,1549c1548,1549
<     cmpl    %eax, %ecx
<     jg      .L442
---
>     cmpl    %ecx, %eax
>     jl      .L442
Akamai
  • 117
  • 1
  • 11
  • 2
    Simply stating that the MD5 hash changes is insufficient. If you care to this level, you should use `objdump -d` and friends to determine what *actually* changed in the .o files. – Jonathon Reinhart Apr 16 '14 at 15:20
  • Thanks Jonathon. Question description has been edited. – Akamai Apr 16 '14 at 15:38
  • Question description edited. – Akamai Apr 16 '14 at 15:41
  • 1
    The two pairs of instructions are semantically identical. I cannot identify exactly why the compiler chose one over the other. I suspect it may have to do with branch prediction, and it may be using the presence of other possible (higher/lower) enum values as a heuristic, when determining which way to "hint" the branch to the processor. – Jonathon Reinhart Apr 16 '14 at 15:48
  • I guess the real question is, why do you care? – Jonathon Reinhart Apr 16 '14 at 15:52
  • i need to maintain binary comparability wrt md5sum. Changing a enum in header file and it causing the md5sum of an object which is not referencing it doesn't make much sense to me. I am trying to avoid that so that my md5sum remains same which is my requirement. – Akamai Apr 16 '14 at 16:16
  • You're changing the source code and recompiling the object file. You can't possibly expect the object file to come out identical every time. – Jonathon Reinhart Apr 16 '14 at 16:52
  • No, its not the source code change for that object. The rational is that this is not the case when compiled with gcc-4.6. It is some feature in 4.2 only causing this effect. I am sure that nothing is changed for that object. – Akamai Apr 16 '14 at 16:54

1 Answers1

1

is there any way to avoid binary change

To check Jonathon Reinhart's suspicion "it may have to do with branch prediction", you could try the option -fno-guess-branch-probability.

Armali
  • 18,255
  • 14
  • 57
  • 171