OSDN Git Service

[X86] Unsigned saturation subtraction canonicalization [the backend part]
authorZvi Rackover <zvi.rackover@intel.com>
Mon, 9 Oct 2017 20:01:10 +0000 (20:01 +0000)
committerZvi Rackover <zvi.rackover@intel.com>
Mon, 9 Oct 2017 20:01:10 +0000 (20:01 +0000)
commit8fa507233db1dfd5500f310ae867204c73b6b55c
tree398a35aee0a3c2d7e837448acc4556841868d7c8
parent9af4e0a83072baaa8d76708ac8098cb3477807bb
[X86] Unsigned saturation subtraction canonicalization [the backend part]

Summary:
On behalf of julia.koval@intel.com

The patch transforms canonical version of unsigned saturation, which is sub(max(a,b),a) or sub(a,min(a,b)) to special psubus insturuction on targets, which support it(8bit and 16bit uints).
umax(a,b) - b -> subus(a,b)
a - umin(a,b) -> subus(a,b)

There is also extra case handled, when right part of sub is 32 bit and can be truncated, using UMIN(this transformation was discussed in https://reviews.llvm.org/D25987).

The example of special case code:

```
void foo(unsigned short *p, int max, int n) {

  int i;
  unsigned m;
  for (i = 0; i < n; i++) {
    m = *--p;
    *p = (unsigned short)(m >= max ? m-max : 0);
  }
}
```
Max in this example is truncated to max_short value, if it is greater than m, or just truncated to 16 bit, if it is not. It is vaid transformation, because if max > max_short, result of the expression will be zero.

Here is the table of types, I try to support, special case items are bold:

| Size | 128 | 256 | 512
| -----  | -----  | -----   | -----
| i8 | v16i8 | v32i8 | v64i8
| i16 | v8i16 | v16i16 | v32i16
| i32 | | **v8i32** | **v16i32**
| i64 | | | **v8i64**

Reviewers: zvi, spatel, DavidKreitzer, RKSimon

Reviewed By: zvi

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D37534

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315237 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/psubus.ll