ARM compiler bug?



Hi All,

The following sample code gives me unexpected results.

void FindBug()
{
static unsigned int x = 0x80000000; // Very negative
static unsigned int y = 1; // Positive
int z = x - y; // z = 0x7FFFFFFF
if (z > 0) {
OALMSG(TRUE, (L"z (0x%X) > 0\r\n", z));
} else {
OALMSG(TRUE, (L"z (0x%X) <= 0?\r\n", z));
}
}

Looking at this code seems that I should get "z (0x7FFFFFFF) > 0", however,
I actually get "z (0x7FFFFFFF) <= 0?".
I have attached the generated assembler file below. I have embedded some
comments in the assembler.

00000 |FindBug| PROC

; 37 : {

00000 |$L14233|
00000 e52de004 str lr, [sp, #-4]!
00004 |$M14231|

; 38 : static unsigned int x = 0x80000000; // Very negative
; 39 : static unsigned int y = 1; // Positive
; 40 : int z = x - y; // z = 0x7FFFFFFF

00004 e59f3024 ldr r3, [pc, #0x24]
00008 e5932004 ldr r2, [r3, #4]
0000c e5933000 ldr r3, [r3]
00010 e0521003 subs r1, r2, r3

; 41 : if (z > 0) {
; 42 : OALMSG(TRUE, (L"z (0x%X) > 0\r\n", z));

-> At this point z = 0x7FFFFFFF (positive number).

00014 c59f0010 ldrgt r0, [pc, #0x10]

-> We expect the ldrgt to execute but it does not (ldrle does).
-> The condition for gt are Z = 0, N==V.
-> Z = 0 We pass the first condition.
-> N = 0 (bit 31) and V = 1 (overflow from negative to positive) We fail the
second condition.
-> Therefore, N != V and the ldrgt (>) does not execute, even though that is
what we expect.

-> Looks like a compiler bug.

; 43 : } else {
; 44 : OALMSG(TRUE, (L"z (0x%X) <= 0?\r\n", z));

00018 d59f0008 ldrle r0, [pc, #8]
0001c eb000000 bl NKDbgPrintfW

; 45 : }
; 46 : }

00020 e49de004 ldr lr, [sp], #4
00024 e12fff1e bx lr
00028 |$L14236|
00028 00000000 DCD
|??_C@_1CC@EMHAJMPE@?$AAz?$AA?5?$AA?$CI?$AA0?$AAx?$AA?$CF?$AAX?$AA?$CJ?$AA?5
?$AA?$DM?$AA?$DN?$AA?5?$AA0?$AA?$DP?$AA?$AN?$AA?6?$AA?$AA@|
0002c 00000000 DCD
|??_C@_1BO@FIKAIAKN@?$AAz?$AA?5?$AA?$CI?$AA0?$AAx?$AA?$CF?$AAX?$AA?$CJ?$AA?5
?$AA?$DO?$AA?5?$AA0?$AA?$AN?$AA?6?$AA?$AA@|
00030 00000000 DCD |?y@?1??FindBug@@9@9|
00034 |$M14232|

ENDP ; |FindBug|

Danny


.