[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