Skip to content

Commit e67adb9

Browse files
committed
Address comments
1 parent a90026c commit e67adb9

File tree

1 file changed

+55
-31
lines changed

1 file changed

+55
-31
lines changed

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,17 @@ class SPIRVInstructionSelector : public InstructionSelector {
105105

106106
bool selectFirstBitSet32(Register ResVReg, const SPIRVType *ResType,
107107
MachineInstr &I, Register SrcReg,
108-
unsigned Opcode) const;
108+
unsigned BitSetOpcode) const;
109109

110110
bool selectFirstBitSet64(Register ResVReg, const SPIRVType *ResType,
111111
MachineInstr &I, Register SrcReg,
112112
unsigned BitSetOpcode, bool SwapPrimarySide) const;
113113

114+
bool selectFirstBitSet64Overflow(Register ResVReg, const SPIRVType *ResType,
115+
MachineInstr &I, Register SrcReg,
116+
unsigned BitSetOpcode,
117+
bool SwapPrimarySide) const;
118+
114119
bool selectGlobalValue(Register ResVReg, MachineInstr &I,
115120
const MachineInstr *Init = nullptr) const;
116121

@@ -3157,51 +3162,42 @@ bool SPIRVInstructionSelector::selectFirstBitSet16(
31573162
selectFirstBitSet32(ResVReg, ResType, I, ExtReg, BitSetOpcode);
31583163
}
31593164

3160-
bool SPIRVInstructionSelector::selectFirstBitSet32(Register ResVReg,
3161-
const SPIRVType *ResType,
3162-
MachineInstr &I,
3163-
Register SrcReg,
3164-
unsigned Opcode) const {
3165+
bool SPIRVInstructionSelector::selectFirstBitSet32(
3166+
Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
3167+
Register SrcReg, unsigned BitSetOpcode) const {
31653168
return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst))
31663169
.addDef(ResVReg)
31673170
.addUse(GR.getSPIRVTypeID(ResType))
31683171
.addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
3169-
.addImm(Opcode)
3172+
.addImm(BitSetOpcode)
31703173
.addUse(SrcReg)
31713174
.constrainAllUses(TII, TRI, RBI);
31723175
}
31733176

3174-
bool SPIRVInstructionSelector::selectFirstBitSet64(
3177+
bool SPIRVInstructionSelector::selectFirstBitSet64Overflow(
31753178
Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
31763179
Register SrcReg, unsigned BitSetOpcode, bool SwapPrimarySide) const {
3180+
31773181
unsigned ComponentCount = GR.getScalarOrVectorComponentCount(ResType);
31783182
SPIRVType *BaseType = GR.retrieveScalarOrVectorIntType(ResType);
31793183
bool ZeroAsNull = STI.isOpenCLEnv();
31803184
Register ConstIntZero =
31813185
GR.getOrCreateConstInt(0, I, BaseType, TII, ZeroAsNull);
3182-
Register ConstIntOne =
3183-
GR.getOrCreateConstInt(1, I, BaseType, TII, ZeroAsNull);
3186+
unsigned LeftComponentCount = ComponentCount / 2;
3187+
unsigned RightComponentCount = ComponentCount - LeftComponentCount;
3188+
bool LeftIsVector = LeftComponentCount > 1;
31843189

3185-
// SPIRV doesn't support vectors with more than 4 components. Since the
3186-
// algoritm below converts i64 -> i32x2 and i64x4 -> i32x8 it can only
3187-
// operate on vectors with 2 or less components. When largers vectors are
3188-
// seen. Split them, recurse, then recombine them.
3189-
if (ComponentCount > 2) {
3190-
unsigned LeftComponentCount = ComponentCount / 2;
3191-
unsigned RightComponentCount = ComponentCount - LeftComponentCount;
3192-
bool LeftIsVector = LeftComponentCount > 1;
3193-
3194-
// Split the SrcReg in half into 2 smaller vec registers
3195-
// (ie i64x4 -> i64x2, i64x2)
3196-
MachineIRBuilder MIRBuilder(I);
3197-
SPIRVType *OpType = GR.getOrCreateSPIRVIntegerType(64, MIRBuilder);
3198-
SPIRVType *LeftVecOpType;
3199-
SPIRVType *LeftVecResType;
3200-
if (LeftIsVector) {
3201-
LeftVecOpType =
3202-
GR.getOrCreateSPIRVVectorType(OpType, LeftComponentCount, MIRBuilder);
3203-
LeftVecResType = GR.getOrCreateSPIRVVectorType(
3204-
BaseType, LeftComponentCount, MIRBuilder);
3190+
// Split the SrcReg in half into 2 smaller vec registers
3191+
// (ie i64x4 -> i64x2, i64x2)
3192+
MachineIRBuilder MIRBuilder(I);
3193+
SPIRVType *OpType = GR.getOrCreateSPIRVIntegerType(64, MIRBuilder);
3194+
SPIRVType *LeftVecOpType;
3195+
SPIRVType *LeftVecResType;
3196+
if (LeftIsVector) {
3197+
LeftVecOpType =
3198+
GR.getOrCreateSPIRVVectorType(OpType, LeftComponentCount, MIRBuilder);
3199+
LeftVecResType =
3200+
GR.getOrCreateSPIRVVectorType(BaseType, LeftComponentCount, MIRBuilder);
32053201
} else {
32063202
LeftVecOpType = OpType;
32073203
LeftVecResType = BaseType;
@@ -3219,6 +3215,8 @@ bool SPIRVInstructionSelector::selectFirstBitSet64(
32193215

32203216
bool Result;
32213217

3218+
// Extract the left half from the SrcReg into LeftSideIn
3219+
// accounting for the special case when it only has one element
32223220
if (LeftIsVector) {
32233221
auto MIB =
32243222
BuildMI(*I.getParent(), I, I.getDebugLoc(),
@@ -3240,6 +3238,9 @@ bool SPIRVInstructionSelector::selectFirstBitSet64(
32403238
SPIRV::OpVectorExtractDynamic);
32413239
}
32423240

3241+
// Extract the right half from the SrcReg into RightSideIn.
3242+
// Right will always be a vector since the only time one element is left is
3243+
// when Component == 3, and in that case Left is one element.
32433244
auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
32443245
TII.get(SPIRV::OpVectorShuffle))
32453246
.addDef(RightSideIn)
@@ -3254,7 +3255,7 @@ bool SPIRVInstructionSelector::selectFirstBitSet64(
32543255

32553256
Result = Result && MIB.constrainAllUses(TII, TRI, RBI);
32563257

3257-
// Recursively call selectFirstBitSet64 on the 2 registers
3258+
// Recursively call selectFirstBitSet64 on the 2 halves
32583259
Register LeftSideOut =
32593260
MRI->createVirtualRegister(GR.getRegClass(LeftVecResType));
32603261
Register RightSideOut =
@@ -3271,6 +3272,26 @@ bool SPIRVInstructionSelector::selectFirstBitSet64(
32713272
return Result &&
32723273
selectOpWithSrcs(ResVReg, ResType, I, {LeftSideOut, RightSideOut},
32733274
SPIRV::OpCompositeConstruct);
3275+
}
3276+
3277+
bool SPIRVInstructionSelector::selectFirstBitSet64(
3278+
Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
3279+
Register SrcReg, unsigned BitSetOpcode, bool SwapPrimarySide) const {
3280+
unsigned ComponentCount = GR.getScalarOrVectorComponentCount(ResType);
3281+
SPIRVType *BaseType = GR.retrieveScalarOrVectorIntType(ResType);
3282+
bool ZeroAsNull = STI.isOpenCLEnv();
3283+
Register ConstIntZero =
3284+
GR.getOrCreateConstInt(0, I, BaseType, TII, ZeroAsNull);
3285+
Register ConstIntOne =
3286+
GR.getOrCreateConstInt(1, I, BaseType, TII, ZeroAsNull);
3287+
3288+
// SPIRV doesn't support vectors with more than 4 components. Since the
3289+
// algoritm below converts i64 -> i32x2 and i64x4 -> i32x8 it can only
3290+
// operate on vectors with 2 or less components. When largers vectors are
3291+
// seen. Split them, recurse, then recombine them.
3292+
if (ComponentCount > 2) {
3293+
return selectFirstBitSet64Overflow(ResVReg, ResType, I, SrcReg,
3294+
BitSetOpcode, SwapPrimarySide);
32743295
}
32753296

32763297
// 1. Split int64 into 2 pieces using a bitcast
@@ -3362,6 +3383,9 @@ bool SPIRVInstructionSelector::selectFirstBitSet64(
33623383
Register SecondaryReg;
33633384
Register PrimaryShiftReg;
33643385
Register SecondaryShiftReg;
3386+
3387+
// By default the emitted opcodes check for the set bit from the MSB side.
3388+
// Setting SwapPrimarySide checks the set bit from the LSB side
33653389
if (SwapPrimarySide) {
33663390
PrimaryReg = LowReg;
33673391
SecondaryReg = HighReg;

0 commit comments

Comments
 (0)