-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[SPIRV] support for the intrinsic @llvm.fptosi.sat.* and @llvm.fptoui.sat.* #129222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-backend-spir-v Author: None (VishMCW) ChangesAdd support for the intrinsic @llvm.fptosi.sat.* and @llvm.fptoui.sat.*
Full diff: https://github.com/llvm/llvm-project/pull/129222.diff 4 Files Affected:
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 5dfba8427258f..450260a0713c2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1367,6 +1367,25 @@ static void createSaturatedConversionDecoration(Instruction *I,
createDecorationIntrinsic(I, SaturatedConversionNode, B);
}
+static void addSaturatedDecorationToIntrinsic(Instruction *I, IRBuilder<> &B) {
+ if (auto *CI = dyn_cast<CallInst>(I)) {
+ if (Function *Fu = CI->getCalledFunction()) {
+ if (Fu->isIntrinsic()) {
+ unsigned const int IntrinsicId = Fu->getIntrinsicID();
+ switch (IntrinsicId) {
+ case Intrinsic::fptosi_sat:
+ case Intrinsic::fptoui_sat:
+ createSaturatedConversionDecoration(I, B);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
+
+
Instruction *SPIRVEmitIntrinsics::visitCallInst(CallInst &Call) {
if (!Call.isInlineAsm())
return &Call;
@@ -2441,7 +2460,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
// Don't emit intrinsics for convergence operations.
if (isConvergenceIntrinsic(I))
continue;
-
+ addSaturatedDecorationToIntrinsic(I, B);
processInstrAfterVisit(I, B);
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index c52b67e72a88c..a9d0e0b726351 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -601,6 +601,11 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
case TargetOpcode::G_FPTOUI:
return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToU);
+ case TargetOpcode::G_FPTOSI_SAT:
+ return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToS);
+ case TargetOpcode::G_FPTOUI_SAT:
+ return selectUnOp(ResVReg, ResType, I, SPIRV::OpConvertFToU);
+
case TargetOpcode::G_SITOFP:
return selectIToF(ResVReg, ResType, I, true, SPIRV::OpConvertSToF);
case TargetOpcode::G_UITOFP:
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index daa8ea52ffe03..06f9f5777f416 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -236,6 +236,10 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
.legalForCartesianProduct(allIntScalarsAndVectors,
allFloatScalarsAndVectors);
+ getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
+ .legalForCartesianProduct(allIntScalarsAndVectors,
+ allFloatScalarsAndVectors);
+
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.legalForCartesianProduct(allFloatScalarsAndVectors,
allScalarsAndVectors);
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/fp-to-int-intrinsics.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/fp-to-int-intrinsics.ll
new file mode 100644
index 0000000000000..5b7387fd1a0bb
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/fp-to-int-intrinsics.ll
@@ -0,0 +1,205 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unkown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unkown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpDecorate %[[#SAT1:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT2:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT3:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT4:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT5:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT6:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT7:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT8:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT9:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT10:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT11:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT12:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT13:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT14:]] SaturatedConversion
+; CHECK: OpDecorate %[[#SAT15:]] SaturatedConversion
+
+
+; CHECK: %[[#SAT1:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_signed_i8(float %input) {
+entry:
+ %ptr = alloca i8
+ %0 = call i8 @llvm.fptosi.sat.i8.f32(float %input)
+ store i8 %0, i8* %ptr
+ ret void
+
+}
+declare i8 @llvm.fptosi.sat.i8.f32(float)
+
+
+; CHECK: %[[#SAT2:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_signed_i16(float %input) {
+entry:
+ %ptr = alloca i16
+ %0 = call i16 @llvm.fptosi.sat.i16.f32(float %input)
+ store i16 %0, i16* %ptr
+ ret void
+
+}
+declare i16 @llvm.fptosi.sat.i16.f32(float)
+
+; CHECK: %[[#SAT3:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_signed_i32(float %input) {
+entry:
+ %ptr = alloca i32
+ %0 = call i32 @llvm.fptosi.sat.i32.f32(float %input)
+ store i32 %0, i32* %ptr
+ ret void
+
+}
+declare i32 @llvm.fptosi.sat.i32.f32(float)
+
+
+; CHECK: %[[#SAT4:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_signed_i64(float %input) {
+entry:
+ %ptr = alloca i64
+ %0 = call i64 @llvm.fptosi.sat.i64.f32(float %input)
+ store i64 %0, i64* %ptr
+ ret void
+}
+declare i64 @llvm.fptosi.sat.i64.f32(float)
+
+
+; CHECK: %[[#SAT5:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_signed_i8(double %input) {
+entry:
+ %ptr = alloca i8
+ %0 = call i8 @llvm.fptosi.sat.i8.f64(double %input)
+ store i8 %0, i8* %ptr
+ ret void
+}
+declare i8 @llvm.fptosi.sat.i8.f64(double)
+
+
+; CHECK: %[[#SAT6:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_signed_i16(double %input) {
+entry:
+ %ptr = alloca i16
+ %0 = call i16 @llvm.fptosi.sat.i16.f64(double %input)
+ store i16 %0, i16* %ptr
+ ret void
+}
+declare i16 @llvm.fptosi.sat.i16.f64(double)
+
+
+; CHECK: %[[#SAT7:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_signed_i32(double %input) {
+entry:
+ %ptr = alloca i32
+ %0 = call i32 @llvm.fptosi.sat.i32.f64(double %input)
+ store i32 %0, i32* %ptr
+ ret void
+}
+declare i32 @llvm.fptosi.sat.i32.f64(double)
+
+
+; CHECK: %[[#SAT8:]] = OpConvertFToS %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_signed_i64(double %input) {
+entry:
+ %ptr = alloca i64
+ %0 = call i64 @llvm.fptosi.sat.i64.f64(double %input)
+ store i64 %0, i64* %ptr
+ ret void
+}
+declare i64 @llvm.fptosi.sat.i64.f64(double)
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; unsigned output
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+; CHECK: %[[#SAT8:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_unsigned_i8(float %input) {
+entry:
+ %ptr = alloca i8
+ %0 = call i8 @llvm.fptoui.sat.i8.f32(float %input)
+ store i8 %0, i8* %ptr
+ ret void
+}
+declare i8 @llvm.fptoui.sat.i8.f32(float)
+
+
+; CHECK: %[[#SAT9:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_unsigned_i16(float %input) {
+entry:
+ %ptr = alloca i16
+ %0 = call i16 @llvm.fptoui.sat.i16.f32(float %input)
+ store i16 %0, i16* %ptr
+ ret void
+}
+declare i16 @llvm.fptoui.sat.i16.f32(float)
+
+
+; CHECK: %[[#SAT10:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_unsigned_i32(float %input) {
+entry:
+ %ptr = alloca i32
+ %0 = call i32 @llvm.fptoui.sat.i32.f32(float %input)
+ store i32 %0, i32* %ptr
+ ret void
+}
+declare i32 @llvm.fptoui.sat.i32.f32(float)
+
+
+; CHECK: %[[#SAT11:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_float_to_unsigned_i64(float %input) {
+entry:
+ %ptr = alloca i64
+ %0 = call i64 @llvm.fptoui.sat.i64.f32(float %input)
+ store i64 %0, i64* %ptr
+ ret void
+}
+declare i64 @llvm.fptoui.sat.i64.f32(float)
+
+
+; CHECK: %[[#SAT12:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_unsigned_i8(double %input) {
+entry:
+ %ptr = alloca i8
+ %0 = call i8 @llvm.fptoui.sat.i8.f64(double %input)
+ store i8 %0, i8* %ptr
+ ret void
+}
+declare i8 @llvm.fptoui.sat.i8.f64(double)
+
+
+; CHECK: %[[#SAT13:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_unsigned_i16(double %input) {
+entry:
+ %ptr = alloca i16
+ %0 = call i16 @llvm.fptoui.sat.i16.f64(double %input)
+ store i16 %0, i16* %ptr
+ ret void
+}
+declare i16 @llvm.fptoui.sat.i16.f64(double)
+
+
+; CHECK: %[[#SAT14:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_unsigned_i32(double %input) {
+entry:
+ %ptr = alloca i32
+ %0 = call i32 @llvm.fptoui.sat.i32.f64(double %input)
+ store i32 %0, i32* %ptr
+ ret void
+}
+declare i32 @llvm.fptoui.sat.i32.f64(double)
+
+
+; CHECK: %[[#SAT15:]] = OpConvertFToU %{{[0-9]+}} %[[#]]
+define spir_kernel void @testfunction_double_to_unsigned_i64(double %input) {
+entry:
+ %ptr = alloca i64
+ %0 = call i64 @llvm.fptoui.sat.i64.f64(double %input)
+ store i64 %0, i64* %ptr
+ ret void
+}
+declare i64 @llvm.fptoui.sat.i64.f64(double)
|
You can test this locally with the following command:git-clang-format --diff a278b28a945a8354627303604671a28751f3ca51 4f25113924e8d659105e83b13d35ed38b52b0e64 --extensions cpp -- llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp View the diff from clang-format here.diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 450260a071..20327b289f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1385,7 +1385,6 @@ static void addSaturatedDecorationToIntrinsic(Instruction *I, IRBuilder<> &B) {
}
}
-
Instruction *SPIRVEmitIntrinsics::visitCallInst(CallInst &Call) {
if (!Call.isInlineAsm())
return &Call;
|
38944e1
to
84d9f31
Compare
84d9f31
to
78b6638
Compare
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the empty lines at the end of the file. Also, please name all vregs (instead of %0
) -- this helps with automatic test adjustments using scripts, I think that also this comment/banner unsigned output
can be removed or at least made smaller (nit).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have made the necessary changes
Add support for the intrinsic @llvm.fptosi.sat.* and @llvm.fptoui.sat.*