@@ -215,6 +215,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
215215 bool selectDot4AddPackedExpansion (Register ResVReg, const SPIRVType *ResType,
216216 MachineInstr &I) const ;
217217
218+ bool selectWaveReduceMax (Register ResVReg, const SPIRVType *ResType,
219+ MachineInstr &I, bool IsUnsigned) const ;
220+
218221 bool selectWaveReduceSum (Register ResVReg, const SPIRVType *ResType,
219222 MachineInstr &I) const ;
220223
@@ -2132,6 +2135,32 @@ bool SPIRVInstructionSelector::selectWaveActiveCountBits(
21322135 return Result;
21332136}
21342137
2138+ bool SPIRVInstructionSelector::selectWaveReduceMax (Register ResVReg,
2139+ const SPIRVType *ResType,
2140+ MachineInstr &I, bool IsUnsigned) const {
2141+ assert (I.getNumOperands () == 3 );
2142+ assert (I.getOperand (2 ).isReg ());
2143+ MachineBasicBlock &BB = *I.getParent ();
2144+ Register InputRegister = I.getOperand (2 ).getReg ();
2145+ SPIRVType *InputType = GR.getSPIRVTypeForVReg (InputRegister);
2146+
2147+ if (!InputType)
2148+ report_fatal_error (" Input Type could not be determined." );
2149+
2150+ SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType (32 , I, TII);
2151+ // Retreive the operation to use based on input type
2152+ bool IsFloatTy = GR.isScalarOrVectorOfType (InputRegister, SPIRV::OpTypeFloat);
2153+ auto IntegerOpcodeType = IsUnsigned ? SPIRV::OpGroupNonUniformUMax : SPIRV::OpGroupNonUniformSMax;
2154+ auto Opcode =
2155+ IsFloatTy ? SPIRV::OpGroupNonUniformFMax : IntegerOpcodeType;
2156+ return BuildMI (BB, I, I.getDebugLoc (), TII.get (Opcode))
2157+ .addDef (ResVReg)
2158+ .addUse (GR.getSPIRVTypeID (ResType))
2159+ .addUse (GR.getOrCreateConstInt (SPIRV::Scope::Subgroup, I, IntTy, TII))
2160+ .addImm (SPIRV::GroupOperation::Reduce)
2161+ .addUse (I.getOperand (2 ).getReg ());
2162+ }
2163+
21352164bool SPIRVInstructionSelector::selectWaveReduceSum (Register ResVReg,
21362165 const SPIRVType *ResType,
21372166 MachineInstr &I) const {
@@ -3086,6 +3115,10 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
30863115 return selectWaveOpInst (ResVReg, ResType, I, SPIRV::OpGroupNonUniformAny);
30873116 case Intrinsic::spv_wave_is_first_lane:
30883117 return selectWaveOpInst (ResVReg, ResType, I, SPIRV::OpGroupNonUniformElect);
3118+ case Intrinsic::spv_wave_reduce_umax:
3119+ return selectWaveReduceMax (ResVReg, ResType, I, /* IsUnsigned*/ true );
3120+ case Intrinsic::spv_wave_reduce_max:
3121+ return selectWaveReduceMax (ResVReg, ResType, I, /* IsUnsigned*/ false );
30893122 case Intrinsic::spv_wave_reduce_sum:
30903123 return selectWaveReduceSum (ResVReg, ResType, I);
30913124 case Intrinsic::spv_wave_readlane:
0 commit comments