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

Farzon Lotfi via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 9 21:14:20 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>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/184936 at github.com>


================
@@ -3078,18 +3084,82 @@ bool SPIRVInstructionSelector::selectWaveExclusiveScan(
   return true;
 }
 
-bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
-                                                SPIRVTypeInst ResType,
-                                                MachineInstr &I) const {
+bool SPIRVInstructionSelector::selectBitreverse16(Register ResVReg,
+                                                  SPIRVTypeInst ResType,
+                                                  MachineInstr &I,
+                                                  Register Op) const {
+  SPIRVTypeInst Int32Type = GR.getOrCreateSPIRVIntegerType(32, I, TII);
+  Register ScalarShiftAmount = GR.getOrCreateConstInt(16, I, Int32Type, 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;
+  // 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))
+    return false;
+
+  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 = 0; It < N; ++It)
+      MIB.addUse(ScalarShiftAmount);
+    MIB.constrainAllUses(TII, TRI, RBI);
+  } else {
+    ShiftConst = ScalarShiftAmount;
+  }
+
+  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))
----------------
farzonl wrote:

on line 3113 you are already checking N > 1 you don't need this terinary. Have a default be scalar ShiftRight and switch it to the vector one if the condition is true.

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


More information about the llvm-commits mailing list