[llvm] f813817 - [SPIR-V] Select int-to-int convert opcode from source signedness (#201116)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 2 08:03:46 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-06-02T17:03:40+02:00
New Revision: f813817e3495c5ab8e0dd7d3c471e531d83a630a
URL: https://github.com/llvm/llvm-project/commit/f813817e3495c5ab8e0dd7d3c471e531d83a630a
DIFF: https://github.com/llvm/llvm-project/commit/f813817e3495c5ab8e0dd7d3c471e531d83a630a.diff
LOG: [SPIR-V] Select int-to-int convert opcode from source signedness (#201116)
OpSConvert/OpUConvert sext/zext is determined by the source operand, not
the destination type. Discovered in
https://github.com/llvm/llvm-project/pull/200791/changes#r3341230426
Fix a regression caused by #200791
Added:
llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_signedness.ll
Modified:
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 9bc29dd0103a6..3e0de48a81349 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -3209,14 +3209,15 @@ static bool generateConvertInst(const StringRef DemangledCall,
unsigned Opcode = SPIRV::OpNop;
if (GR->isScalarOrVectorOfType(Call->Arguments[0], SPIRV::OpTypeInt)) {
// Int -> ...
+ bool IsSourceSigned =
+ DemangledCall[DemangledCall.find_first_of('(') + 1] != 'u';
if (GR->isScalarOrVectorOfType(Call->ReturnRegister, SPIRV::OpTypeInt)) {
// Int -> Int
if (Builtin->IsSaturated)
Opcode = Builtin->IsDestinationSigned ? SPIRV::OpSatConvertUToS
: SPIRV::OpSatConvertSToU;
else
- Opcode = Builtin->IsDestinationSigned ? SPIRV::OpSConvert
- : SPIRV::OpUConvert;
+ Opcode = IsSourceSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
} else if (GR->isScalarOrVectorOfType(Call->ReturnRegister,
SPIRV::OpTypeFloat)) {
// Int -> Float
@@ -3231,8 +3232,6 @@ static bool generateConvertInst(const StringRef DemangledCall,
GR->getScalarOrVectorComponentCount(Call->ReturnRegister);
Opcode = SPIRV::OpConvertBF16ToFINTEL;
} else {
- bool IsSourceSigned =
- DemangledCall[DemangledCall.find_first_of('(') + 1] != 'u';
Opcode = IsSourceSigned ? SPIRV::OpConvertSToF : SPIRV::OpConvertUToF;
}
}
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_signedness.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_signedness.ll
new file mode 100644
index 0000000000000..d20d6a1e79931
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/convert_signedness.ll
@@ -0,0 +1,67 @@
+; Check that convert_ builtins pick the signed/unsigned opcode from the source
+; operand signedness.
+
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpName %[[#StoS:]] "s_to_s"
+; CHECK-DAG: OpName %[[#StoU:]] "s_to_u"
+; CHECK-DAG: OpName %[[#UtoS:]] "u_to_s"
+; CHECK-DAG: OpName %[[#UtoU:]] "u_to_u"
+; CHECK-DAG: OpName %[[#StoF:]] "s_to_f"
+; CHECK-DAG: OpName %[[#UtoF:]] "u_to_f"
+
+; signed source -> signed dest: sign-extend.
+; CHECK: %[[#StoS]] = OpFunction
+; CHECK: OpSConvert
+define spir_func void @s_to_s(i32 noundef %x) {
+ call spir_func i64 @_Z12convert_longi(i32 noundef %x)
+ ret void
+}
+
+; signed source -> unsigned dest: sign-extend.
+; CHECK: %[[#StoU]] = OpFunction
+; CHECK: OpSConvert
+define spir_func void @s_to_u(i32 noundef %x) {
+ call spir_func i64 @_Z13convert_ulongi(i32 noundef %x)
+ ret void
+}
+
+; unsigned source -> signed dest: zero-extend.
+; CHECK: %[[#UtoS]] = OpFunction
+; CHECK: OpUConvert
+define spir_func void @u_to_s(i32 noundef %x) {
+ call spir_func i64 @_Z12convert_longj(i32 noundef %x)
+ ret void
+}
+
+; unsigned source -> unsigned dest: zero-extend.
+; CHECK: %[[#UtoU]] = OpFunction
+; CHECK: OpUConvert
+define spir_func void @u_to_u(i32 noundef %x) {
+ call spir_func i64 @_Z13convert_ulongj(i32 noundef %x)
+ ret void
+}
+
+; signed source -> float.
+; CHECK: %[[#StoF]] = OpFunction
+; CHECK: OpConvertSToF
+define spir_func void @s_to_f(i32 noundef %x) {
+ call spir_func float @_Z13convert_floati(i32 noundef %x)
+ ret void
+}
+
+; unsigned source -> float.
+; CHECK: %[[#UtoF]] = OpFunction
+; CHECK: OpConvertUToF
+define spir_func void @u_to_f(i32 noundef %x) {
+ call spir_func float @_Z13convert_floatj(i32 noundef %x)
+ ret void
+}
+
+declare spir_func i64 @_Z12convert_longi(i32 noundef)
+declare spir_func i64 @_Z13convert_ulongi(i32 noundef)
+declare spir_func i64 @_Z12convert_longj(i32 noundef)
+declare spir_func i64 @_Z13convert_ulongj(i32 noundef)
+declare spir_func float @_Z13convert_floati(i32 noundef)
+declare spir_func float @_Z13convert_floatj(i32 noundef)
More information about the llvm-commits
mailing list