kindwolf.org Git repositories xavierg-snippets / master gcc-optimizations / avoid-imul.c
master

Tree @master (Download .tar.gz)

avoid-imul.c @masterraw · history · blame

/*
 * A few dummy functions to show how gcc avoids integer
 * multiplication (i.e. the "imul" instruction) even with -O0.
 * Of course, the avoidance is more, err, straightforward
 * with -O1 and friends.
 * Tested with x86-64 gcc 6.2 and -O0.
 *
 * Let's be honest, I was procrastinating something here...
 */
#include <stdint.h>

uint32_t gcc_O0_optim_mul_2() {
	uint32_t multiplize_me = 42;
	// This will actually do multiplize_me + multiplize_me
	return multiplize_me * 2;
}

uint32_t gcc_O0_optim_mul_3() {
	uint32_t multiplize_me = 42;
	// This will actually do multiplize_me + multiplize_me + multiplize_me
	return multiplize_me * 3;
}

uint32_t gcc_O0_optim_mul_4() {
	uint32_t multiplize_me = 42;
	// This will actually do multiplize_me << 2
	return multiplize_me * 4;
}

uint32_t gcc_O0_optim_mul_5() {
	uint32_t multiplize_me = 42;
	// This will actually do (multiplize_me << 2) + multiplize_me
	return multiplize_me * 5;
}

uint32_t gcc_O0_optim_mul_6() {
	uint32_t multiplize_me = 42;
	// This will do gcc_O0_optim_mul_3 followed by gcc_O0_optim_mul_2
	return multiplize_me * 6;
}

uint32_t gcc_O0_optim_mul_7() {
	uint32_t multiplize_me = 42;
	// This will actually do (multiplize_me << 3) - multiplize_me
	return multiplize_me * 7;
}

uint32_t gcc_O0_optim_mul_8() {
	uint32_t multiplize_me = 42;
	// This will actually do multiplize_me << 3
	return multiplize_me * 8;
}

uint32_t gcc_O0_optim_mul_9() {
	uint32_t multiplize_me = 42;
	// This will actually do (multiplize_me << 3) + multiplize_me
	return multiplize_me * 9;
}

uint32_t gcc_O0_optim_mul_10() {
	uint32_t multiplize_me = 42;
	// This will do gcc_O0_optim_mul_5 followed by gcc_O0_optim_mul_2
	return multiplize_me * 10;
}

uint32_t gcc_O0_optim_mul_11() {
	uint32_t multiplize_me = 42;
	// This will do gcc_O0_optim_mul_10 then add multiplize_me
	return multiplize_me * 11;
}

uint32_t gcc_O0_optim_mul_12() {
	uint32_t multiplize_me = 42;
	// This will do gcc_O0_optim_mul_3 followed by gcc_O0_optim_mul_4
	return multiplize_me * 12;
}

uint32_t gcc_O0_optim_mul_13() {
	uint32_t multiplize_me = 42;
	// This will do gcc_O0_optim_mul_12 then add multiplize_me
	return multiplize_me * 13;
}

uint32_t gcc_O0_optim_mul_14() {
	uint32_t multiplize_me = 42;
	// This will, at last, call imul
	return multiplize_me * 14;
}

uint32_t gcc_O0_optim_mul_15() {
	uint32_t multiplize_me = 42;
	// This will actually do (multiplize_me << 4) - multiplize_me
	return multiplize_me * 15;
}

uint32_t gcc_O0_optim_mul_16() {
	uint32_t multiplize_me = 42;
	// This will actually do multiplize_me << 4
	return multiplize_me * 16;
}