0

I'm reviewing disassembly of some program in Visual Studio and see the following:

001B1015  cmp         ebx, edx  
001B1017  jae         wmain+19h (001B1019h)  
001B1019  pop         esi

This code is just dumb. If jae causes a conditional jump control passes to exactly the same instruction where it would otherwise fall through.

The question is how branch prediction in the CPU will deal with it. The CPU will make a prediction whether it should "jump" or "fall through". Until they gather some statistics over previous execution of the code Intel x86 processors predict conditional jumps forward as "won't be done". So this jae will be predicted as "won't happen, fall through" and the CPU will select the "fall through" path.

If a misprediction happens (it turns out the "fall through" path was erroneously selected) the CPU formally should reset the pipeline and run the "branch" path instead.

The trick here is "fall through" and "branch" effectively do the same and are equivalent to nop.

I've never seen this scenario analyzed in any documentation on branching.

Can a popular CPU typically treat this jae as nop or will it use usual prediction logic?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • I have neither seen this special case in any Intel or AMD manual. So I believe such special cases are not differently executed than any other conditional jump. There can be many special cases, which we cannot think of at the moment, which special consideration by CPU would take too many additional transistors, maybe even additional pipeline steps, hence generate more power and heat. If such an instruction sequence is rather common then additional transistor and power cost would be worth. Otherwise they are not worth. – Igor Popov Feb 10 '15 at 13:11
  • 1
    @IgorPopov: Sounds reasonable. A compiler has much better chances to deal with this. – sharptooth Feb 10 '15 at 13:20
  • I sure hope you found these instructions in code that was generated without optimizations, no? – Mike Nakis Feb 10 '15 at 14:46
  • @MikeNakis Either of /O2 and /Ox cause this code to be emitted. – sharptooth Feb 10 '15 at 15:13
  • well, what can I say, this is quite lame on behalf of the compiler. – Mike Nakis Feb 10 '15 at 15:18
  • What source code got the compiler to use `cmp + jae` as a very expensive no-op there? And to chime in on the question, no, there are efficient HW-supported no-ops already. Adding hardware support for jumps as no-ops wouldn't be useful, and would take extra silicon, not to mention design time. – Peter Cordes Jun 25 '15 at 12:09
  • @PeterCordes Four months later I simply don't remember what code it was. – sharptooth Jun 25 '15 at 12:16

0 Answers0