| 520 | } |
| 521 | |
| 522 | ConstantFoldingRule FoldMatrixTimesVector() { |
| 523 | return [](IRContext* context, Instruction* inst, |
| 524 | const std::vector<const analysis::Constant*>& constants) |
| 525 | -> const analysis::Constant* { |
| 526 | assert(inst->opcode() == spv::Op::OpMatrixTimesVector); |
| 527 | analysis::ConstantManager* const_mgr = context->get_constant_mgr(); |
| 528 | analysis::TypeManager* type_mgr = context->get_type_mgr(); |
| 529 | |
| 530 | if (!inst->IsFloatingPointFoldingAllowed()) { |
| 531 | if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) { |
| 532 | return nullptr; |
| 533 | } |
| 534 | } |
| 535 | |
| 536 | const analysis::Constant* c1 = constants[0]; |
| 537 | const analysis::Constant* c2 = constants[1]; |
| 538 | |
| 539 | if (c1 == nullptr || c2 == nullptr) { |
| 540 | return nullptr; |
| 541 | } |
| 542 | |
| 543 | // Check result type. |
| 544 | const analysis::Type* result_type = type_mgr->GetType(inst->type_id()); |
| 545 | const analysis::Vector* vector_type = result_type->AsVector(); |
| 546 | assert(vector_type != nullptr); |
| 547 | const analysis::Type* element_type = vector_type->element_type(); |
| 548 | assert(element_type != nullptr); |
| 549 | const analysis::Float* float_type = element_type->AsFloat(); |
| 550 | assert(float_type != nullptr); |
| 551 | |
| 552 | // Check types of c1 and c2. |
| 553 | assert(c1->type()->AsMatrix()->element_type() == vector_type); |
| 554 | assert(c2->type()->AsVector()->element_type() == element_type); |
| 555 | |
| 556 | uint32_t resultVectorSize = result_type->AsVector()->element_count(); |
| 557 | std::vector<uint32_t> ids; |
| 558 | |
| 559 | if ((c1 && c1->IsZero()) || (c2 && c2->IsZero())) { |
| 560 | std::vector<uint32_t> words(float_type->width() / 32, 0); |
| 561 | for (uint32_t i = 0; i < resultVectorSize; ++i) { |
| 562 | const analysis::Constant* new_elem = |
| 563 | const_mgr->GetConstant(float_type, words); |
| 564 | ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); |
| 565 | } |
| 566 | return const_mgr->GetConstant(vector_type, ids); |
| 567 | } |
| 568 | |
| 569 | // Get a float vector that is the result of matrix-times-vector. |
| 570 | std::vector<const analysis::Constant*> c1_components = |
| 571 | c1->AsMatrixConstant()->GetComponents(); |
| 572 | std::vector<const analysis::Constant*> c2_components = |
| 573 | c2->GetVectorComponents(const_mgr); |
| 574 | |
| 575 | if (float_type->width() == 32) { |
| 576 | for (uint32_t i = 0; i < resultVectorSize; ++i) { |
| 577 | float result_scalar = 0.0f; |
| 578 | for (uint32_t j = 0; j < c1_components.size(); ++j) { |
| 579 | if (!c1_components[j]->AsNullConstant()) { |
no test coverage detected