Skip to content

Commit 84d9f31

Browse files
committed
FEAT:
Add support for the intrinsic @llvm.fptosi.sat.* and @llvm.fptoui.sat.* - Add legalizer for G_FPTOSI_SAT and G_FPTOUI_SAT - Add instructionSelector for G_FPTOSI_SAT and G_FPTOUI_SAT - Add function to add saturatedConversion decoration to the intrinsic
1 parent a278b28 commit 84d9f31

File tree

4 files changed

+221
-0
lines changed

4 files changed

+221
-0
lines changed

llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,6 +2442,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
24422442
if (isConvergenceIntrinsic(I))
24432443
continue;
24442444

2445+
addSaturatedDecorationToIntrinsic(I, B);
24452446
processInstrAfterVisit(I, B);
24462447
}
24472448

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,11 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
601601
case TargetOpcode::G_FPTOUI:
602602
return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToU);
603603

604+
case TargetOpcode::G_FPTOSI_SAT:
605+
return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToS);
606+
case TargetOpcode::G_FPTOUI_SAT:
607+
return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToU);
608+
604609
case TargetOpcode::G_SITOFP:
605610
return selectIToF(ResVReg, ResType, I, true, SPIRV::OpConvertSToF);
606611
case TargetOpcode::G_UITOFP:

llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
236236
.legalForCartesianProduct(allIntScalarsAndVectors,
237237
allFloatScalarsAndVectors);
238238

239+
getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
240+
.legalForCartesianProduct(allIntScalarsAndVectors,
241+
allFloatScalarsAndVectors);
242+
239243
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
240244
.legalForCartesianProduct(allFloatScalarsAndVectors,
241245
allScalarsAndVectors);
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unkown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unkown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; CHECK: OpDecorate %[[#SAT1:]] SaturatedConversion
5+
; CHECK: OpDecorate %[[#SAT2:]] SaturatedConversion
6+
; CHECK: OpDecorate %[[#SAT3:]] SaturatedConversion
7+
; CHECK: OpDecorate %[[#SAT4:]] SaturatedConversion
8+
; CHECK: OpDecorate %[[#SAT5:]] SaturatedConversion
9+
; CHECK: OpDecorate %[[#SAT6:]] SaturatedConversion
10+
; CHECK: OpDecorate %[[#SAT7:]] SaturatedConversion
11+
; CHECK: OpDecorate %[[#SAT8:]] SaturatedConversion
12+
; CHECK: OpDecorate %[[#SAT9:]] SaturatedConversion
13+
; CHECK: OpDecorate %[[#SAT10:]] SaturatedConversion
14+
; CHECK: OpDecorate %[[#SAT11:]] SaturatedConversion
15+
; CHECK: OpDecorate %[[#SAT12:]] SaturatedConversion
16+
; CHECK: OpDecorate %[[#SAT13:]] SaturatedConversion
17+
; CHECK: OpDecorate %[[#SAT14:]] SaturatedConversion
18+
; CHECK: OpDecorate %[[#SAT15:]] SaturatedConversion
19+
20+
21+
; CHECK: %[[#SAT1:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
22+
define spir_kernel void @testfunction_float_to_signed_i8(float %input) {
23+
entry:
24+
%ptr = alloca i8
25+
%0 = call i8 @llvm.fptosi.sat.i8.f32(float %input)
26+
store i8 %0, i8* %ptr
27+
ret void
28+
29+
}
30+
declare i8 @llvm.fptosi.sat.i8.f32(float)
31+
32+
33+
; CHECK: %[[#SAT2:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
34+
define spir_kernel void @testfunction_float_to_signed_i16(float %input) {
35+
entry:
36+
%ptr = alloca i16
37+
%0 = call i16 @llvm.fptosi.sat.i16.f32(float %input)
38+
store i16 %0, i16* %ptr
39+
ret void
40+
41+
}
42+
declare i16 @llvm.fptosi.sat.i16.f32(float)
43+
44+
; CHECK: %[[#SAT3:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
45+
define spir_kernel void @testfunction_float_to_signed_i32(float %input) {
46+
entry:
47+
%ptr = alloca i32
48+
%0 = call i32 @llvm.fptosi.sat.i32.f32(float %input)
49+
store i32 %0, i32* %ptr
50+
ret void
51+
52+
}
53+
declare i32 @llvm.fptosi.sat.i32.f32(float)
54+
55+
56+
; CHECK: %[[#SAT4:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
57+
define spir_kernel void @testfunction_float_to_signed_i64(float %input) {
58+
entry:
59+
%ptr = alloca i64
60+
%0 = call i64 @llvm.fptosi.sat.i64.f32(float %input)
61+
store i64 %0, i64* %ptr
62+
ret void
63+
}
64+
declare i64 @llvm.fptosi.sat.i64.f32(float)
65+
66+
67+
; CHECK: %[[#SAT5:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
68+
define spir_kernel void @testfunction_double_to_signed_i8(double %input) {
69+
entry:
70+
%ptr = alloca i8
71+
%0 = call i8 @llvm.fptosi.sat.i8.f64(double %input)
72+
store i8 %0, i8* %ptr
73+
ret void
74+
}
75+
declare i8 @llvm.fptosi.sat.i8.f64(double)
76+
77+
78+
; CHECK: %[[#SAT6:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
79+
define spir_kernel void @testfunction_double_to_signed_i16(double %input) {
80+
entry:
81+
%ptr = alloca i16
82+
%0 = call i16 @llvm.fptosi.sat.i16.f64(double %input)
83+
store i16 %0, i16* %ptr
84+
ret void
85+
}
86+
declare i16 @llvm.fptosi.sat.i16.f64(double)
87+
88+
89+
; CHECK: %[[#SAT7:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
90+
define spir_kernel void @testfunction_double_to_signed_i32(double %input) {
91+
entry:
92+
%ptr = alloca i32
93+
%0 = call i32 @llvm.fptosi.sat.i32.f64(double %input)
94+
store i32 %0, i32* %ptr
95+
ret void
96+
}
97+
declare i32 @llvm.fptosi.sat.i32.f64(double)
98+
99+
100+
; CHECK: %[[#SAT8:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
101+
define spir_kernel void @testfunction_double_to_signed_i64(double %input) {
102+
entry:
103+
%ptr = alloca i64
104+
%0 = call i64 @llvm.fptosi.sat.i64.f64(double %input)
105+
store i64 %0, i64* %ptr
106+
ret void
107+
}
108+
declare i64 @llvm.fptosi.sat.i64.f64(double)
109+
110+
111+
112+
113+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
114+
115+
; unsigned output
116+
117+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
118+
119+
120+
; CHECK: %[[#SAT8:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
121+
define spir_kernel void @testfunction_float_to_unsigned_i8(float %input) {
122+
entry:
123+
%ptr = alloca i8
124+
%0 = call i8 @llvm.fptoui.sat.i8.f32(float %input)
125+
store i8 %0, i8* %ptr
126+
ret void
127+
}
128+
declare i8 @llvm.fptoui.sat.i8.f32(float)
129+
130+
131+
; CHECK: %[[#SAT9:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
132+
define spir_kernel void @testfunction_float_to_unsigned_i16(float %input) {
133+
entry:
134+
%ptr = alloca i16
135+
%0 = call i16 @llvm.fptoui.sat.i16.f32(float %input)
136+
store i16 %0, i16* %ptr
137+
ret void
138+
}
139+
declare i16 @llvm.fptoui.sat.i16.f32(float)
140+
141+
142+
; CHECK: %[[#SAT10:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
143+
define spir_kernel void @testfunction_float_to_unsigned_i32(float %input) {
144+
entry:
145+
%ptr = alloca i32
146+
%0 = call i32 @llvm.fptoui.sat.i32.f32(float %input)
147+
store i32 %0, i32* %ptr
148+
ret void
149+
}
150+
declare i32 @llvm.fptoui.sat.i32.f32(float)
151+
152+
153+
; CHECK: %[[#SAT11:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
154+
define spir_kernel void @testfunction_float_to_unsigned_i64(float %input) {
155+
entry:
156+
%ptr = alloca i64
157+
%0 = call i64 @llvm.fptoui.sat.i64.f32(float %input)
158+
store i64 %0, i64* %ptr
159+
ret void
160+
}
161+
declare i64 @llvm.fptoui.sat.i64.f32(float)
162+
163+
164+
; CHECK: %[[#SAT12:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
165+
define spir_kernel void @testfunction_double_to_unsigned_i8(double %input) {
166+
entry:
167+
%ptr = alloca i8
168+
%0 = call i8 @llvm.fptoui.sat.i8.f64(double %input)
169+
store i8 %0, i8* %ptr
170+
ret void
171+
}
172+
declare i8 @llvm.fptoui.sat.i8.f64(double)
173+
174+
175+
; CHECK: %[[#SAT13:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
176+
define spir_kernel void @testfunction_double_to_unsigned_i16(double %input) {
177+
entry:
178+
%ptr = alloca i16
179+
%0 = call i16 @llvm.fptoui.sat.i16.f64(double %input)
180+
store i16 %0, i16* %ptr
181+
ret void
182+
}
183+
declare i16 @llvm.fptoui.sat.i16.f64(double)
184+
185+
186+
; CHECK: %[[#SAT14:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
187+
define spir_kernel void @testfunction_double_to_unsigned_i32(double %input) {
188+
entry:
189+
%ptr = alloca i32
190+
%0 = call i32 @llvm.fptoui.sat.i32.f64(double %input)
191+
store i32 %0, i32* %ptr
192+
ret void
193+
}
194+
declare i32 @llvm.fptoui.sat.i32.f64(double)
195+
196+
197+
; CHECK: %[[#SAT15:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
198+
define spir_kernel void @testfunction_double_to_unsigned_i64(double %input) {
199+
entry:
200+
%ptr = alloca i64
201+
%0 = call i64 @llvm.fptoui.sat.i64.f64(double %input)
202+
store i64 %0, i64* %ptr
203+
ret void
204+
}
205+
declare i64 @llvm.fptoui.sat.i64.f64(double)
206+
207+
208+
209+
210+
211+

0 commit comments

Comments
 (0)