Division Operations with Fast Integer Division Support

If the --idiv_support=idiv0 command-line option is used, the compiler generates faster instructions to perform integer division when the division ("/") or modulo ("%") operator or the div() or ldiv() function is used. The faster versions of these built-in operators are used whether or not the stdlib.h header file is included.

The following table shows which intrinsics are used to perform integer operations using the division ("/") and modulo ("%") operators.

Types Operated Upon Equivalent Intrinsic Call
int / int __traditional_div_i16byi16(int, int).quot
int % int __traditional_div_i16byi16(int, int).rem
unsigned int / unsigned int __traditional_div_u16byu16(unsigned int, unsigned int).quot
unsigned int % unsigned int __traditional_div_u16byu16(unsigned int, unsigned int).rem
long / long __traditional_div_i32byi32(long, long).quot
long % long __traditional_div_i32byi32(long, long).rem
unsigned long / unsigned long __traditional_div_u32byu32(unsigned long, unsigned long).quot
unsigned long % unsigned long __traditional_div_u32byu32(unsigned long, unsigned long).rem
long long / long long __traditional_div_i64byi64(long long, long long).quot
long long % long long __traditional_div_i64byi64(long long, long long).rem
unsigned long long / unsigned long long __traditional_div_u64byu64(unsigned long long, unsigned long long).quot
unsigned long long % unsigned long long __traditional_div_u64byu64(unsigned long long, unsigned long long).rem

Intrinsics that allow you to more exactly specify the operation to be performed are listed in Section 7.6.3.

In C, when the operands of integer division or modulo operations have different types, the compiler automatically performs "integral promotion" (also called implicit type conversion). That is, the compiler inserts an implicit cast to convert to a common type, and then performs the operation in that type.

The intrinsic that is performed may be different than the one expected based on the types being divided. For example:

long dividend_i32, quotient_i32; unsigned long divisor_u32, quotient_u32; int divisor_i16; /* uses __traditional_div_u32byu32, not __traditional_div_i32byu32 */ quotient_u32 = dividend_i32 / divisor_u32; /* uses __traditional_div_i32byi32, not __traditional_div_i32byi16 */ quotient_i32 = dividend_i32 / divisor_i16;

Because integral promotion can be confusing, it is often best to avoid the issue by making sure the operand types agree, possibly by using a cast operator. For more about integral promotion, see How to Write Multiplies Correctly in C Code (SPRA683).