[llvm] [HLSL][SPIRV] Update reversebits codegen for half types (PR #184936)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 20:08:42 PDT 2026


=?utf-8?q?João?= Saffran <joaosaffranllvm at gmail.com>,Joao Saffran
 <joaosaffranllvm at gmail.com>,
=?utf-8?q?João?= Saffran <joaosaffranllvm at gmail.com>,Joao Saffran
 <joaosaffranllvm at gmail.com>,Joao Saffran <joaosaffranllvm at gmail.com>,Joao
 Saffran <joaosaffranllvm at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/184936 at github.com>


https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/184936

>From 3b597e52fe579240687db1aa72920c454bd54131 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 14:53:16 -0800
Subject: [PATCH 1/8] add 16 bit case

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 21 ++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 7b4c047593a3a..bfaf861747612 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3081,11 +3081,30 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
 bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
                                                 SPIRVTypeInst ResType,
                                                 MachineInstr &I) const {
+  Register OpReg = I.getOperand(1).getReg();
+
+  if (GR.getScalarOrVectorBitWidth(ResType) == 16) {
+    SPIRVTypeInst IntType = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+    unsigned N = GR.getScalarOrVectorComponentCount(ResType);
+    if (N > 1)
+      IntType = GR.getOrCreateSPIRVVectorType(ResType, N, I, TII);
+
+    OpReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
+    unsigned ExtendOpcode =
+        sampledTypeIsSignedInteger(GR.getTypeForSPIRVType(ResType))
+            ? SPIRV::OpSConvert
+            : SPIRV::OpUConvert;
+    if (!selectOpWithSrcs(OpReg, IntType, I, {I.getOperand(1).getReg()},
+                          ExtendOpcode))
+      return false;
+    ResType = IntType;
+  }
+
   MachineBasicBlock &BB = *I.getParent();
   BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
       .addDef(ResVReg)
       .addUse(GR.getSPIRVTypeID(ResType))
-      .addUse(I.getOperand(1).getReg())
+      .addUse(OpReg)
       .constrainAllUses(TII, TRI, RBI);
   return true;
 }

>From edb30c0ad4938969f4f71a48a4374fef622dcbf4 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 15:22:50 -0800
Subject: [PATCH 2/8] fix incorrect function usage & update test reversebits.ll

---
 llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp    |  7 +++----
 .../test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll | 11 +++++++++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index bfaf861747612..fd53bab28b4d8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3090,10 +3090,9 @@ bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
       IntType = GR.getOrCreateSPIRVVectorType(ResType, N, I, TII);
 
     OpReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
-    unsigned ExtendOpcode =
-        sampledTypeIsSignedInteger(GR.getTypeForSPIRVType(ResType))
-            ? SPIRV::OpSConvert
-            : SPIRV::OpUConvert;
+    unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
+                                ? SPIRV::OpSConvert
+                                : SPIRV::OpUConvert;
     if (!selectOpWithSrcs(OpReg, IntType, I, {I.getOperand(1).getReg()},
                           ExtendOpcode))
       return false;
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
index 6571b2992fab3..77f24c72cffc6 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
@@ -3,16 +3,23 @@
 
 ; CHECK: OpMemoryModel Logical GLSL450
 
+;CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+;CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+
 define noundef i32 @reversebits_i32(i32 noundef %a) {
 entry:
-; CHECK: %[[#]] = OpBitReverse %[[#]] %[[#]]
+; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_32]]
+; CHECK-NOT: OpUConvert 
+; CHECK: %[[#]] = OpBitReverse %[[#int_32]] %[[#param]]
   %elt.bitreverse = call i32 @llvm.bitreverse.i32(i32 %a)
   ret i32 %elt.bitreverse
 }
 
 define noundef i16 @reversebits_i16(i16 noundef %a) {
 entry:
-; CHECK: %[[#]] = OpBitReverse %[[#]] %[[#]]
+; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_16]]
+; CHECK: %[[#conversion:]] = OpUConvert %[[#int_32]] %[[#param]]
+; CHECK-NEXT: %[[#]] = OpBitReverse %[[#int_32]] %[[#conversion]]
   %elt.bitreverse = call i16 @llvm.bitreverse.i16(i16 %a)
   ret i16 %elt.bitreverse
 }

>From 3c0f0e494ff1fb110df41733414c6a345a3c04cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 17:14:27 -0800
Subject: [PATCH 3/8] add composite to shift

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 68 ++++++++++++++-----
 1 file changed, 52 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index fd53bab28b4d8..7b8dec6106142 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -188,6 +188,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
   bool selectBitreverse(Register ResVReg, SPIRVTypeInst ResType,
                         MachineInstr &I) const;
 
+  bool selectBitreverse16(Register ResVReg, SPIRVTypeInst ResType,
+                          MachineInstr &I) const;
+
   bool selectBuildVector(Register ResVReg, SPIRVTypeInst ResType,
                          MachineInstr &I) const;
   bool selectSplatVector(Register ResVReg, SPIRVTypeInst ResType,
@@ -3078,32 +3081,65 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
   return true;
 }
 
+bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
+                                                  SPIRVTypeInst ResType,
+                                                  MachineInstr &I) const {
+  SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+
+  unsigned N = GR.getScalarOrVectorComponentCount(ResType);
+  if (N > 1)
+    Int32Type = GR.getOrCreateSPIRVVectorType(Int32Type, N, I, TII);
+
+  Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+  unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
+                              ? SPIRV::OpSConvert
+                              : SPIRV::OpUConvert;
+  if (!selectOpWithSrcs(ExtReg, Int32Type, I, {I.getOperand(1).getReg()},
+                        ExtendOpcode))
+    return false;
+
+  Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+  if (!selectOpWithSrcs(BitrevReg, Int32Type, I, {ExtReg}, SPIRV::OpBitReverse))
+    return false;
+
+  Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
+
+  Register ShiftConst;
+  if (N > 1) {
+    ShiftConst = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+    auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+                       TII.get(SPIRV::OpConstantComposite))
+                   .addDef(ShiftConst)
+                   .addUse(GR.getSPIRVTypeID(Int32Type));
+    for (unsigned It = I.getNumExplicitDefs(); It < I.getNumExplicitOperands();
+         ++It)
+      MIB.addUse(ScalarShiftAmount);
+    MIB.constrainAllUses(TII, TRI, RBI);
+  } else {
+    ShiftConst = ScalarShiftAmount;
+  }
+
+  Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+  if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
+                        N > 1 ? SPIRV::OpShiftRightLogicalV
+                              : SPIRV::OpShiftRightLogicalS))
+    return false;
+
+  return selectOpWithSrcs(ResVReg, ResType, I, {ShiftReg}, ExtendOpcode);
+}
+
 bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
                                                 SPIRVTypeInst ResType,
                                                 MachineInstr &I) const {
-  Register OpReg = I.getOperand(1).getReg();
-
   if (GR.getScalarOrVectorBitWidth(ResType) == 16) {
-    SPIRVTypeInst IntType = GR.getOrCreateSPIRVIntegerType(32, I, TII);
-    unsigned N = GR.getScalarOrVectorComponentCount(ResType);
-    if (N > 1)
-      IntType = GR.getOrCreateSPIRVVectorType(ResType, N, I, TII);
-
-    OpReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
-    unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
-                                ? SPIRV::OpSConvert
-                                : SPIRV::OpUConvert;
-    if (!selectOpWithSrcs(OpReg, IntType, I, {I.getOperand(1).getReg()},
-                          ExtendOpcode))
-      return false;
-    ResType = IntType;
+    return selectBitreverse16(ResVReg, ResType, I);
   }
 
   MachineBasicBlock &BB = *I.getParent();
   BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
       .addDef(ResVReg)
       .addUse(GR.getSPIRVTypeID(ResType))
-      .addUse(OpReg)
+      .addUse(I.getOperand(1).getReg())
       .constrainAllUses(TII, TRI, RBI);
   return true;
 }

>From 1f4c76b49e9a528c02790d84abd9aa9381f2a073 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 17:36:31 -0800
Subject: [PATCH 4/8] fix composite logic

---
 llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 7b8dec6106142..41bbb10da8e74 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3085,6 +3085,7 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
                                                   SPIRVTypeInst ResType,
                                                   MachineInstr &I) const {
   SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+  Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
 
   unsigned N = GR.getScalarOrVectorComponentCount(ResType);
   if (N > 1)
@@ -3102,8 +3103,6 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
   if (!selectOpWithSrcs(BitrevReg, Int32Type, I, {ExtReg}, SPIRV::OpBitReverse))
     return false;
 
-  Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
-
   Register ShiftConst;
   if (N > 1) {
     ShiftConst = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
@@ -3111,8 +3110,7 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
                        TII.get(SPIRV::OpConstantComposite))
                    .addDef(ShiftConst)
                    .addUse(GR.getSPIRVTypeID(Int32Type));
-    for (unsigned It = I.getNumExplicitDefs(); It < I.getNumExplicitOperands();
-         ++It)
+    for (unsigned It = 0; It < N; ++It)
       MIB.addUse(ScalarShiftAmount);
     MIB.constrainAllUses(TII, TRI, RBI);
   } else {

>From b63d635555dc90b2e6d8e5eac42c2806bbff07c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <joaosaffranllvm at gmail.com>
Date: Thu, 5 Mar 2026 18:21:45 -0800
Subject: [PATCH 5/8] update test

---
 .../SPIRV/hlsl-intrinsics/reversebits.ll      | 23 ++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
index 77f24c72cffc6..c1c7210b90f6a 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reversebits.ll
@@ -5,12 +5,18 @@
 
 ;CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
 ;CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+;CHECK-DAG: %[[#vec_int_32:]] = OpTypeVector %[[#int_32]] 2
+;CHECK-DAG: %[[#vec_int_16:]] = OpTypeVector %[[#int_16]] 2
+
+;CHECK-DAG: %[[#const_16:]] = OpConstant %[[#int_32]] 16
+;CHECK-DAG: %[[#composite:]] = OpConstantComposite %[[#vec_int_32]] %[[#const_16]] %[[#const_16]] 
 
 define noundef i32 @reversebits_i32(i32 noundef %a) {
 entry:
 ; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_32]]
 ; CHECK-NOT: OpUConvert 
 ; CHECK: %[[#]] = OpBitReverse %[[#int_32]] %[[#param]]
+; CHECK-NOT: OpShiftRightLogical 
   %elt.bitreverse = call i32 @llvm.bitreverse.i32(i32 %a)
   ret i32 %elt.bitreverse
 }
@@ -19,10 +25,25 @@ define noundef i16 @reversebits_i16(i16 noundef %a) {
 entry:
 ; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_16]]
 ; CHECK: %[[#conversion:]] = OpUConvert %[[#int_32]] %[[#param]]
-; CHECK-NEXT: %[[#]] = OpBitReverse %[[#int_32]] %[[#conversion]]
+; CHECK-NEXT: %[[#bitrev:]] = OpBitReverse %[[#int_32]] %[[#conversion]]
+; CHECK-NEXT: %[[#shift:]] = OpShiftRightLogical %[[#int_32]] %[[#bitrev]] %[[#const_16]]
+; CHECK-NEXT: %[[#]] = OpUConvert %[[#int_16]] %[[#shift]]
   %elt.bitreverse = call i16 @llvm.bitreverse.i16(i16 %a)
   ret i16 %elt.bitreverse
 }
 
+define noundef <2 x i16> @reversebits_veci16(<2 x i16> noundef %a) {
+entry:
+; CHECK: %[[#param:]] = OpFunctionParameter %[[#vec_int_16]]
+; CHECK: %[[#conversion:]] = OpUConvert %[[#vec_int_32]] %[[#param]]
+; CHECK-NEXT: %[[#bitrev:]] = OpBitReverse %[[#vec_int_32]] %[[#conversion]]
+; CHECK-NEXT: %[[#shift:]] = OpShiftRightLogical %[[#vec_int_32]] %[[#bitrev]] %[[#composite]]
+; CHECK-NEXT: %[[#]] = OpUConvert %[[#vec_int_16]] %[[#shift]]
+  %elt.bitreverse = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %a)
+  ret <2 x i16> %elt.bitreverse
+}
+
+
 declare i16 @llvm.bitreverse.i16(i16)
 declare i32 @llvm.bitreverse.i32(i32)
+declare <2 x i16> @llvm.bitreverse.v2i16(<2 x i16>)

>From 251a7c965e51fb7500302f00f5f6002d3a1525fe Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 9 Mar 2026 16:18:13 -0700
Subject: [PATCH 6/8] create a single function to emit bitreverse

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 44 ++++++++++++++-----
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 41bbb10da8e74..887a7faa50589 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -189,7 +189,10 @@ class SPIRVInstructionSelector : public InstructionSelector {
                         MachineInstr &I) const;
 
   bool selectBitreverse16(Register ResVReg, SPIRVTypeInst ResType,
-                          MachineInstr &I) const;
+                          MachineInstr &I, Register Op) const;
+
+  bool selectBitreverse32(Register ResVReg, SPIRVTypeInst ResType,
+                          MachineInstr &I, Register Op) const;
 
   bool selectBuildVector(Register ResVReg, SPIRVTypeInst ResType,
                          MachineInstr &I) const;
@@ -3083,7 +3086,8 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
 
 bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
                                                   SPIRVTypeInst ResType,
-                                                  MachineInstr &I) const {
+                                                  MachineInstr &I, 
+                                                  Register Op) const {
   SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
   Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
 
@@ -3095,12 +3099,14 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
   unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
                               ? SPIRV::OpSConvert
                               : SPIRV::OpUConvert;
-  if (!selectOpWithSrcs(ExtReg, Int32Type, I, {I.getOperand(1).getReg()},
+  // Converts the i16 input to i32 (or vector of i32)                            
+  if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op},
                         ExtendOpcode))
     return false;
 
   Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
-  if (!selectOpWithSrcs(BitrevReg, Int32Type, I, {ExtReg}, SPIRV::OpBitReverse))
+  // Perform bitreverse on the i32 value
+  if(!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
     return false;
 
   Register ShiftConst;
@@ -3118,30 +3124,44 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
   }
 
   Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+
+  // Shift the bit-reversed value to get the final result. 
   if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
                         N > 1 ? SPIRV::OpShiftRightLogicalV
                               : SPIRV::OpShiftRightLogicalS))
     return false;
-
+  
+  // Finally, convert the result back to i16 (or vector of i16).
   return selectOpWithSrcs(ResVReg, ResType, I, {ShiftReg}, ExtendOpcode);
 }
 
-bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
+bool SPIRVInstructionSelector::selectBitreverse32(Register ResVReg,
                                                 SPIRVTypeInst ResType,
-                                                MachineInstr &I) const {
-  if (GR.getScalarOrVectorBitWidth(ResType) == 16) {
-    return selectBitreverse16(ResVReg, ResType, I);
-  }
-
+                                                MachineInstr &I,
+                                                Register Op) const {
   MachineBasicBlock &BB = *I.getParent();
   BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
       .addDef(ResVReg)
       .addUse(GR.getSPIRVTypeID(ResType))
-      .addUse(I.getOperand(1).getReg())
+      .addUse(Op)
       .constrainAllUses(TII, TRI, RBI);
   return true;
 }
 
+
+bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
+                                                SPIRVTypeInst ResType,
+                                                MachineInstr &I) const {
+  Register OpReg = I.getOperand(1).getReg();
+  SPIRVTypeInst OpType = GR.getSPIRVTypeForVReg(OpReg);
+  switch(GR.getScalarOrVectorBitWidth(OpType)) {
+  case 16:
+    return selectBitreverse16(ResVReg, ResType, I, OpReg);
+  default:
+    return selectBitreverse32(ResVReg, ResType, I, OpReg);
+  }
+}
+
 bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
                                             SPIRVTypeInst ResType,
                                             MachineInstr &I) const {

>From b9b95abbe03a462c3f091895b4e423288466a91b Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 9 Mar 2026 16:55:15 -0700
Subject: [PATCH 7/8] format

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 22 +++++++++----------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 887a7faa50589..a7a3f877f4eb5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3086,7 +3086,7 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
 
 bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
                                                   SPIRVTypeInst ResType,
-                                                  MachineInstr &I, 
+                                                  MachineInstr &I,
                                                   Register Op) const {
   SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
   Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
@@ -3099,14 +3099,13 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
   unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
                               ? SPIRV::OpSConvert
                               : SPIRV::OpUConvert;
-  // Converts the i16 input to i32 (or vector of i32)                            
-  if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op},
-                        ExtendOpcode))
+  // Converts the i16 input to i32 (or vector of i32)
+  if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op}, ExtendOpcode))
     return false;
 
   Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
   // Perform bitreverse on the i32 value
-  if(!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
+  if (!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
     return false;
 
   Register ShiftConst;
@@ -3125,20 +3124,20 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
 
   Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
 
-  // Shift the bit-reversed value to get the final result. 
+  // Shift the bit-reversed value to get the final result.
   if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
                         N > 1 ? SPIRV::OpShiftRightLogicalV
                               : SPIRV::OpShiftRightLogicalS))
     return false;
-  
+
   // Finally, convert the result back to i16 (or vector of i16).
   return selectOpWithSrcs(ResVReg, ResType, I, {ShiftReg}, ExtendOpcode);
 }
 
 bool SPIRVInstructionSelector::selectBitreverse32(Register ResVReg,
-                                                SPIRVTypeInst ResType,
-                                                MachineInstr &I,
-                                                Register Op) const {
+                                                  SPIRVTypeInst ResType,
+                                                  MachineInstr &I,
+                                                  Register Op) const {
   MachineBasicBlock &BB = *I.getParent();
   BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpBitReverse))
       .addDef(ResVReg)
@@ -3148,13 +3147,12 @@ bool SPIRVInstructionSelector::selectBitreverse32(Register ResVReg,
   return true;
 }
 
-
 bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
                                                 SPIRVTypeInst ResType,
                                                 MachineInstr &I) const {
   Register OpReg = I.getOperand(1).getReg();
   SPIRVTypeInst OpType = GR.getSPIRVTypeForVReg(OpReg);
-  switch(GR.getScalarOrVectorBitWidth(OpType)) {
+  switch (GR.getScalarOrVectorBitWidth(OpType)) {
   case 16:
     return selectBitreverse16(ResVReg, ResType, I, OpReg);
   default:

>From f86cb1a5b76b0f6f7691f533415a60a932bb19b6 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Tue, 10 Mar 2026 20:08:14 -0700
Subject: [PATCH 8/8] refactor for readability

---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 53 ++++++++++---------
 1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index a7a3f877f4eb5..a200cb45fd440 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3089,45 +3089,46 @@ bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
                                                   MachineInstr &I,
                                                   Register Op) const {
   SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
-  Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, TII);
+  Register ShiftConst = GR.getOrCreateConstInt(16, I, Int32Type, TII);
+  unsigned ShiftOp = SPIRV::OpShiftRightLogicalS;
 
-  unsigned N = GR.getScalarOrVectorComponentCount(ResType);
-  if (N > 1)
-    Int32Type = GR.getOrCreateSPIRVVectorType(Int32Type, N, I, TII);
-
-  Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
-  unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
-                              ? SPIRV::OpSConvert
-                              : SPIRV::OpUConvert;
-  // Converts the i16 input to i32 (or vector of i32)
-  if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op}, ExtendOpcode))
-    return false;
+  const unsigned N = GR.getScalarOrVectorComponentCount(ResType);
+  const unsigned ExtendOpcode = GR.isScalarOrVectorSigned(ResType)
+                                    ? SPIRV::OpSConvert
+                                    : SPIRV::OpUConvert;
 
-  Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
-  // Perform bitreverse on the i32 value
-  if (!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
-    return false;
-
-  Register ShiftConst;
   if (N > 1) {
-    ShiftConst = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+    Int32Type = GR.getOrCreateSPIRVVectorType(Int32Type, N, I, TII);
+    ShiftOp = SPIRV::OpShiftRightLogicalV;
+
+    // Vector shifts require a composite constant
+    const Register CompositeReg =
+        MRI->createVirtualRegister(GR.getRegClass(Int32Type));
     auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
                        TII.get(SPIRV::OpConstantComposite))
-                   .addDef(ShiftConst)
+                   .addDef(CompositeReg)
                    .addUse(GR.getSPIRVTypeID(Int32Type));
     for (unsigned It = 0; It < N; ++It)
-      MIB.addUse(ScalarShiftAmount);
+      MIB.addUse(ShiftConst);
     MIB.constrainAllUses(TII, TRI, RBI);
-  } else {
-    ShiftConst = ScalarShiftAmount;
+
+    ShiftConst = CompositeReg;
   }
 
-  Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+  // Converts the i16 input to i32 (or vector of i32)
+  Register ExtReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+  if (!selectOpWithSrcs(ExtReg, Int32Type, I, {Op}, ExtendOpcode))
+    return false;
+
+  // Perform bitreverse on the i32 value
+  Register BitrevReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
+  if (!selectBitreverse32(BitrevReg, Int32Type, I, ExtReg))
+    return false;
 
   // Shift the bit-reversed value to get the final result.
+  Register ShiftReg = MRI->createVirtualRegister(GR.getRegClass(Int32Type));
   if (!selectOpWithSrcs(ShiftReg, Int32Type, I, {BitrevReg, ShiftConst},
-                        N > 1 ? SPIRV::OpShiftRightLogicalV
-                              : SPIRV::OpShiftRightLogicalS))
+                        ShiftOp))
     return false;
 
   // Finally, convert the result back to i16 (or vector of i16).



More information about the llvm-commits mailing list