That silliness is not comparable to effective use of local variables to both streamline the source code
and get better output from the compiler.
By the way, the magic multiplication number can be worked out, because it's just fixed point math. We take the 32:32 fixed point representation of 1 and divide by 17 to get an approximation of 1/17 in 32:32 fixed: 0x100000000 / 17 = 0xF0F0F0F. That's our magic number for dividing 32 bits by 17 by doing a 64 bit multiplication. For instance 90/17 is 90 * 0xF0F0F0F = 0x54B4B4B46. The integer part of this 32:32 fixed point value is in the upper 32 bits which is 5.
There are some subtleties there, plus considerations of whether we want signed or unsigned division. Better let the compiler deal with it. Arithmetic reductions are safe optimizations. It's hard to imagine what you could do wrong so that an arithmetic reduction breaks your code, given that it produces the same result and doesn't interact with some some memory aliasing where the compiler isn't informed about what you're doing.
And by the way, given this code:
#include <stdio.h>
struct node {
struct node *next, *prev;
};
void ins_after_a(struct node *prev, struct node *node)
{
node->prev = prev;
node->next = prev->next;
prev->next->prev = node;
prev->next = node;
}
void ins_after_b(struct node *prev, struct node *node)
{
struct node *next = prev->next;
node->prev = prev;
node->next = next;
prev->next = node;
next->prev = node;
}
gcc 7.2.0 on Ubuntu 17 generates better code for the cleaner, streamlined second one with the local variable, for exactly the reason I gave. ins_after_a yields 6 movq instructions; in_after_b yields 5.
Better source that is easier to reason about; better machine code: all round win.
ins_after_a:
.LFB23:
.cfi_startproc
movq (%rdi), %rax
movq %rdi, 8(%rsi)
movq %rax, (%rsi)
movq (%rdi), %rax <-- wasteful re-load of (%rdi) due to aliasing suspicion
movq %rsi, 8(%rax)
movq %rsi, (%rdi)
ret
.cfi_endproc
.LFE23:
.size ins_after_a, .-ins_after_a
.p2align 4,,15
.globl ins_after_b
.type ins_after_b, @function
ins_after_b:
.LFB24:
.cfi_startproc
movq (%rdi), %rax
movq %rdi, 8(%rsi)
movq %rax, (%rsi)
movq %rsi, (%rdi)
movq %rsi, 8(%rax)
ret
.cfi_endproc
The language could be specified that way (accesses to structs are memory loads) for all I care and that could be helpful.