This patch is addressing some comments that arose after #193068 was merged.
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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]]
|
||||
|
||||
Reference in New Issue
Block a user