Under the promotion rules a C compiler may end up producing the same assembler code for all these three versions (ignoring weird optimizations).
Correct?
Yes. The magic phrase to google for about this is "usual arithmetic conversions" which describes the implicit conversions the compiler will do to the arguments of a binary operator before applying the operator.
[Edit: I assumed you meant the assembly for the comparison part... the memory load and conversion of "int x" versus "float x" might be different if the compiler doesn't completely optimize it away. But in all cases the comparison is between two doubles.]
wgarvin wrote:Yes. The magic phrase to google for about this is "usual arithmetic conversions" which describes the implicit conversions the compiler will do to the arguments of a binary operator before applying the operator.
[Edit: I assumed you meant the assembly for the comparison part... the memory load and conversion of "int x" versus "float x" might be different if the compiler doesn't completely optimize it away. But in all cases the comparison is between two doubles.]
Because in the document in which is shown how Rybka 1.0 was disassembled, it was inferred that the R1 code had a snippet like "C". Then, in the context, it looks weird that a comparison was done to 0.0. Explicitly, it is said that it only made sense when you looked at Fruit code that had a similar comparison to 0.0 (it made sense there). So, it is inferred that this was a sloppy cut, paste and modification and the 0.0 remained.
This is the danger of this type of techniques in which the answer is degenerate (several options possible). You find what you are looking for. The whole point is valid if the source code is actually "C", but we do not know what the source code is. It could actually be like "A". In that case the compiler (following the C rules) may place the 0.0 there and the whole point is invalid.
D)
int x;
if (x > 0) {
/* code here */
}
This would never generate assembly instructions to do a floating point compare. So, assuming the assembly is the way BB+ said it is, it is strange. Proof of copying? Absolutely not. But it would deserve consideration as part of a big picture, and is not completely meaningless either.
If you start with the assembly instructions, I think you could tell whether the source snippet was like C (with int x) or like the other two (with double x). Snippet C would generate an instruction to convert x from int to double somewhere between the load and the comparison. The other two snippets would not.
UncombedCoconut wrote:Well, that's a different matter entirely!
The logical snippet to write in this context, if your time management variables are integers, is
D)
int x;
if (x > 0) {
/* code here */
}
This would never generate assembly instructions to do a floating point compare. So, assuming the assembly is the way BB+ said it is, it is strange. Proof of copying? Absolutely not. But it would deserve consideration as part of a big picture, and is not completely meaningless either.
michiguel wrote:Why do you we have to assume x is an integer?
Miguel
In his report, BB+ said the time management code of Rybka is integer-based. The declaration type is easy to infer from the full assembler code, because in time management code you perform arithmetic -- which will show up unmistakably in assembly as either integer or floating-point operations. What the author is saying is that these operations are integer in general -- but in part of the code he saw instructions to convert the integer to floating-point, and then make a comparison.
michiguel wrote:Under the promotion rules a C compiler may end up producing the same assembler code for all these three versions (ignoring weird optimizations).
Correct?
C)
int x;
if (x > 0.0) {
/* code here */
}
Miguel
I would not think "exact." For example, you would use an fild instruction to get the integer value on the FP stack, while you would use fld to load a normal real value.
Or the last one could be done in integer entirely which would look a lot different (if you understand how to use the floating point compare stuff.)
wgarvin wrote:Yes. The magic phrase to google for about this is "usual arithmetic conversions" which describes the implicit conversions the compiler will do to the arguments of a binary operator before applying the operator.
[Edit: I assumed you meant the assembly for the comparison part... the memory load and conversion of "int x" versus "float x" might be different if the compiler doesn't completely optimize it away. But in all cases the comparison is between two doubles.]
Because in the document in which is shown how Rybka 1.0 was disassembled, it was inferred that the R1 code had a snippet like "C". Then, in the context, it looks weird that a comparison was done to 0.0. Explicitly, it is said that it only made sense when you looked at Fruit code that had a similar comparison to 0.0 (it made sense there). So, it is inferred that this was a sloppy cut, paste and modification and the 0.0 remained.
This is the danger of this type of techniques in which the answer is degenerate (several options possible). You find what you are looking for. The whole point is valid if the source code is actually "C", but we do not know what the source code is. It could actually be like "A". In that case the compiler (following the C rules) may place the 0.0 there and the whole point is invalid.
Miguel
You can most likely determine whether a float is compared to an int or not, because of the floating point instructions. "fi" vs "f" instructions in particular.
However, that is a miniscule issue in the great scheme of rybka vs fruit (and other programs also).
UncombedCoconut wrote:Well, that's a different matter entirely!
The logical snippet to write in this context, if your time management variables are integers, is
D)
int x;
if (x > 0) {
/* code here */
}
This would never generate assembly instructions to do a floating point compare. So, assuming the assembly is the way BB+ said it is, it is strange. Proof of copying? Absolutely not. But it would deserve consideration as part of a big picture, and is not completely meaningless either.
Why do you we have to assume x is an integer?
Miguel
You can certainly tell by the floating point instruction opcode. To load a float, you do a "fld" to get it on the stack. To load an int, you do a "fild" which lets the FP hardware do the conversion and put the converted value on the stack... And you can't use floating point constants in an instruction (fadd 1.0, for example).