madd@world.std.com (jim frost) (09/26/90)
P Asselin writes: >In article <384@nwnexus.WA.COM> golder@nwnexus.WA.COM (Warren Jones) writes: >> [ gives a short Fortran program that optimizes incorrectly ] >>Incidentally -- does anyone know if all the XL languages (including >>C and Pascal) use the same optimizer? Until I'm sure of the >>answer, I'm not using the C optimizer either. > >Well, I transliterated your example to C and got the same behaviour. > [code deleted] I tested further and found that `m' wasn't necessary (it also wasn't optimized out, strangely). `test' is necessary, although it *is* optimized out. `b' is necessary and is kept up-to-date although it isn't really used by the code. The resultant function (as minimal as I could get it) is: -- cut here -- #include <stdio.h> main() { int b, i, k, n; int test; test= 1; i= k= 0; do { i++; if(test) { for(n= 0; n<3; n++) { k++; b= k+1; } printf("k= %d, k-1= %d\n", k, k-1); } } while(i<2); } -- cut here -- cc -O bug.c yields (for you assembler weenies): -- cut here -- (main) mflr r0 # prologue (main+0x4) mfcr r12 (main+0x8) stm r27,-20(r1) (main+0xc) st r12,0x4(r1) (main+0x10) st r0,0x8(r1) (main+0x14) stu r1,-96(r1) # k is r27, i is r28, b is r29 (main+0x18) lil r27,0x0 # k= 0; (main+0x1c) oril r28,r27,0x0 # i= 0; (main+0x20) ai r29,r27,0x1 # b= k + 1 (main+0x24) l r30,0xc(r2) (main+0x28) lil r31,0x3 (main+0x2c) oril r5,r27,0x0 # 3rd print parm is k (zero) (main+0x30) ai r28,r28,0x1 # i++; (main+0x34) mtctr r31 forloop: (main+0x38) oril r27,r29,0x0 (main+0x3c) ai r29,r27,0x1 (main+0x40) bdnge 0x10000310 (main+0x38) # forloop (main+0x44) oril r3,r30,0x0 (main+0x48) oril r4,r27,0x0 (main+0x4c) cmpi cr4,r28,0x2 # test for do loop (main+0x50) bl 0x10000378 (printf) (main+0x54) l r2,0x14(r1) # } while (i < 2); (main+0x58) bge 4,0x10000344 (main+0x6c)# return # bug -- r5 (k - 1) is not updated following the for loop but rather in the do # loop, thus is off by two (main+0x5c) oril r5,r27,0x0 # 2nd printf parm is k - 1 (main+0x60) ai r28,r28,0x1 # i++; (main+0x64) mtctr r31 # reset for loop counter; this # is unnecessary since we # could branch to forloop - 4. (main+0x68) b 0x10000310 (main+0x38) # forloop return: (main+0x6c) l r0,0x68(r1) (main+0x70) l r12,0x64(r1) (main+0x74) ai r1,r1,0x60 (main+0x78) mtlr r0 (main+0x7c) mtcrf 0x8,r12 (main+0x80) lm r27,-20(r1) (main+0x84) br -- cut here -- Thus this code really implements: -- cut here -- main() { int b, i, j, k, n; int test; test= 1; i= j= k= 0; b= k + 1; do { i++; for(n= 0; n<3; n++) { k= b; b= k+1; } printf("k= %d, k-1= %d\n", k, j); j= k; /* bug! */ } while(i<2); } -- cut here -- Notes: r29, which stores variable `b', is unnecessary and should have been optimized out, leaving only `k++' in the for loop. An `si' instruction should have been inserted before the printf instead of trying to move the assignment of the 3rd print parameter outside of the for loop. I'm submitting this problem report to IBM (others may already have done so as well), maybe we'll see it get fixed. Happy hacking, jim frost saber software jimf@saber.com
clarke@acheron.uucp (Ed Clarke/10240000) (09/27/90)
> I'm submitting this problem report to IBM (others may already have > done so as well), maybe we'll see it get fixed. I submitted it (unoficially) to the C maintenance people and also gave a copy to one of the optimizer designers. His comment (freely translated) was "Oh my! That's not good" ... I suspect that a fix will be forthcoming fairly quickly from one group or the other. The test case was quite clear - thanks for posting it. -- | "Pain, n. An uncomfortable frame of mind that may have Ed Clarke | a physical basis in something that is being done to the acheron!clarke | body, or may be purely mental, caused by the good fortune | of another." - Ambrose Bierce