Looks like an optimizer bug. I wonder if it's trying to lift the if (c-(t*8) < 0) condition out of the loop and failing. Could you post the generated asm for the busted version?
Just for curiousity, I wonder what happens if you set "Bitmap b=1ULL;".
compiler dependent scores!
Moderator: Ras
-
- Posts: 568
- Joined: Tue Dec 12, 2006 10:10 am
- Full name: Gary Linscott
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: A complete and broken program
I ran this on a 32 bit machine using latest intel C++ compiler. I get this:jswaff wrote:A complete program demonstrating this problem is below. This problem occurs with Intel's compiler at -O2 (strangely this is working at -O1 where -O1 it didn't in Prophet). This is on a 32 bit machine (the original problem in Prophet was on a 64 bit machine).
With the printf commented out:With it in:Code: Select all
00000000 00000000 00000000 00001000 00000000 00000000 00000000 00000000
Code: Select all
considering: 1 considering: 2 considering: 3 considering: 4 considering: 5 00001000 00001000 00001000 00001000 00000000 00000000 00000000 00000000
Code: Select all
#include <stdio.h> enum SQUARES { A8,B8,C8,D8,E8,F8,G8,H8, A7,B7,C7,D7,E7,F7,G7,H7, A6,B6,C6,D6,E6,F6,G6,H6, A5,B5,C5,D5,E5,F5,G5,H5, A4,B4,C4,D4,E4,F4,G4,H4, A3,B3,C3,D3,E3,F3,G3,H3, A2,B2,C2,D2,E2,F2,G2,H2, A1,B1,C1,D1,E1,F1,G1,H1, NO_SQUARE }; typedef unsigned long long Bitmap; Bitmap bm_mask[64]; Bitmap to_boundary[64]; void DrawBitmap(Bitmap bmap) { for (int c=0;c<64;c++) { if (bmap&bm_mask[c]) printf("1"); else printf("0"); if ((c%8)==7) printf("\n"); } printf("\n"); } void Initialize() { Bitmap b=1; for (int c=0;c<64;c++) bm_mask[c]=(b<<c); for (int c=0;c<64;c++) { to_boundary[c]=0; for (int t=1;t<8;t++) { // if (c==E4) printf("considering: %d\n",t); if (c-(t*8)<0) break; to_boundary[c]|=bm_mask[c-(t*8)]; } } DrawBitmap(to_boundary[E4]); } int main(int argc,char *argv[]) { Initialize(); return 0; }
crafty% ./bug
00001000
00001000
00001000
00001000
00000000
00000000
00000000
00000000
crafty% ./bug
considering: 1
considering: 2
considering: 3
considering: 4
considering: 5
00001000
00001000
00001000
00001000
00000000
00000000
00000000
00000000
I will note that intel C does not like the for (int i=0; ...) type declaration, so I just declared c and t as int at the top of the procedure(s) where they are used. Seems to work as expected here with that one change... whether I use -O, -O2 or -O3 has no effect on the output...
you are not doing any overclocking or anything like that I assume???
Re: A complete and broken program
I actually compiled it as a C++ program, so the for (int c=0 ... is legal there.
But I just compiled it as a C program and it's the same problem.
And no, I'm not overclocking. Remember I've reproduced this on two machines, both using icc 10.0.026 on Gentoo Linux. (one 32 bit and the other 64 bit)
I'm going to dig into the assembly, but I don't have time to do it tonight.
--
James
But I just compiled it as a C program and it's the same problem.
And no, I'm not overclocking. Remember I've reproduced this on two machines, both using icc 10.0.026 on Gentoo Linux. (one 32 bit and the other 64 bit)
I'm going to dig into the assembly, but I don't have time to do it tonight.
--
James
Re: getting VERY weird
Michael Sherwin wrote:Have you verified that bm_mask[] is correct at the different levels of optimization?
Code: Select all
DrawBitmap(bm_mask[E5]);
DrawBitmap(bm_mask[E6]);
DrawBitmap(bm_mask[E7]);
DrawBitmap(bm_mask[E8]);
Code: Select all
00000000
00000000
00000000
00001000
00000000
00000000
00000000
00000000
00000000
00000000
00001000
00000000
00000000
00000000
00000000
00000000
00000000
00001000
00000000
00000000
00000000
00000000
00000000
00000000
00001000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
Re: getting VERY weird
I tried 1ULL, and it had no effect. I'll definitely look at the assembly, probably tomorrow. I'll post again after I've had a look at it. It's hard to see how this is not a compiler bug though.gladius wrote:Looks like an optimizer bug. I wonder if it's trying to lift the if (c-(t*8) < 0) condition out of the loop and failing. Could you post the generated asm for the busted version?
Just for curiousity, I wonder what happens if you set "Bitmap b=1ULL;".
--
James
-
- Posts: 2251
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: A complete and broken program
Just another try to avoid redundant repeat/break condition of the inner loop as a source of possible compiler confusion...jswaff wrote:Code: Select all
for (int c=0;c<64;c++) { to_boundary[c]=0; for (int t=1;t<8;t++) { // if (c==E4) printf("considering: %d\n",t); if (c-(t*8)<0) break; to_boundary[c]|=bm_mask[c-(t*8)]; } }
Code: Select all
for (int c=0; c<64; c++) {
to_boundary[c]=0;
for (int t=8; t <= c; t += 8) {
// if (c==E4) printf("considering: %d\n",t>>3);
to_boundary[c] |= bm_mask[c-t];
}
}
Re: A complete and broken program
Code: Select all
...
void Initialize() {
Bitmap b=1;
for (int c=0;c<64;c++)
bm_mask[c]=(b<<c);
for (int c=0;c<64;c++) {
to_boundary[c]=0;
for (int t=1;t<8;t++) {
if (!(c-(t*8)<0))
to_boundary[c]|=bm_mask[c-(t*8)];
}
}
DrawBitmap(to_boundary[E4]);
}
HJ.
Re: A complete and broken program
Yes, iirc it's the combination of declaring the same loop variable twice wich will cause the compiler to combine them and a break in one of them, wich the compiler doesn't notice and still combines.Harald Johnsen wrote:Don't do a break in the loop, the compiler does not execute the loop in the order you think (ie 1 to 8).Code: Select all
... void Initialize() { Bitmap b=1; for (int c=0;c<64;c++) bm_mask[c]=(b<<c); for (int c=0;c<64;c++) { to_boundary[c]=0; for (int t=1;t<8;t++) { if (!(c-(t*8)<0)) to_boundary[c]|=bm_mask[c-(t*8)]; } } DrawBitmap(to_boundary[E4]); }
HJ.
I had it in my initialisation code a bunch of
Code: Select all
for (int sq=0;(sq & 0x88)==0;sq++)
{
...
}
Tony
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: A complete and broken program
I am using 10.1.008 herejswaff wrote:I actually compiled it as a C++ program, so the for (int c=0 ... is legal there.
But I just compiled it as a C program and it's the same problem.
And no, I'm not overclocking. Remember I've reproduced this on two machines, both using icc 10.0.026 on Gentoo Linux. (one 32 bit and the other 64 bit)
I'm going to dig into the assembly, but I don't have time to do it tonight.
--
James
Re: A complete and broken program
Shouldn't it though? The for-loop SHOULD be a sequential construct. If the compiler is optimizing in a way that isn't sequentially consistent with the unoptimized version, then that's a bug.Harald Johnsen wrote: Don't do a break in the loop, the compiler does not execute the loop in the order you think (ie 1 to 8).
HJ.
--
James