Performs |input1| |opcode| |input2| and returns the merged constant result id. Returns 0 if the result is not a valid value. The input types must be Float.
| 590 | // id. Returns 0 if the result is not a valid value. The input types must be |
| 591 | // Float. |
| 592 | uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, |
| 593 | spv::Op opcode, |
| 594 | const analysis::Constant* input1, |
| 595 | const analysis::Constant* input2) { |
| 596 | const analysis::Type* type = input1->type(); |
| 597 | assert(type->AsFloat()); |
| 598 | uint32_t width = type->AsFloat()->width(); |
| 599 | assert(width == 32 || width == 64); |
| 600 | std::vector<uint32_t> words; |
| 601 | #define FOLD_OP(op) \ |
| 602 | if (width == 64) { \ |
| 603 | utils::FloatProxy<double> val = \ |
| 604 | input1->GetDouble() op input2->GetDouble(); \ |
| 605 | double dval = val.getAsFloat(); \ |
| 606 | if (!IsValidResult(dval)) return 0; \ |
| 607 | words = val.GetWords(); \ |
| 608 | } else { \ |
| 609 | utils::FloatProxy<float> val = input1->GetFloat() op input2->GetFloat(); \ |
| 610 | float fval = val.getAsFloat(); \ |
| 611 | if (!IsValidResult(fval)) return 0; \ |
| 612 | words = val.GetWords(); \ |
| 613 | } \ |
| 614 | static_assert(true, "require extra semicolon") |
| 615 | switch (opcode) { |
| 616 | case spv::Op::OpFMul: |
| 617 | FOLD_OP(*); |
| 618 | break; |
| 619 | case spv::Op::OpFDiv: |
| 620 | if (HasZero(input2)) return 0; |
| 621 | FOLD_OP(/); |
| 622 | break; |
| 623 | case spv::Op::OpFAdd: |
| 624 | FOLD_OP(+); |
| 625 | break; |
| 626 | case spv::Op::OpFSub: |
| 627 | FOLD_OP(-); |
| 628 | break; |
| 629 | default: |
| 630 | assert(false && "Unexpected operation"); |
| 631 | break; |
| 632 | } |
| 633 | #undef FOLD_OP |
| 634 | const analysis::Constant* merged_const = const_mgr->GetConstant(type, words); |
| 635 | return const_mgr->GetDefiningInstruction(merged_const)->result_id(); |
| 636 | } |
| 637 | |
| 638 | // Performs |input1| |opcode| |input2| and returns the merged constant result |
| 639 | // id. Returns 0 if the result is not a valid value. The input types must be |
no test coverage detected