@@ -647,6 +647,52 @@ spv_result_t ValidateSpecConstantOp(ValidationState_t& _,
647647 return SPV_SUCCESS;
648648}
649649
650+ spv_result_t ValidateConstantFunctionPointerINTEL (ValidationState_t& _,
651+ const Instruction* inst) {
652+ const auto result_type = _.FindDef (inst->type_id ());
653+ // Result Type must be a pointer type
654+ if (result_type->opcode () != spv::Op::OpTypePointer &&
655+ result_type->opcode () != spv::Op::OpTypeUntypedPointerKHR) {
656+ return _.diag (SPV_ERROR_INVALID_ID, inst)
657+ << " OpConstantFunctionPointerINTEL Result Type <id> "
658+ << _.getIdName (inst->type_id ()) << " is not a pointer type" ;
659+ }
660+
661+ // For typed pointers, check that pointee is a function type
662+ const Instruction* pointee_type = nullptr ;
663+ if (result_type->opcode () == spv::Op::OpTypePointer) {
664+ pointee_type = _.FindDef (result_type->GetOperandAs <uint32_t >(2 ));
665+ if (pointee_type->opcode () != spv::Op::OpTypeFunction) {
666+ return _.diag (SPV_ERROR_INVALID_ID, inst)
667+ << " OpConstantFunctionPointerINTEL Result Type <id> "
668+ << _.getIdName (inst->type_id ())
669+ << " must be a pointer to function type" ;
670+ }
671+ }
672+
673+ // Validate that the function operand refers to an OpFunction
674+ const uint32_t function_id = inst->GetOperandAs <uint32_t >(2 );
675+ const auto function_inst = _.FindDef (function_id);
676+ if (function_inst->opcode () != spv::Op::OpFunction) {
677+ return _.diag (SPV_ERROR_INVALID_ID, inst)
678+ << " OpConstantFunctionPointerINTEL Function operand <id> "
679+ << _.getIdName (function_id) << " is not an OpFunction" ;
680+ }
681+
682+ // For typed pointers, validate that function type matches pointee type
683+ if (pointee_type) {
684+ const uint32_t function_type_id = function_inst->GetOperandAs <uint32_t >(3 );
685+ if (function_type_id != pointee_type->id ()) {
686+ return _.diag (SPV_ERROR_INVALID_ID, inst)
687+ << " OpConstantFunctionPointerINTEL Function operand <id> "
688+ << _.getIdName (function_id)
689+ << " type does not match the pointer's function type" ;
690+ }
691+ }
692+
693+ return SPV_SUCCESS;
694+ }
695+
650696} // namespace
651697
652698spv_result_t ConstantPass (ValidationState_t& _, const Instruction* inst) {
@@ -681,6 +727,10 @@ spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst) {
681727 case spv::Op::OpConstantSizeOfEXT:
682728 if (auto error = ValidateConstantSizeOfEXT (_, inst)) return error;
683729 break ;
730+ case spv::Op::OpConstantFunctionPointerINTEL:
731+ if (auto error = ValidateConstantFunctionPointerINTEL (_, inst))
732+ return error;
733+ break ;
684734 default :
685735 break ;
686736 }
0 commit comments