Skip to content

Commit cf9a5a1

Browse files
[SPIR-V] Support saturation arithmetic intrinsics in SPIR-V Backend (#91722)
This PR is to support saturation arithmetic intrinsics in SPIR-V Backend.
1 parent 3ae6343 commit cf9a5a1

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,15 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
495495
case TargetOpcode::G_UMULH:
496496
return selectExtInst(ResVReg, ResType, I, CL::u_mul_hi);
497497

498+
case TargetOpcode::G_SADDSAT:
499+
return selectExtInst(ResVReg, ResType, I, CL::s_add_sat);
500+
case TargetOpcode::G_UADDSAT:
501+
return selectExtInst(ResVReg, ResType, I, CL::u_add_sat);
502+
case TargetOpcode::G_SSUBSAT:
503+
return selectExtInst(ResVReg, ResType, I, CL::s_sub_sat);
504+
case TargetOpcode::G_USUBSAT:
505+
return selectExtInst(ResVReg, ResType, I, CL::u_sub_sat);
506+
498507
case TargetOpcode::G_SEXT:
499508
return selectExt(ResVReg, ResType, I, true);
500509
case TargetOpcode::G_ANYEXT:

llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
304304

305305
// Struct return types become a single scalar, so cannot easily legalize.
306306
getActionDefinitionsBuilder({G_SMULH, G_UMULH}).alwaysLegal();
307+
308+
// supported saturation arithmetic
309+
getActionDefinitionsBuilder({G_SADDSAT, G_UADDSAT, G_SSUBSAT, G_USUBSAT})
310+
.legalFor(allIntScalarsAndVectors);
307311
}
308312

309313
getLegacyLegalizerInfo().computeTables();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
5+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
6+
7+
; CHECK: OpExtInstImport "OpenCL.std"
8+
; CHECK-DAG: OpName %[[#Foo:]] "foo"
9+
; CHECK-DAG: OpName %[[#Bar:]] "bar"
10+
; CHECK: %[[#Foo]] = OpFunction
11+
; CHECK: %[[#]] = OpExtInst %[[#]] %[[#]] u_add_sat
12+
; CHECK-NEXT: %[[#]] = OpExtInst %[[#]] %[[#]] u_sub_sat
13+
; CHECK-NEXT: %[[#]] = OpExtInst %[[#]] %[[#]] s_add_sat
14+
; CHECK-NEXT: %[[#]] = OpExtInst %[[#]] %[[#]] s_sub_sat
15+
; CHECK: %[[#Bar]] = OpFunction
16+
; CHECK: %[[#]] = OpExtInst %[[#]] %[[#]] u_add_sat
17+
; CHECK-NEXT: %[[#]] = OpExtInst %[[#]] %[[#]] u_sub_sat
18+
; CHECK-NEXT: %[[#]] = OpExtInst %[[#]] %[[#]] s_add_sat
19+
; CHECK-NEXT: %[[#]] = OpExtInst %[[#]] %[[#]] s_sub_sat
20+
21+
define spir_func void @foo(i16 %x, i16 %y) {
22+
entry:
23+
%r1 = tail call i16 @llvm.uadd.sat.i16(i16 %x, i16 %y)
24+
%r2 = tail call i16 @llvm.usub.sat.i16(i16 %x, i16 %y)
25+
%r3 = tail call i16 @llvm.sadd.sat.i16(i16 %x, i16 %y)
26+
%r4 = tail call i16 @llvm.ssub.sat.i16(i16 %x, i16 %y)
27+
ret void
28+
}
29+
30+
define spir_func void @bar(<4 x i32> %x, <4 x i32> %y) {
31+
entry:
32+
%r1 = tail call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
33+
%r2 = tail call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
34+
%r3 = tail call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
35+
%r4 = tail call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
36+
ret void
37+
}

0 commit comments

Comments
 (0)