@@ -81,7 +81,6 @@ class SPIRVAsmPrinter : public AsmPrinter {
8181 void outputExecutionMode (const Module &M);
8282 void outputAnnotations (const Module &M);
8383 void outputModuleSections ();
84- void outputFPFastMathDefaultInfo ();
8584 bool isHidden () {
8685 return MF->getFunction ()
8786 .getFnAttribute (SPIRV_BACKEND_SERVICE_FUN_NAME)
@@ -499,27 +498,11 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
499498 NamedMDNode *Node = M.getNamedMetadata (" spirv.ExecutionMode" );
500499 if (Node) {
501500 for (unsigned i = 0 ; i < Node->getNumOperands (); i++) {
502- // If SPV_KHR_float_controls2 is enabled and we find any of
503- // FPFastMathDefault, ContractionOff or SignedZeroInfNanPreserve execution
504- // modes, skip it, it'll be done somewhere else.
505- if (ST->canUseExtension (SPIRV::Extension::SPV_KHR_float_controls2)) {
506- const auto EM =
507- cast<ConstantInt>(
508- cast<ConstantAsMetadata>((Node->getOperand (i))->getOperand (1 ))
509- ->getValue ())
510- ->getZExtValue ();
511- if (EM == SPIRV::ExecutionMode::FPFastMathDefault ||
512- EM == SPIRV::ExecutionMode::ContractionOff ||
513- EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve)
514- continue ;
515- }
516-
517501 MCInst Inst;
518502 Inst.setOpcode (SPIRV::OpExecutionMode);
519503 addOpsFromMDNode (cast<MDNode>(Node->getOperand (i)), Inst, MAI);
520504 outputMCInst (Inst);
521505 }
522- outputFPFastMathDefaultInfo ();
523506 }
524507 for (auto FI = M.begin (), E = M.end (); FI != E; ++FI) {
525508 const Function &F = *FI;
@@ -569,84 +552,12 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
569552 }
570553 if (ST->isKernel () && !M.getNamedMetadata (" spirv.ExecutionMode" ) &&
571554 !M.getNamedMetadata (" opencl.enable.FP_CONTRACT" )) {
572- if (ST->canUseExtension (SPIRV::Extension::SPV_KHR_float_controls2)) {
573- // When SPV_KHR_float_controls2 is enabled, ContractionOff is
574- // deprecated. We need to use FPFastMathDefault with the appropriate
575- // flags instead. Since FPFastMathDefault takes a target type, we need
576- // to emit it for each floating-point type that exists in the module
577- // to match the effect of ContractionOff. As of now, there are 3 FP
578- // types: fp16, fp32 and fp64.
579-
580- // We only end up here because there is no "spirv.ExecutionMode"
581- // metadata, so that means no FPFastMathDefault. Therefore, we only
582- // need to make sure AllowContract is set to 0, as the rest of flags.
583- // We still need to emit the OpExecutionMode instruction, otherwise
584- // it's up to the client API to define the flags. Therefore, we need
585- // to find the constant with 0 value.
586-
587- // Collect the SPIRVTypes for fp16, fp32, and fp64 and the constant of
588- // type int32 with 0 value to represent the FP Fast Math Mode.
589- std::vector<const MachineInstr *> SPIRVFloatTypes;
590- const MachineInstr *ConstZero = nullptr ;
591- for (const MachineInstr *MI :
592- MAI->getMSInstrs (SPIRV::MB_TypeConstVars)) {
593- // Skip if the instruction is not OpTypeFloat or OpConstant.
594- unsigned OpCode = MI->getOpcode ();
595- if (OpCode != SPIRV::OpTypeFloat && OpCode != SPIRV::OpConstantNull)
596- continue ;
597-
598- // Collect the SPIRV type if it's a float.
599- if (OpCode == SPIRV::OpTypeFloat) {
600- // Skip if the target type is not fp16, fp32, fp64.
601- const unsigned OpTypeFloatSize = MI->getOperand (1 ).getImm ();
602- if (OpTypeFloatSize != 16 && OpTypeFloatSize != 32 &&
603- OpTypeFloatSize != 64 ) {
604- continue ;
605- }
606- SPIRVFloatTypes.push_back (MI);
607- } else {
608- // Check if the constant is int32, if not skip it.
609- const MachineRegisterInfo &MRI = MI->getMF ()->getRegInfo ();
610- MachineInstr *TypeMI = MRI.getVRegDef (MI->getOperand (1 ).getReg ());
611- if (!TypeMI || TypeMI->getOperand (1 ).getImm () != 32 )
612- continue ;
613-
614- ConstZero = MI;
615- }
616- }
617-
618- // When SPV_KHR_float_controls2 is enabled, ContractionOff is
619- // deprecated. We need to use FPFastMathDefault with the appropriate
620- // flags instead. Since FPFastMathDefault takes a target type, we need
621- // to emit it for each floating-point type that exists in the module
622- // to match the effect of ContractionOff. As of now, there are 3 FP
623- // types: fp16, fp32 and fp64.
624- for (const MachineInstr *MI : SPIRVFloatTypes) {
625- MCInst Inst;
626- Inst.setOpcode (SPIRV::OpExecutionModeId);
627- Inst.addOperand (MCOperand::createReg (FReg));
628- unsigned EM =
629- static_cast <unsigned >(SPIRV::ExecutionMode::FPFastMathDefault);
630- Inst.addOperand (MCOperand::createImm (EM));
631- const MachineFunction *MF = MI->getMF ();
632- MCRegister TypeReg =
633- MAI->getRegisterAlias (MF, MI->getOperand (0 ).getReg ());
634- Inst.addOperand (MCOperand::createReg (TypeReg));
635- assert (ConstZero && " There should be a constant zero." );
636- MCRegister ConstReg = MAI->getRegisterAlias (
637- ConstZero->getMF (), ConstZero->getOperand (0 ).getReg ());
638- Inst.addOperand (MCOperand::createReg (ConstReg));
639- outputMCInst (Inst);
640- }
641- } else {
642- MCInst Inst;
643- Inst.setOpcode (SPIRV::OpExecutionMode);
644- Inst.addOperand (MCOperand::createReg (FReg));
645- unsigned EM =
646- static_cast <unsigned >(SPIRV::ExecutionMode::ContractionOff);
647- Inst.addOperand (MCOperand::createImm (EM));
648- outputMCInst (Inst);
649- }
555+ MCInst Inst;
556+ Inst.setOpcode (SPIRV::OpExecutionMode);
557+ Inst.addOperand (MCOperand::createReg (FReg));
558+ unsigned EM = static_cast <unsigned >(SPIRV::ExecutionMode::ContractionOff);
559+ Inst.addOperand (MCOperand::createImm (EM));
560+ outputMCInst (Inst);
650561 }
651562 }
652563}
@@ -695,101 +606,6 @@ void SPIRVAsmPrinter::outputAnnotations(const Module &M) {
695606 }
696607}
697608
698- void SPIRVAsmPrinter::outputFPFastMathDefaultInfo () {
699- // Collect the SPIRVTypes that are OpTypeFloat and the constants of type
700- // int32, that might be used as FP Fast Math Mode.
701- std::vector<const MachineInstr *> SPIRVFloatTypes;
702- // Hashtable to associate immediate values with the constant holding them.
703- std::unordered_map<int , const MachineInstr *> ConstMap;
704- for (const MachineInstr *MI : MAI->getMSInstrs (SPIRV::MB_TypeConstVars)) {
705- // Skip if the instruction is not OpTypeFloat or OpConstant.
706- unsigned OpCode = MI->getOpcode ();
707- if (OpCode != SPIRV::OpTypeFloat && OpCode != SPIRV::OpConstantI &&
708- OpCode != SPIRV::OpConstantNull)
709- continue ;
710-
711- // Collect the SPIRV type if it's a float.
712- if (OpCode == SPIRV::OpTypeFloat) {
713- SPIRVFloatTypes.push_back (MI);
714- } else {
715- // Check if the constant is int32, if not skip it.
716- const MachineRegisterInfo &MRI = MI->getMF ()->getRegInfo ();
717- MachineInstr *TypeMI = MRI.getVRegDef (MI->getOperand (1 ).getReg ());
718- if (!TypeMI || TypeMI->getOpcode () != SPIRV::OpTypeInt ||
719- TypeMI->getOperand (1 ).getImm () != 32 )
720- continue ;
721-
722- if (OpCode == SPIRV::OpConstantI)
723- ConstMap[MI->getOperand (2 ).getImm ()] = MI;
724- else
725- ConstMap[0 ] = MI;
726- }
727- }
728-
729- for (const auto &[Func, FPFastMathDefaultInfoVec] :
730- MAI->FPFastMathDefaultInfoMap ) {
731- if (FPFastMathDefaultInfoVec.empty ())
732- continue ;
733-
734- for (const MachineInstr *MI : SPIRVFloatTypes) {
735- unsigned OpTypeFloatSize = MI->getOperand (1 ).getImm ();
736- unsigned Index = SPIRV::FPFastMathDefaultInfoVector::
737- computeFPFastMathDefaultInfoVecIndex (OpTypeFloatSize);
738- assert (Index < FPFastMathDefaultInfoVec.size () &&
739- " Index out of bounds for FPFastMathDefaultInfoVec" );
740- const auto &FPFastMathDefaultInfo = FPFastMathDefaultInfoVec[Index];
741- assert (FPFastMathDefaultInfo.Ty &&
742- " Expected target type for FPFastMathDefaultInfo" );
743- assert (FPFastMathDefaultInfo.Ty ->getScalarSizeInBits () ==
744- OpTypeFloatSize &&
745- " Mismatched float type size" );
746- MCInst Inst;
747- Inst.setOpcode (SPIRV::OpExecutionModeId);
748- MCRegister FuncReg = MAI->getFuncReg (Func);
749- assert (FuncReg.isValid ());
750- Inst.addOperand (MCOperand::createReg (FuncReg));
751- Inst.addOperand (
752- MCOperand::createImm (SPIRV::ExecutionMode::FPFastMathDefault));
753- MCRegister TypeReg =
754- MAI->getRegisterAlias (MI->getMF (), MI->getOperand (0 ).getReg ());
755- Inst.addOperand (MCOperand::createReg (TypeReg));
756- unsigned Flags = FPFastMathDefaultInfo.FastMathFlags ;
757- if (FPFastMathDefaultInfo.ContractionOff &&
758- (Flags & SPIRV::FPFastMathMode::AllowContract))
759- report_fatal_error (
760- " Conflicting FPFastMathFlags: ContractionOff and AllowContract" );
761-
762- if (FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
763- !(Flags &
764- (SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
765- SPIRV::FPFastMathMode::NSZ))) {
766- if (FPFastMathDefaultInfo.FPFastMathDefault )
767- report_fatal_error (" Conflicting FPFastMathFlags: "
768- " SignedZeroInfNanPreserve but at least one of "
769- " NotNaN/NotInf/NSZ is enabled." );
770- }
771-
772- // Don't emit if none of the execution modes was used.
773- if (Flags == SPIRV::FPFastMathMode::None &&
774- !FPFastMathDefaultInfo.ContractionOff &&
775- !FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
776- !FPFastMathDefaultInfo.FPFastMathDefault )
777- continue ;
778-
779- // Retrieve the constant instruction for the immediate value.
780- auto It = ConstMap.find (Flags);
781- if (It == ConstMap.end ())
782- report_fatal_error (" Expected constant instruction for FP Fast Math "
783- " Mode operand of FPFastMathDefault execution mode." );
784- const MachineInstr *ConstMI = It->second ;
785- MCRegister ConstReg = MAI->getRegisterAlias (
786- ConstMI->getMF (), ConstMI->getOperand (0 ).getReg ());
787- Inst.addOperand (MCOperand::createReg (ConstReg));
788- outputMCInst (Inst);
789- }
790- }
791- }
792-
793609void SPIRVAsmPrinter::outputModuleSections () {
794610 const Module *M = MMI->getModule ();
795611 // Get the global subtarget to output module-level info.
@@ -798,17 +614,15 @@ void SPIRVAsmPrinter::outputModuleSections() {
798614 MAI = &SPIRVModuleAnalysis::MAI;
799615 assert (ST && TII && MAI && M && " Module analysis is required" );
800616 // Output instructions according to the Logical Layout of a Module:
801- // 1,2. All OpCapability instructions, then optional OpExtension
802- // instructions.
617+ // 1,2. All OpCapability instructions, then optional OpExtension instructions.
803618 outputGlobalRequirements ();
804619 // 3. Optional OpExtInstImport instructions.
805620 outputOpExtInstImports (*M);
806621 // 4. The single required OpMemoryModel instruction.
807622 outputOpMemoryModel ();
808623 // 5. All entry point declarations, using OpEntryPoint.
809624 outputEntryPoints ();
810- // 6. Execution-mode declarations, using OpExecutionMode or
811- // OpExecutionModeId.
625+ // 6. Execution-mode declarations, using OpExecutionMode or OpExecutionModeId.
812626 outputExecutionMode (*M);
813627 // 7a. Debug: all OpString, OpSourceExtension, OpSource, and
814628 // OpSourceContinued, without forward references.
0 commit comments