MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / PerformIntegerOperation

Function PerformIntegerOperation

source/opt/folding_rules.cpp:641–693  ·  view source on GitHub ↗

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 Integers.

Source from the content-addressed store, hash-verified

639// id. Returns 0 if the result is not a valid value. The input types must be
640// Integers.
641uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr,
642 spv::Op opcode,
643 const analysis::Constant* input1,
644 const analysis::Constant* input2) {
645 assert(input1->type()->AsInteger());
646 const analysis::Integer* type = input1->type()->AsInteger();
647 uint32_t width = type->AsInteger()->width();
648 assert(width == 32 || width == 64);
649 std::vector<uint32_t> words;
650 // Regardless of the sign of the constant, folding is performed on an unsigned
651 // interpretation of the constant data. This avoids signed integer overflow
652 // while folding, and works because sign is irrelevant for the IAdd, ISub and
653 // IMul instructions.
654#define FOLD_OP(op) \
655 if (width == 64) { \
656 uint64_t val = input1->GetU64() op input2->GetU64(); \
657 words = ExtractInts(val); \
658 } else { \
659 uint32_t val = input1->GetU32() op input2->GetU32(); \
660 words.push_back(val); \
661 } \
662 static_assert(true, "require extra semicolon")
663 switch (opcode) {
664 case spv::Op::OpIMul:
665 FOLD_OP(*);
666 break;
667 case spv::Op::OpSDiv:
668 case spv::Op::OpUDiv:
669 assert(false && "Should not merge integer division");
670 break;
671 case spv::Op::OpIAdd:
672 FOLD_OP(+);
673 break;
674 case spv::Op::OpISub:
675 FOLD_OP(-);
676 break;
677 case spv::Op::OpBitwiseXor:
678 FOLD_OP(^);
679 break;
680 case spv::Op::OpBitwiseOr:
681 FOLD_OP(|);
682 break;
683 case spv::Op::OpBitwiseAnd:
684 FOLD_OP(&);
685 break;
686 default:
687 assert(false && "Unexpected operation");
688 break;
689 }
690#undef FOLD_OP
691 const analysis::Constant* merged_const = const_mgr->GetConstant(type, words);
692 return const_mgr->GetDefiningInstruction(merged_const)->result_id();
693}
694
695// Performs |input1| |opcode| |input2| and returns the merged constant result
696// id. Returns 0 if the result is not a valid value. The input types must be

Callers 1

PerformOperationFunction · 0.85

Calls 6

AsIntegerMethod · 0.80
typeMethod · 0.45
widthMethod · 0.45
GetConstantMethod · 0.45
result_idMethod · 0.45

Tested by

no test coverage detected