5

In my embedded project, using IAR EWARM dev tools (v7.10.3), I have the following piece of code:

/*  1 */   uint32_t packet_sync = 0;
/*  2 */   uint32_t synced      = 0;
/*  3 */   uint32_t gpio        = 0;

/*  4 */   while (1) {
/*  5 */     if ((packet_sync != 0) && ((packet_sync = gpio) == 0)) {
/*  6 */       if (synced < 2) {
/*  7 */         synced++;
/*  8 */       }
/*  9 */     }
/* 10 */   };

From some reason, when I compile the code, the compiler gets stuck in the middle of the compilation. I tried playing around with the various constructs, and it seems like any minor change I make, removes the problem (but may make the code incorrect as well). For example, adding a NOP in #6a,and the code does compile successfully:

/*  6 */       if (synced < 2) {
/* 6a */         __NOP();
/*  7 */         synced++;
/*  8 */       }

Other examples of successful changes are removing line #7 or changing line #5 as:

/*  5 */     if ((packet_sync != 0) && ((gpio) == 0)) {

and a couple more variations.

I do not see a C rule violation in the problematic code, and it compiles just fine in Visual Studio 2013. Do I miss something? Why does this code not compile?

* Note: the code presented is an extract of the actual code and is logically meaningless.


Update: The code is compiled with the "High"/"Balanced" optimization level. With lower optimization levels, the compilation concludes just fine.

It also gets stuck when using "High" level but removing the optimization options in the "Enabled transformations:" box. Also, stuck for "Speed" and "Size" options.

ysap
  • 7,723
  • 7
  • 59
  • 122
  • What compiler options are you using, and do the results change if for example you switch optimisation on/off or use C++ compilation rather than C?. Since you don't know what the problem is, how can you be sure that presenting a "abstract" is sufficient information to reproduce the problem? The code is certainly not "SSCCE" as you claim! – Clifford Nov 06 '14 at 19:08
  • In the first fragment `gpio` is loop invariant. If it may be changed in some other context it must be declared `volatile`. Other variables may also need to be declared `volatile` depending on usage elsewhere in the code. – Clifford Nov 06 '14 at 19:11
  • @Clifford - I did not claim SSCCE. One "C", for Compilable, was removed, since this code needs to be wrapped by a proper function. `gpio` is indeed invariant (in the extract code). The code was presented as is defined in the project. No variables are volatile. You are right in that I did not mention that the code is *size* optimized. Unfortunately, it is difficult to remove the optimization w/o some massive rework on the project. – ysap Nov 06 '14 at 19:45
  • Sorry, the optimization level is "High"/"Balanced". – ysap Nov 06 '14 at 19:54
  • @Clifford - but you're right, the other "C" should be removed s well, as it is not really self contained. So, I'll edit the question... – ysap Nov 06 '14 at 19:58
  • @Clifford - for completeness, I performed the changes, and the question was updated. – ysap Nov 06 '14 at 20:08

3 Answers3

3

Optimisation is the most complex part of any compiler and thus the most likely place for compiler bugs - especially for a "narrow market" compiler with a small development team and a smaller number if users that a desktop system compiler.

Application of optimisation has two consequences that you need to be wary of; The compiler itself may be buggy (as seems likely in this instance), and any area of "undefined behaviour" in your own code may well change behaviour under optimisation. If you need to use optimisation, you need to be prepared to test extensively - the generated code is not necessarily equivalent to the debug/development build.

In this case you should certainly report the issue to the vendor, ideally with a truly compilable example and project configuration. To solve your immediate problem judicious use of the volatile keyword may resolve the issue - the optimiser will work hard to eliminate variables that appear to have no effect otherwise - if you can avoid the optimiser taking the same path, you may avoid the bug. If you don't use volatile correctly, your code may well exhibit bugs in any case under optimisation. In your example, some variables certainly need to be declared volatile, but as the example is not "real" but "illustrative" it is not possible to advise.

Another possibility as a workaround is to disable optimisation selectively for this code section or source file. Do you really need optimisation to make your code work at all? If not I'd advise avoiding it in any case - not using optimisation avoids changes in behaviour between debug and released code, and makes debugging simpler in the first instance. I'd advise using optimisation as a solution to code size or performance related issues when and if they arise rather than just as a matter of course.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Thanks. This is all true, and well known facts. In the actual code, the `gpio` is declared appropriately. Moreover, I later replaced it with a mere `0`, and the problem persists, so expression volatility is not the source of it. As I noted in the question, it is easy to work around this by simply adding a `NOP` instruction inside the `if`. Points regarding optimization are valid, but in this case, the code already overflows the CPU's memory, while being a critical path, so size reduction is a must, as well as speed increase. Anyway, bug report was sent yesterday. – ysap Nov 07 '14 at 11:50
  • @ysap : In which case I think we need to give up on this - we are discussing a code fragment that is not representative and unlikely to enable someone else with the same tool to reproduce the issue. Moreover it appears ro be about the tool nor programming per se. It probably should not have been migrated here. – Clifford Nov 07 '14 at 22:39
2

If the compiler literally "gets stuck", i.e. freezes up so you have to kill the process, then that's of course a compiler bug.

Figuring out why a piece of code (=the compiler) we haven't seen breaks for a particular input is very hard.

If on the other hand you mean that the compiler stops because it reports an error in your code, then of course it'd be useful to know that, and what it says.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • The process gets stuck, and I have to click on the "Stop Build" button to stop it. No error report is given. – ysap Nov 06 '14 at 15:02
  • 1
    Of course it is very hard... otherwise, I would not post a question here ;-) – ysap Nov 06 '14 at 15:04
  • @ysap I was being lightly ironic. I would claim that what you're asking is basically impossible to figure out remotely. Is there commercial support for the compiler? – unwind Nov 06 '14 at 15:12
  • 2
    Hence the ;-). Yes, there is support but many times I find SE to be much more responsive and productive. – ysap Nov 06 '14 at 15:34
2

I suspect this is a compiler bug. Consider filing a bug with your compiler vendor and make sure to attach the faulty source code so they can reproduce the compiler bug. Bad luck for you. Try to work around this bug for now.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • Thanks. You are basically correct, but please see my comment to @unwind. – ysap Nov 06 '14 at 15:36
  • 1
    Produce a MCVE showing the bug to get good support from the vendor, they won't be able to fix it or spend any time on it if they can't reproduce – M.M Nov 06 '14 at 21:24