| 2919 | } |
| 2920 | |
| 2921 | FoldingRule BitReverseScalarOrVector() { |
| 2922 | return [](IRContext* context, Instruction* inst, |
| 2923 | const std::vector<const analysis::Constant*>& constants) { |
| 2924 | assert(inst->opcode() == spv::Op::OpBitReverse && constants.size() == 1); |
| 2925 | if (constants[0] == nullptr) return false; |
| 2926 | |
| 2927 | const analysis::Type* type = |
| 2928 | context->get_type_mgr()->GetType(inst->type_id()); |
| 2929 | assert(!HasFloatingPoint(type) && |
| 2930 | "BitReverse cannot be applied to floating point types."); |
| 2931 | assert((type->AsInteger() || type->AsVector()) && |
| 2932 | "BitReverse can only be applied to integer scalars or vectors."); |
| 2933 | assert((ElementWidth(type) == 32) && |
| 2934 | "BitReverse can only be applied to integer types of width 32"); |
| 2935 | |
| 2936 | analysis::ConstantManager* const_mgr = context->get_constant_mgr(); |
| 2937 | std::vector<uint32_t> words = |
| 2938 | GetWordsFromNumericScalarOrVectorConstant(const_mgr, constants[0]); |
| 2939 | if (words.size() == 0) return false; |
| 2940 | |
| 2941 | for (uint32_t& word : words) { |
| 2942 | // Reverse the bits in each word. |
| 2943 | word = ((word & 0x55555555) << 1) | ((word >> 1) & 0x55555555); |
| 2944 | word = ((word & 0x33333333) << 2) | ((word >> 2) & 0x33333333); |
| 2945 | word = ((word & 0x0F0F0F0F) << 4) | ((word >> 4) & 0x0F0F0F0F); |
| 2946 | word = ((word & 0x00FF00FF) << 8) | ((word >> 8) & 0x00FF00FF); |
| 2947 | word = (word << 16) | (word >> 16); |
| 2948 | } |
| 2949 | |
| 2950 | const analysis::Constant* bitreversed_constant = |
| 2951 | ConvertWordsToNumericScalarOrVectorConstant(const_mgr, words, type); |
| 2952 | if (!bitreversed_constant) return false; |
| 2953 | |
| 2954 | auto new_feeder_id = |
| 2955 | const_mgr->GetDefiningInstruction(bitreversed_constant, inst->type_id()) |
| 2956 | ->result_id(); |
| 2957 | inst->SetOpcode(spv::Op::OpCopyObject); |
| 2958 | inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {new_feeder_id}}}); |
| 2959 | return true; |
| 2960 | }; |
| 2961 | } |
| 2962 | |
| 2963 | FoldingRule RedundantSelect() { |
| 2964 | // An OpSelect instruction where both values are the same or the condition is |
no test coverage detected