@@ -220,8 +220,10 @@ class SPIRVInstructionSelector : public InstructionSelector {
220
220
bool selectConst (Register ResVReg, const SPIRVType *ResType,
221
221
MachineInstr &I) const ;
222
222
223
- bool selectSelect (Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
224
- bool IsSigned) const ;
223
+ bool selectSelect (Register ResVReg, const SPIRVType *ResType,
224
+ MachineInstr &I) const ;
225
+ bool selectSelectDefaultArgs (Register ResVReg, const SPIRVType *ResType,
226
+ MachineInstr &I, bool IsSigned) const ;
225
227
bool selectIToF (Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
226
228
bool IsSigned, unsigned Opcode) const ;
227
229
bool selectExt (Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
@@ -510,7 +512,18 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
510
512
if (isTypeFoldingSupported (Def->getOpcode ()) &&
511
513
Def->getOpcode () != TargetOpcode::G_CONSTANT &&
512
514
Def->getOpcode () != TargetOpcode::G_FCONSTANT) {
513
- bool Res = selectImpl (I, *CoverageInfo);
515
+ bool Res = false ;
516
+ if (Def->getOpcode () == TargetOpcode::G_SELECT) {
517
+ Register SelectDstReg = Def->getOperand (0 ).getReg ();
518
+ Res = selectSelect (SelectDstReg, GR.getSPIRVTypeForVReg (SelectDstReg),
519
+ *Def);
520
+ GR.invalidateMachineInstr (Def);
521
+ Def->removeFromParent ();
522
+ MRI->replaceRegWith (DstReg, SelectDstReg);
523
+ GR.invalidateMachineInstr (&I);
524
+ I.removeFromParent ();
525
+ } else
526
+ Res = selectImpl (I, *CoverageInfo);
514
527
LLVM_DEBUG ({
515
528
if (!Res && Def->getOpcode () != TargetOpcode::G_CONSTANT) {
516
529
dbgs () << " Unexpected pattern in ASSIGN_TYPE.\n Instruction: " ;
@@ -2565,8 +2578,52 @@ Register SPIRVInstructionSelector::buildOnesVal(bool AllOnes,
2565
2578
2566
2579
bool SPIRVInstructionSelector::selectSelect (Register ResVReg,
2567
2580
const SPIRVType *ResType,
2568
- MachineInstr &I,
2569
- bool IsSigned) const {
2581
+ MachineInstr &I) const {
2582
+ Register SelectFirstArg = I.getOperand (2 ).getReg ();
2583
+ Register SelectSecondArg = I.getOperand (3 ).getReg ();
2584
+ assert (ResType == GR.getSPIRVTypeForVReg (SelectFirstArg) &&
2585
+ ResType == GR.getSPIRVTypeForVReg (SelectSecondArg));
2586
+
2587
+ bool IsFloatTy =
2588
+ GR.isScalarOrVectorOfType (SelectFirstArg, SPIRV::OpTypeFloat);
2589
+ bool IsPtrTy =
2590
+ GR.isScalarOrVectorOfType (SelectFirstArg, SPIRV::OpTypePointer);
2591
+ bool IsVectorTy = GR.getSPIRVTypeForVReg (SelectFirstArg)->getOpcode () ==
2592
+ SPIRV::OpTypeVector;
2593
+
2594
+ bool IsScalarBool =
2595
+ GR.isScalarOfType (I.getOperand (1 ).getReg (), SPIRV::OpTypeBool);
2596
+ unsigned Opcode;
2597
+ if (IsVectorTy) {
2598
+ if (IsFloatTy) {
2599
+ Opcode = IsScalarBool ? SPIRV::OpSelectVFSCond : SPIRV::OpSelectVFVCond;
2600
+ } else if (IsPtrTy) {
2601
+ Opcode = IsScalarBool ? SPIRV::OpSelectVPSCond : SPIRV::OpSelectVPVCond;
2602
+ } else {
2603
+ Opcode = IsScalarBool ? SPIRV::OpSelectVISCond : SPIRV::OpSelectVIVCond;
2604
+ }
2605
+ } else {
2606
+ if (IsFloatTy) {
2607
+ Opcode = IsScalarBool ? SPIRV::OpSelectSFSCond : SPIRV::OpSelectVFVCond;
2608
+ } else if (IsPtrTy) {
2609
+ Opcode = IsScalarBool ? SPIRV::OpSelectSPSCond : SPIRV::OpSelectVPVCond;
2610
+ } else {
2611
+ Opcode = IsScalarBool ? SPIRV::OpSelectSISCond : SPIRV::OpSelectVIVCond;
2612
+ }
2613
+ }
2614
+ return BuildMI (*I.getParent (), I, I.getDebugLoc (), TII.get (Opcode))
2615
+ .addDef (ResVReg)
2616
+ .addUse (GR.getSPIRVTypeID (ResType))
2617
+ .addUse (I.getOperand (1 ).getReg ())
2618
+ .addUse (SelectFirstArg)
2619
+ .addUse (SelectSecondArg)
2620
+ .constrainAllUses (TII, TRI, RBI);
2621
+ }
2622
+
2623
+ bool SPIRVInstructionSelector::selectSelectDefaultArgs (Register ResVReg,
2624
+ const SPIRVType *ResType,
2625
+ MachineInstr &I,
2626
+ bool IsSigned) const {
2570
2627
// To extend a bool, we need to use OpSelect between constants.
2571
2628
Register ZeroReg = buildZerosVal (ResType, I);
2572
2629
Register OneReg = buildOnesVal (IsSigned, ResType, I);
@@ -2598,7 +2655,7 @@ bool SPIRVInstructionSelector::selectIToF(Register ResVReg,
2598
2655
TmpType = GR.getOrCreateSPIRVVectorType (TmpType, NumElts, I, TII);
2599
2656
}
2600
2657
SrcReg = createVirtualRegister (TmpType, &GR, MRI, MRI->getMF ());
2601
- selectSelect (SrcReg, TmpType, I, false );
2658
+ selectSelectDefaultArgs (SrcReg, TmpType, I, false );
2602
2659
}
2603
2660
return selectOpWithSrcs (ResVReg, ResType, I, {SrcReg}, Opcode);
2604
2661
}
@@ -2608,7 +2665,7 @@ bool SPIRVInstructionSelector::selectExt(Register ResVReg,
2608
2665
MachineInstr &I, bool IsSigned) const {
2609
2666
Register SrcReg = I.getOperand (1 ).getReg ();
2610
2667
if (GR.isScalarOrVectorOfType (SrcReg, SPIRV::OpTypeBool))
2611
- return selectSelect (ResVReg, ResType, I, IsSigned);
2668
+ return selectSelectDefaultArgs (ResVReg, ResType, I, IsSigned);
2612
2669
2613
2670
SPIRVType *SrcType = GR.getSPIRVTypeForVReg (SrcReg);
2614
2671
if (SrcType == ResType)
0 commit comments