This is an archive of the discontinued LLVM Phabricator instance.

Add Integer Saturation Intrinsics.
Needs ReviewPublic

Authored by ab on Jan 14 2015, 2:02 PM.

Details

Reviewers
echristo
weimingz
Summary

I'm not sure the C-ish examples in the documentation are desirable, but I've added a few examples to make the behavior clear enough.

See the llvmdev thread. As described there:
This patch introduces a new family of intrinsics, for integer saturation: @llvm.usat, and @llvm.ssat (unsigned/signed). Quoting the added documentation:

%r = call i32 @llvm.ssat.i32(i32 %x, i32 %n)

is equivalent to the expression min(max(x, -2^(n-1)), 2^(n-1)-1), itself
implementable as the following IR:

%min_sint_n = i32 ... ; the min. signed integer of bitwidth n, -2^(n-1)
%max_sint_n = i32 ... ; the max. signed integer of bitwidth n, 2^(n-1)-1
%0 = icmp slt i32 %x, %min_sint_n
%1 = select i1 %0, i32 %min_sint_n, i32 %x
%2 = icmp sgt i32 %1, %max_sint_n
%r = select i1 %2, i32 %max_sint_n, i32 %1

Diff Detail

Event Timeline

ab updated this revision to Diff 18181.Jan 14 2015, 2:02 PM
ab updated this revision to Diff 18182.
ab retitled this revision from to Add Integer Saturation Intrinsics..
ab updated this object.
ab edited the test plan for this revision. (Show Details)
ab added a subscriber: Unknown Object (MLST).Jan 14 2015, 2:09 PM

Do we need to remove the llvm.arm.usat with this patch?

rengolin set the repository for this revision to rL LLVM.
rengolin edited edge metadata.
rengolin removed a subscriber: weimingz.

FYI, D8371 would greatly benefit from this patch. I'm adding Eric me and Weiming to the review list, the interested parties in the change going in. Please, add whomever else would be good to have in the reviewers list.

cheers,
--renato

Probably we'll have to rebase the whole thing. Let's get that one sorted first, then we see what's left. I have a feeling that it'll be a lot less code from your part.

Hi Ahmed,

This looks clean enough for me, and it matches the ARM semantics. I believe front-ends could generate it directly, but also it could become the end-result of an optimization pass looking for that pattern in IR, right?

cheers,
--renato

ab added a comment.Mar 20 2015, 7:20 PM

Hi Ahmed,

This looks clean enough for me, and it matches the ARM semantics. I believe front-ends could generate it directly, but also it could become the end-result of an optimization pass looking for that pattern in IR, right?

Right, my goal was to have an InstCombine that recognizes this.

However, on the RFC thread there were some concerns with adding intrinsics, and honestly I can see where they're coming from (you'd need to teach the various optimizers about those intrinsics). We can do all this at the SelectionDAG level, with a CodeGenPrepare fixup to get the select/icmp closer together. So, why would we add special-case intrinsics if we can express this in fairly simple canonical IR? We do the same for min/max, and we don't have intrinsics for those.

Anyway, I'll try to rebase this soon-ish and put my other patches up; sorry I couldn't get to this sooner!

Do we need to remove the llvm.arm.usat with this patch?

For now I'd rather keep the ARM intrinsics, we can deprecate and autoupgrade down the road.

-Ahmed

My problem with implementing this on the ARM side is that the code won't be useful anywhere else.

Maybe, a better approach would be to have them just as special DAG nodes, created by a special DAG pass that only run for selected back-ends, instead of an IR intrisic, or an ARM-specific late pass.

I'm assuming the semantics of such pass would be very similar on other back-ends...

delena added a subscriber: delena.Mar 30 2015, 4:25 AM

Hi,

I'm interested in these intrinsics for X86. Do you plan to push them as target independent?

Thanks.

  • Elena
rengolin resigned from this revision.May 13 2016, 7:14 AM
rengolin removed a reviewer: rengolin.
tkn added a subscriber: tkn.Nov 17 2016, 7:08 PM