| 2857 | } |
| 2858 | |
| 2859 | FoldingRule BitCastScalarOrVector() { |
| 2860 | return [](IRContext* context, Instruction* inst, |
| 2861 | const std::vector<const analysis::Constant*>& constants) { |
| 2862 | assert(inst->opcode() == spv::Op::OpBitcast && constants.size() == 1); |
| 2863 | if (constants[0] == nullptr) return false; |
| 2864 | |
| 2865 | const analysis::Type* type = |
| 2866 | context->get_type_mgr()->GetType(inst->type_id()); |
| 2867 | if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed()) |
| 2868 | return false; |
| 2869 | |
| 2870 | analysis::ConstantManager* const_mgr = context->get_constant_mgr(); |
| 2871 | std::vector<uint32_t> words = |
| 2872 | GetWordsFromNumericScalarOrVectorConstant(const_mgr, constants[0]); |
| 2873 | if (words.size() == 0) return false; |
| 2874 | |
| 2875 | const analysis::Constant* bitcasted_constant = |
| 2876 | ConvertWordsToNumericScalarOrVectorConstant(const_mgr, words, type); |
| 2877 | if (!bitcasted_constant) return false; |
| 2878 | |
| 2879 | auto new_feeder_id = |
| 2880 | const_mgr->GetDefiningInstruction(bitcasted_constant, inst->type_id()) |
| 2881 | ->result_id(); |
| 2882 | inst->SetOpcode(spv::Op::OpCopyObject); |
| 2883 | inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {new_feeder_id}}}); |
| 2884 | return true; |
| 2885 | }; |
| 2886 | } |
| 2887 | |
| 2888 | // Remove indirect bitcasts which have no effect. |
| 2889 | // uint32 x; asuint32(x) => x |
no test coverage detected