For C experts

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

For C experts

Post by michiguel »

Under the promotion rules a C compiler may end up producing the same assembler code for all these three versions (ignoring weird optimizations).
Correct?

Code: Select all

A)

double x;
if (x > 0) {
    /* code here */
}

Code: Select all

B)

double x;
if (x > 0.0) {
    /* code here */
}

Code: Select all

C)

int x;
if (x > 0.0) {
    /* code here */
}
Miguel
wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 5:03 pm
Location: British Columbia, Canada

Re: For C experts

Post by wgarvin »

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.

See section 6.5.4 (Relational Operators) on this page, for example.

[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.]
User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

Re: For C experts

Post by michiguel »

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.

See section 6.5.4 (Relational Operators) on this page, for example.

[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
UncombedCoconut
Posts: 319
Joined: Fri Dec 18, 2009 11:40 am
Location: Naperville, IL

Re: For C experts

Post by UncombedCoconut »

Well, that's a different matter entirely!
The logical snippet to write in this context, if your time management variables are integers, is

Code: Select all

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.
wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 5:03 pm
Location: British Columbia, Canada

Re: For C experts

Post by wgarvin »

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.
User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

Re: For C experts

Post by michiguel »

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

Code: Select all

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
UncombedCoconut
Posts: 319
Joined: Fri Dec 18, 2009 11:40 am
Location: Naperville, IL

Re: For C experts

Post by UncombedCoconut »

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.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: For C experts

Post by bob »

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?

Code: Select all

A)

double x;
if (x > 0) {
    /* code here */
}

Code: Select all

B)

double x;
if (x > 0.0) {
    /* code here */
}

Code: Select all

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.)
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: For C experts

Post by bob »

michiguel wrote:
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.

See section 6.5.4 (Relational Operators) on this page, for example.

[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).
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: For C experts

Post by bob »

michiguel wrote:
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

Code: Select all

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).