[LLVMdev] RFC: Integer saturation intrinsics

Evan Cheng evan.cheng at apple.com
Fri Jun 17 15:08:38 PDT 2011


Hi all,

I'm proposing integer saturation intrinsics.

def int_ssat : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i32_ty]>;
def int_usat : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i32_ty]>;

The first operand is the integer value being saturated, and second is the saturation bit position.

For scalar integer types, the semantics are:

int_ssat: x < -(1 << (bit-1)) ? -(1 << (bit-1)) : (x > (1 << (bit-1))-1 ? (1 << (bit-1))-1 : x)
int_usat: x < 0 ? 0 : (x > (1 << bit)-1 : (1 << bit)-1 : x)

e.g. If bit is 8, the range is -128 to 127 for int_ssat; 0 to 255 for int_usat. This is useful for i16 / i32 / i64 to i8 satuation code like the following:
(x < -256) ? -256 : (x > 255 ? 255 : x)
(x < 0) ? 0 : (x > 255 ? 255 : x)

If the source type is an integer vector type, then each element of the vector is being saturated.

For ARM, these intrinsics will map to usat / ssat instructions. The semantics matches exactly. X86 doesn't have saturation instructions. However, SSE does have packed add, packed sub, and pack with saturation. So it's possible to instruction select patterns such as (int_{s|u}sat ({add|sub} x, y), c).

The plan is to form calls to these intrinsics in InstCombine. Legalizer can expand these intrinsics if they are not legal. The expansion should be fairly straight forward and produce code that is at least as good as what LLVM is currently generating for these code sequence.

Comments?

Evan



More information about the llvm-dev mailing list