Skip to content

Commit 1327288

Browse files
[Hexagon] Lowering saturating subtraction (#158726)
Saturating arithmetic can be expressed by llvm.uadd/usub.sat generic intrinsics.
1 parent c3fb2e1 commit 1327288

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ HexagonTargetLowering::initializeHVXLowering() {
208208
setOperationAction(ISD::SPLAT_VECTOR, T, Legal);
209209
setOperationAction(ISD::UADDSAT, T, Legal);
210210
setOperationAction(ISD::SADDSAT, T, Legal);
211+
setOperationAction(ISD::USUBSAT, T, Legal);
212+
setOperationAction(ISD::SSUBSAT, T, Legal);
211213
if (T != ByteV) {
212214
setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, T, Legal);
213215
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Legal);
@@ -302,6 +304,8 @@ HexagonTargetLowering::initializeHVXLowering() {
302304
setOperationAction(ISD::UADDSAT, T, Legal);
303305
setOperationAction(ISD::SADDSAT, T, Legal);
304306
setOperationAction(ISD::SUB, T, Legal);
307+
setOperationAction(ISD::USUBSAT, T, Legal);
308+
setOperationAction(ISD::SSUBSAT, T, Legal);
305309
setOperationAction(ISD::MUL, T, Custom);
306310
setOperationAction(ISD::MULHS, T, Custom);
307311
setOperationAction(ISD::MULHU, T, Custom);

llvm/lib/Target/Hexagon/HexagonPatternsHVX.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,21 @@ let Predicates = [UseHVX] in {
441441
def: OpR_RR_pat_sat<V6_vaddwsat_dv, saddsat, VecPI32, HWI32>;
442442
}
443443

444+
let Predicates = [UseHVX] in {
445+
def: OpR_RR_pat_sat<V6_vsububsat, usubsat, VecI8, HVI8>;
446+
def: OpR_RR_pat_sat<V6_vsubuhsat, usubsat, VecI16, HVI16>;
447+
def: OpR_RR_pat_sat<V6_vsubuwsat, usubsat, VecI32, HVI32>;
448+
def: OpR_RR_pat_sat<V6_vsubbsat, ssubsat, VecI8, HVI8>;
449+
def: OpR_RR_pat_sat<V6_vsubhsat, ssubsat, VecI16, HVI16>;
450+
def: OpR_RR_pat_sat<V6_vsubwsat, ssubsat, VecI32, HVI32>;
451+
def: OpR_RR_pat_sat<V6_vsububsat_dv, usubsat, VecPI8, HWI8>;
452+
def: OpR_RR_pat_sat<V6_vsubuhsat_dv, usubsat, VecPI16, HWI16>;
453+
def: OpR_RR_pat_sat<V6_vsubuwsat_dv, usubsat, VecPI32, HWI32>;
454+
def: OpR_RR_pat_sat<V6_vsubbsat_dv, ssubsat, VecPI8, HWI8>;
455+
def: OpR_RR_pat_sat<V6_vsubhsat_dv, ssubsat, VecPI16, HWI16>;
456+
def: OpR_RR_pat_sat<V6_vsubwsat_dv, ssubsat, VecPI32, HWI32>;
457+
}
458+
444459
// For now, we always deal with vector floating point in SF mode.
445460
class OpR_RR_pat_conv<InstHexagon MI, PatFrag Op, ValueType ResType,
446461
PatFrag RsPred, PatFrag RtPred = RsPred>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
; RUN: llc -march=hexagon -mattr=+hvxv73,+hvx-length128b < %s | FileCheck %s
2+
3+
;; Saturating subtraction.
4+
5+
; CHECK-LABEL: vsububsat
6+
; CHECK: v[[#]].ub = vsub(v[[#]].ub,v[[#]].ub):sat
7+
define dso_local <128 x i8> @vsububsat(<128 x i8> %x, <128 x i8> %y) {
8+
entry:
9+
%0 = tail call <128 x i8> @llvm.usub.sat.v128i8(<128 x i8> %x, <128 x i8> %y)
10+
ret <128 x i8> %0
11+
}
12+
13+
; CHECK-LABEL: vsubuhsat
14+
; CHECK: v[[#]].uh = vsub(v[[#]].uh,v[[#]].uh):sat
15+
define dso_local <64 x i16> @vsubuhsat(<64 x i16> %x, <64 x i16> %y) {
16+
entry:
17+
%0 = tail call <64 x i16> @llvm.usub.sat.v64i16(<64 x i16> %x, <64 x i16> %y)
18+
ret <64 x i16> %0
19+
}
20+
21+
; CHECK-LABEL: vsubuwsat
22+
; CHECK: v[[#]].uw = vsub(v[[#]].uw,v[[#]].uw):sat
23+
define dso_local <32 x i32> @vsubuwsat(<32 x i32> %x, <32 x i32> %y) {
24+
entry:
25+
%0 = tail call <32 x i32> @llvm.usub.sat.v32i32(<32 x i32> %x, <32 x i32> %y)
26+
ret <32 x i32> %0
27+
}
28+
29+
; CHECK-LABEL: vsubbsat
30+
; CHECK: v[[#]].b = vsub(v[[#]].b,v[[#]].b):sat
31+
define dso_local <128 x i8> @vsubbsat(<128 x i8> %x, <128 x i8> %y) {
32+
entry:
33+
%0 = tail call <128 x i8> @llvm.ssub.sat.v128i8(<128 x i8> %x, <128 x i8> %y)
34+
ret <128 x i8> %0
35+
}
36+
37+
; CHECK-LABEL: vsubhsat
38+
; CHECK: v[[#]].h = vsub(v[[#]].h,v[[#]].h):sat
39+
define dso_local <64 x i16> @vsubhsat(<64 x i16> %x, <64 x i16> %y) {
40+
entry:
41+
%0 = tail call <64 x i16> @llvm.ssub.sat.v64i16(<64 x i16> %x, <64 x i16> %y)
42+
ret <64 x i16> %0
43+
}
44+
45+
; CHECK-LABEL: vsubwsat
46+
; CHECK: v[[#]].w = vsub(v[[#]].w,v[[#]].w):sat
47+
define dso_local <32 x i32> @vsubwsat(<32 x i32> %x, <32 x i32> %y) {
48+
entry:
49+
%0 = tail call <32 x i32> @llvm.ssub.sat.v32i32(<32 x i32> %x, <32 x i32> %y)
50+
ret <32 x i32> %0
51+
}
52+
53+
; CHECK-LABEL: vsububsat_dv
54+
; CHECK: v[[#]]:[[#]].ub = vsub(v[[#]]:[[#]].ub,v[[#]]:[[#]].ub):sat
55+
define dso_local <256 x i8> @vsububsat_dv(<256 x i8> %x, <256 x i8> %y) {
56+
entry:
57+
%0 = tail call <256 x i8> @llvm.usub.sat.v256i8(<256 x i8> %x, <256 x i8> %y)
58+
ret <256 x i8> %0
59+
}
60+
61+
; CHECK-LABEL: vsubuhsat_dv
62+
; CHECK: v[[#]]:[[#]].uh = vsub(v[[#]]:[[#]].uh,v[[#]]:[[#]].uh):sat
63+
define dso_local <128 x i16> @vsubuhsat_dv(<128 x i16> %x, <128 x i16> %y) {
64+
entry:
65+
%0 = tail call <128 x i16> @llvm.usub.sat.v128i16(<128 x i16> %x, <128 x i16> %y)
66+
ret <128 x i16> %0
67+
}
68+
69+
; CHECK-LABEL: vsubuwsat_dv
70+
; CHECK: v[[#]]:[[#]].uw = vsub(v[[#]]:[[#]].uw,v[[#]]:[[#]].uw):sat
71+
define dso_local <64 x i32> @vsubuwsat_dv(<64 x i32> %x, <64 x i32> %y) {
72+
entry:
73+
%0 = tail call <64 x i32> @llvm.usub.sat.v64i32(<64 x i32> %x, <64 x i32> %y)
74+
ret <64 x i32> %0
75+
}
76+
77+
; CHECK-LABEL: vsubbsat_dv
78+
; CHECK: v[[#]]:[[#]].b = vsub(v[[#]]:[[#]].b,v[[#]]:[[#]].b):sat
79+
define dso_local <256 x i8> @vsubbsat_dv(<256 x i8> %x, <256 x i8> %y) {
80+
entry:
81+
%0 = tail call <256 x i8> @llvm.ssub.sat.v256i8(<256 x i8> %x, <256 x i8> %y)
82+
ret <256 x i8> %0
83+
}
84+
85+
; CHECK-LABEL: vsubhsat_dv
86+
; CHECK: v[[#]]:[[#]].h = vsub(v[[#]]:[[#]].h,v[[#]]:[[#]].h):sat
87+
define dso_local <128 x i16> @vsubhsat_dv(<128 x i16> %x, <128 x i16> %y) {
88+
entry:
89+
%0 = tail call <128 x i16> @llvm.ssub.sat.v128i16(<128 x i16> %x, <128 x i16> %y)
90+
ret <128 x i16> %0
91+
}
92+
93+
; CHECK-LABEL: vsubwsat_dv
94+
; CHECK: v[[#]]:[[#]].w = vsub(v[[#]]:[[#]].w,v[[#]]:[[#]].w):sat
95+
define dso_local <64 x i32> @vsubwsat_dv(<64 x i32> %x, <64 x i32> %y) {
96+
entry:
97+
%0 = tail call <64 x i32> @llvm.ssub.sat.v64i32(<64 x i32> %x, <64 x i32> %y)
98+
ret <64 x i32> %0
99+
}

0 commit comments

Comments
 (0)