Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Inspired by some of the comments I got rid of the branch on my Pentium and <code>gcc</code> compiler using</p> <pre><code>int f (int x, int y) { y += y == 0; return x/y; } </code></pre> <p>The compiler basically recognizes that it can use a condition flag of the test in the addition.</p> <p>As per request the assembly:</p> <pre><code>.globl f .type f, @function f: pushl %ebp xorl %eax, %eax movl %esp, %ebp movl 12(%ebp), %edx testl %edx, %edx sete %al addl %edx, %eax movl 8(%ebp), %edx movl %eax, %ecx popl %ebp movl %edx, %eax sarl $31, %edx idivl %ecx ret </code></pre> <p>As this turned out to be such a popular question and answer, I'll elaborate a bit more. The above example is based on programming idiom that a compiler recognizes. In the above case a boolean expression is used in integral arithmetic and the use of condition flags are invented in hardware for this purpose. In general condition flags are only accessible in C through using idiom. That is why it so hard to make a portable multiple precision integer library in C without resorting to (inline) assembly. My guess is that most decent compilers will understand the above idiom.</p> <p>Another way of avoiding branches, as also remarked in some of the above comments, is predicated execution. I therefore took philipp's first code and my code and ran it through the compiler from ARM and the GCC compiler for the ARM architecture, which features predicated execution. Both compilers avoid the branch in both samples of code:</p> <p>Philipp's version with the ARM compiler:</p> <pre><code>f PROC CMP r1,#0 BNE __aeabi_idivmod MOVEQ r0,#0 BX lr </code></pre> <p>Philipp's version with GCC:</p> <pre><code>f: subs r3, r1, #0 str lr, [sp, #-4]! moveq r0, r3 ldreq pc, [sp], #4 bl __divsi3 ldr pc, [sp], #4 </code></pre> <p>My code with the ARM compiler:</p> <pre><code>f PROC RSBS r2,r1,#1 MOVCC r2,#0 ADD r1,r1,r2 B __aeabi_idivmod </code></pre> <p>My code with GCC:</p> <pre><code>f: str lr, [sp, #-4]! cmp r1, #0 addeq r1, r1, #1 bl __divsi3 ldr pc, [sp], #4 </code></pre> <p>All versions still need a branch to the division routine, because this version of the ARM doesn't have hardware for a division, but the test for <code>y == 0</code> is fully implemented through predicated execution.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload