[HLSL] SPIRV Address after merge comments from #193068 (#194462)

This patch is addressing some comments that arose after #193068 was
merged.
This commit is contained in:
joaosaffran
2026-04-27 14:38:51 -07:00
committed by GitHub
parent 20a62a41c2
commit 1a805ace43
2 changed files with 23 additions and 13 deletions

View File

@@ -1707,29 +1707,29 @@ bool SPIRVInstructionSelector::selectPopCount64(Register ResVReg,
SPIRVTypeInst VecI32Type = GR.getOrCreateSPIRVVectorType(
I32Type, 2 * ComponentCount, MIRBuilder, /*IsSigned=*/false);
// ---- Stage 1: 64-bit → 2x32-bit ----
// Converts 64 bit into and array of 32 bit, containing 2 elements.
Register Vec32 = MRI->createVirtualRegister(GR.getRegClass(VecI32Type));
if (!selectOpWithSrcs(Vec32, VecI32Type, I, {SrcReg}, SPIRV::OpBitcast))
return false;
// ---- Stage 2: popcount per 32-bit lane ----
// Apply popcount on each 32 bit lane
Register Pop32 = MRI->createVirtualRegister(GR.getRegClass(VecI32Type));
if (!selectPopCount32(Pop32, VecI32Type, I, Vec32, Opcode))
return false;
// ---- Stage 3: split even (low) / odd (high) lanes ----
// Splits result into highbit lane and lowbit lane
auto MaybeParts = splitEvenOddLanes(Pop32, ComponentCount, I, I32Type);
if (!MaybeParts)
return false;
SplitParts &Parts = *MaybeParts;
// ---- Stage 4: sum high + low ----
// Sum high part and low part
unsigned OpAdd = Parts.IsScalar ? SPIRV::OpIAddS : SPIRV::OpIAddV;
Register Sum = MRI->createVirtualRegister(GR.getRegClass(Parts.Type));
if (!selectOpWithSrcs(Sum, Parts.Type, I, {Parts.High, Parts.Low}, OpAdd))
return false;
// ---- Stage 5: convert i32 sum to the final result type ----
// Convert 32 bit sum into 64 bit scalar
bool IsSigned = GR.isScalarOrVectorSigned(ResType);
unsigned ConvOp = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
return selectOpWithSrcs(ResVReg, ResType, I, {Sum}, ConvOp);
@@ -3667,28 +3667,26 @@ bool SPIRVInstructionSelector::selectBitreverse64(Register ResVReg,
MachineIRBuilder MIRBuilder(I);
// ---- Types ----
SPIRVTypeInst I32Type = GR.getOrCreateSPIRVIntegerType(32, MIRBuilder);
SPIRVTypeInst VecI32Type = GR.getOrCreateSPIRVVectorType(
I32Type, 2 * ComponentCount, MIRBuilder, /*IsSigned=*/false);
// ---- Stage 1: 64-bit -> 2x32-bit (High, Low) ----
// Converts 64 bit into and array of 32 bit, containing 2 elements.
Register Vec32 = MRI->createVirtualRegister(GR.getRegClass(VecI32Type));
if (!selectOpWithSrcs(Vec32, VecI32Type, I, {SrcReg}, SPIRV::OpBitcast))
return false;
// ---- Stage 2: bitreverse per 32-bit lane ----
// Apply bitreverse on each 32 bit lane
Register Reverse32 = MRI->createVirtualRegister(GR.getRegClass(VecI32Type));
if (!selectBitreverseNative(Reverse32, VecI32Type, I, Vec32))
return false;
// ---- Stage 3: split even (low) / odd (high) lanes ----
// Splits result into highbit lane and lowbit lane
auto MaybeParts = splitEvenOddLanes(Reverse32, ComponentCount, I, I32Type);
if (!MaybeParts)
return false;
SplitParts &Parts = *MaybeParts;
// ---- Stage 4: swap halves and reconstruct v2i32 ----
// Reversing a 64-bit value = reverse each 32-bit half AND swap them,
// so the old High word becomes lane 0 (low) and old Low becomes lane 1
// (high).
@@ -3697,7 +3695,7 @@ bool SPIRVInstructionSelector::selectBitreverse64(Register ResVReg,
SPIRV::OpCompositeConstruct))
return false;
// ---- Stage 5: v2i32 -> 64-bit ----
// Groups 32 bit vector back to 64 bit scalar.
return selectOpWithSrcs(ResVReg, ResType, I, {SwappedVec}, SPIRV::OpBitcast);
}
@@ -3730,9 +3728,9 @@ bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
return selectBitreverseNative(ResVReg, ResType, I, OpReg);
case 64:
return selectBitreverse64(ResVReg, ResType, I, OpReg);
default:
report_fatal_error("G_BITREVERSE only support 16,32,64 bits.");
}
return SPIRVInstructionSelector::diagnoseUnsupported(
I, "G_BITREVERSE only support 16,32,64 bits.");
}
if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions))

View File

@@ -3,6 +3,7 @@
; CHECK: OpMemoryModel Logical GLSL450
;CHECK-DAG: %[[#int_8:]] = OpTypeInt 8
;CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
;CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
;CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
@@ -29,6 +30,17 @@ entry:
ret i32 %elt.bitreverse
}
define noundef i8 @reversebits_i8(i8 noundef %a) {
entry:
; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_8]]
; CHECK: %[[#conversion:]] = OpUConvert %[[#int_32]] %[[#param]]
; CHECK-NEXT: %[[#bitrev:]] = OpBitReverse %[[#int_32]] %[[#conversion]]
; CHECK-NEXT: %[[#shift:]] = OpShiftRightLogical %[[#int_32]] %[[#bitrev]] %[[#const_16]]
; CHECK-NEXT: %[[#]] = OpUConvert %[[#int_8]] %[[#shift]]
%elt.bitreverse = call i8 @llvm.bitreverse.i8(i8 %a)
ret i8 %elt.bitreverse
}
define noundef i16 @reversebits_i16(i16 noundef %a) {
entry:
; CHECK: %[[#param:]] = OpFunctionParameter %[[#int_16]]