@@ -2759,82 +2759,82 @@ bool SPIRVInstructionSelector::selectFirstBitHigh64(Register ResVReg,
2759
2759
Register FBHReg = MRI->createVirtualRegister (GR.getRegClass (postCastT));
2760
2760
Result &= selectFirstBitHigh32 (FBHReg, postCastT, I, bitcastReg, IsSigned);
2761
2761
2762
- // 3. check if result of each top 32 bits is == -1
2763
- // split result vector into vector of high bits and vector of low bits
2764
- // get high bits
2765
- // if ResType is a scalar we need a vector anyways because our code
2766
- // operates on vectors, even vectors of length one.
2767
- SPIRVType *VResType = ResType;
2762
+ // 3. split result vector into high bits and low bits
2763
+ Register HighReg = MRI->createVirtualRegister (GR.getRegClass (ResType));
2764
+ Register LowReg = MRI->createVirtualRegister (GR.getRegClass (ResType));
2765
+
2766
+ bool ZeroAsNull = STI.isOpenCLEnv ();
2768
2767
bool isScalarRes = ResType->getOpcode () != SPIRV::OpTypeVector;
2769
- if (isScalarRes)
2770
- VResType = GR.getOrCreateSPIRVVectorType (ResType, count, MIRBuilder);
2771
- // count should be one.
2768
+ if (isScalarRes) {
2769
+ // if scalar do a vector extract
2770
+ Result &= selectNAryOpWithSrcs (
2771
+ HighReg, ResType, I,
2772
+ {FBHReg, GR.getOrCreateConstInt (0 , I, ResType, TII, ZeroAsNull)},
2773
+ SPIRV::OpVectorExtractDynamic);
2774
+ Result &= selectNAryOpWithSrcs (
2775
+ LowReg, ResType, I,
2776
+ {FBHReg, GR.getOrCreateConstInt (1 , I, ResType, TII, ZeroAsNull)},
2777
+ SPIRV::OpVectorExtractDynamic);
2778
+ } else { // vector case do a shufflevector
2779
+ auto MIB = BuildMI (*I.getParent (), I, I.getDebugLoc (),
2780
+ TII.get (SPIRV::OpVectorShuffle))
2781
+ .addDef (HighReg)
2782
+ .addUse (GR.getSPIRVTypeID (ResType))
2783
+ .addUse (FBHReg)
2784
+ .addUse (FBHReg);
2785
+ // ^^ this vector will not be selected from; could be empty
2786
+ unsigned j;
2787
+ for (j = 0 ; j < count * 2 ; j += 2 ) {
2788
+ MIB.addImm (j);
2789
+ }
2790
+ Result &= MIB.constrainAllUses (TII, TRI, RBI);
2791
+
2792
+ // get low bits
2793
+ MIB = BuildMI (*I.getParent (), I, I.getDebugLoc (),
2794
+ TII.get (SPIRV::OpVectorShuffle))
2795
+ .addDef (LowReg)
2796
+ .addUse (GR.getSPIRVTypeID (ResType))
2797
+ .addUse (FBHReg)
2798
+ .addUse (FBHReg);
2799
+ // ^^ this vector will not be selected from; could be empty
2800
+ for (j = 1 ; j < count * 2 ; j += 2 ) {
2801
+ MIB.addImm (j);
2802
+ }
2803
+ Result &= MIB.constrainAllUses (TII, TRI, RBI);
2804
+ }
2805
+
2806
+ // 4. check if result of each top 32 bits is == -1
2807
+ SPIRVType *BoolType = GR.getOrCreateSPIRVBoolType (I, TII);
2808
+ if (!isScalarRes)
2809
+ BoolType = GR.getOrCreateSPIRVVectorType (BoolType, count, MIRBuilder);
2772
2810
2773
- Register HighReg = MRI->createVirtualRegister (GR.getRegClass (VResType));
2774
- auto MIB = BuildMI (*I.getParent (), I, I.getDebugLoc (),
2775
- TII.get (SPIRV::OpVectorShuffle))
2776
- .addDef (HighReg)
2777
- .addUse (GR.getSPIRVTypeID (VResType))
2778
- .addUse (FBHReg)
2779
- .addUse (FBHReg);
2780
- // ^^ this vector will not be selected from; could be empty
2781
- unsigned j;
2782
- for (j = 0 ; j < count * 2 ; j += 2 ) {
2783
- MIB.addImm (j);
2784
- }
2785
- Result &= MIB.constrainAllUses (TII, TRI, RBI);
2786
-
2787
- // get low bits
2788
- Register LowReg = MRI->createVirtualRegister (GR.getRegClass (VResType));
2789
- MIB = BuildMI (*I.getParent (), I, I.getDebugLoc (),
2790
- TII.get (SPIRV::OpVectorShuffle))
2791
- .addDef (LowReg)
2792
- .addUse (GR.getSPIRVTypeID (VResType))
2793
- .addUse (FBHReg)
2794
- .addUse (FBHReg);
2795
- // ^^ this vector will not be selected from; could be empty
2796
- for (j = 1 ; j < count * 2 ; j += 2 ) {
2797
- MIB.addImm (j);
2798
- }
2799
- Result &= MIB.constrainAllUses (TII, TRI, RBI);
2800
-
2801
- SPIRVType *BoolType = GR.getOrCreateSPIRVVectorType (
2802
- GR.getOrCreateSPIRVBoolType (I, TII), count, MIRBuilder);
2803
2811
// check if the high bits are == -1;
2804
- Register NegOneReg = GR.getOrCreateConstVector (-1 , I, VResType, TII);
2812
+ Register NegOneReg =
2813
+ GR.getOrCreateConstScalarOrVector (-1 , I, ResType, TII, ZeroAsNull);
2805
2814
// true if -1
2806
2815
Register BReg = MRI->createVirtualRegister (GR.getRegClass (BoolType));
2807
2816
Result &= selectNAryOpWithSrcs (BReg, BoolType, I, {HighReg, NegOneReg},
2808
2817
SPIRV::OpIEqual);
2809
2818
2810
2819
// Select low bits if true in BReg, otherwise high bits
2811
- Register TmpReg = MRI->createVirtualRegister (GR.getRegClass (VResType));
2812
- Result &= selectNAryOpWithSrcs (TmpReg, VResType, I, {BReg, LowReg, HighReg},
2813
- SPIRV::OpSelectVIVCond);
2820
+ unsigned selectOp =
2821
+ isScalarRes ? SPIRV::OpSelectSISCond : SPIRV::OpSelectVIVCond;
2822
+ Register TmpReg = MRI->createVirtualRegister (GR.getRegClass (ResType));
2823
+ Result &= selectNAryOpWithSrcs (TmpReg, ResType, I, {BReg, LowReg, HighReg},
2824
+ selectOp);
2814
2825
2815
2826
// Add 32 for high bits, 0 for low bits
2816
- Register ValReg = MRI->createVirtualRegister (GR.getRegClass (VResType));
2817
- bool ZeroAsNull = STI.isOpenCLEnv ();
2818
- Register Reg32 = GR.getOrCreateConstVector (32 , I, VResType, TII, ZeroAsNull);
2819
- Register Reg0 = GR.getOrCreateConstVector (0 , I, VResType, TII, ZeroAsNull);
2820
- Result &= selectNAryOpWithSrcs (ValReg, VResType, I, {BReg, Reg0, Reg32},
2821
- SPIRV::OpSelectVIVCond);
2822
-
2823
- Register AddReg = ResVReg;
2824
- if (isScalarRes)
2825
- AddReg = MRI->createVirtualRegister (GR.getRegClass (VResType));
2826
-
2827
- Result &= selectNAryOpWithSrcs (AddReg, VResType, I, {ValReg, TmpReg},
2828
- SPIRV::OpIAddV);
2829
-
2830
- // convert result back to scalar if necessary
2831
- if (!isScalarRes)
2832
- return Result;
2833
- else
2834
- return Result & selectNAryOpWithSrcs (
2835
- ResVReg, ResType, I,
2836
- {AddReg, GR.getOrCreateConstInt (0 , I, ResType, TII)},
2837
- SPIRV::OpVectorExtractDynamic);
2827
+ Register ValReg = MRI->createVirtualRegister (GR.getRegClass (ResType));
2828
+ Register Reg0 =
2829
+ GR.getOrCreateConstScalarOrVector (0 , I, ResType, TII, ZeroAsNull);
2830
+ Register Reg32 =
2831
+ GR.getOrCreateConstScalarOrVector (32 , I, ResType, TII, ZeroAsNull);
2832
+ Result &=
2833
+ selectNAryOpWithSrcs (ValReg, ResType, I, {BReg, Reg0, Reg32}, selectOp);
2834
+
2835
+ return Result &=
2836
+ selectNAryOpWithSrcs (ResVReg, ResType, I, {ValReg, TmpReg},
2837
+ isScalarRes ? SPIRV::OpIAddS : SPIRV::OpIAddV);
2838
2838
}
2839
2839
2840
2840
bool SPIRVInstructionSelector::selectFirstBitHigh (Register ResVReg,
0 commit comments