Compiler bug

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Compiler bug

621 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by s3-software on Wed Mar 09 16:25:14 MST 2016
I found a bug with the compiler generating code with a udf (Undefined Instruction).

The following code does not create valid code for the if statement.

uint32_t *first_location = 0;
if (*first_location == 0)
__WFI();


The generated assembler (from the debugger) is:

00000244:   movs    r3, #0
00000246:   ldr     r3, [r3, #0]
00000248:   udf     #255    ; 0xff


Any suggestions?

This was tested with the latest lpcxpresso 8.1.2_603 (as well as earlier 8.0 version), and with LPC1768 and LPC1778 targets, and Os (Size) optimizations.

0 Kudos
8 Replies

561 Views
lpcware
NXP Employee
NXP Employee
bump
0 Kudos

561 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by s3-software on Thu Mar 10 17:38:41 MST 2016
Looks like you are right!  Appears to inject a stealth trap in the code (instead of a friendly error).

Referencing location 4 with this code:

volatile uint32_t *first_location = 4;
if (*first_location == 0)
__NOP();


Generates:

  50 0014 0423     movsr3, #4
  51 0016 1B68     ldrr3, [r3]
  52 0018 03B9     cbnzr3, .L1
  59 001a 00BF     nop
  63              .L1


Whereas referencing location 0:

volatile uint32_t *first_location = 0;
if (*first_location == 0)
__NOP();


Generates:

  50 0014 0023     movsr3, #0
  51 0016 1B68     ldrr3, [r3]
  52 0018 FFDE     .inst0xdeff
  53              .L3:
  54 001a 00BF     .align2
  55              .L2


Thanks for the insights.
0 Kudos

561 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Thu Mar 10 12:58:41 MST 2016
You are dereferencing a null pointer, which is undefined behavior. So the compiler is within its rights to generate whatever code it wants, and recent GCC versions have become quite aggressive at this (yes, people are complaining, mostly about signed overflow).
Its a bit unfortunate if you really want to access address 0, maybe you need to hide your bad intentions better, so the compiler doesn't notice.
0 Kudos

561 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Thu Mar 10 09:55:40 MST 2016
@vtw.433e

Even if the volatile modifier 'fixed it' for you, the OP code (as explained)
is also correct syntax and reportedly causes a code generation error.

Of course, we do not see the compiler and/or assembler switches applied
either in the OP or yours. That might be causing a problem if wrong or inappropriate
for the particular device.

Cheers, Mike.
0 Kudos

561 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Thu Mar 10 09:46:50 MST 2016
According to the Arm Architecture Manual v7M, the top 5 bits being '11111' indicate the 1st 16-bit word of a 32 bit instruction.
The listing is seems to be incomplete (maybe that is where the bug is).

FFDE matches neither of the two encodings for WFI.
I would have expected the generated code to be

movs r3 0   (0023)
ldr r3, [r3]   (1B68)
it eq           (BF08)
WFI           (BF30)

The beginning of the FFDE seems to indicate a co-processor instruction.
[it's complicated, I could be wrong]
But it could just be random crap.

Cheers, Mike. [Sorry, that's all I have time for]
0 Kudos

561 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by vtw.433e on Thu Mar 10 09:46:35 MST 2016
Maybe an unexpected bug in your code?

Try
volatile uint32_t * volatile first_location = 0;
if (*first_location == 0)
__WFI();

[Works for me]
0 Kudos

561 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by s3-software on Thu Mar 10 09:07:06 MST 2016
The intention of the code is actually to look at location zero, as the code is using the IAP flash utilities to rewrite the flash, and sometimes the flash is not erased, so the code it looking at location zero to check.

Here is the intermediate file for the assembler

  50 0014 0023     movsr3, #0
  51 0016 1B68     ldrr3, [r3]
  52 0018 FFDE     .inst0xdeff


This also generates an invalid opcode.  Very strange!

Thanks
0 Kudos

561 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Thu Mar 10 08:46:08 MST 2016
Of course, the initialisation of the pointer is invalid in that you are setting the address of the pointer to zero (and not a valid location).
And, therefore, the intended initialisation of the variables value to zero never happens.

This does not mean the the generated code is not wrong. It would have been useful to see exactly what the generated
op-code bytes actually are. [Is there now an option in the assembler window for this?]

Probably, the intended instruction is slightly 'off' with the operands or similar leading to an undefined variation.

Cheers, Mike.
0 Kudos