Closer inspection shows that as far as the test on line IL_0017 goes, it will always end up going to line IL_001d, hence it doesn't even bother.

The test is not the problem, the problem is that the ldc 2 at IL_0019 is nowhere to be found in the generated C++ code. My guess is that the reason for this bug is the following:

I'm using an evaluation stack based approach that accumulates expressions until an instruction comes along that does some real work, like storing

The value (expression) that gets stored here was defined in two different places. Somehow you lost track of one of those definitions and ended up always writing 1. IL_001D can be reached with 2 different stack states but the generated code accounts for only for one.

I'm just curious, what method is used to compile IL to native code?

I don't know exactly what CLR does but what I'd do is convert the IL to some intermediate representation where there's no stack and where all instruction operands are explicit instead of implicit. Such explicit representation are far more easy to reason about.

You may say that you aren't writing a compiler but getting familiar with some compiler techniques would be a good idea. Reading the code generation chapter(s) from the "Dragon Book" (http://dragonbook.stanford.edu/) is advisable.