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

Function MergeSubSubArithmetic

source/opt/folding_rules.cpp:1436–1506  ·  view source on GitHub ↗

Folds subtraction of a subtraction where each operand has a constant operand. Cases: (x - 2) - 2 = x - 4 (2 - x) - 2 = 0 - x 2 - (x - 2) = 4 - x 2 - (2 - x) = x + 0

Source from the content-addressed store, hash-verified

1434// 2 - (x - 2) = 4 - x
1435// 2 - (2 - x) = x + 0
1436FoldingRule MergeSubSubArithmetic() {
1437 return [](IRContext* context, Instruction* inst,
1438 const std::vector<const analysis::Constant*>& constants) {
1439 assert(inst->opcode() == spv::Op::OpFSub ||
1440 inst->opcode() == spv::Op::OpISub);
1441 const analysis::Type* type =
1442 context->get_type_mgr()->GetType(inst->type_id());
1443
1444 if (type->IsCooperativeMatrix()) {
1445 return false;
1446 }
1447
1448 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
1449 bool uses_float = HasFloatingPoint(type);
1450 if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false;
1451
1452 uint32_t width = ElementWidth(type);
1453 if (width != 32 && width != 64) return false;
1454
1455 const analysis::Constant* const_input1 = ConstInput(constants);
1456 if (!const_input1) return false;
1457 Instruction* other_inst = NonConstInput(context, constants[0], inst);
1458 if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
1459 return false;
1460
1461 if (other_inst->opcode() == spv::Op::OpFSub ||
1462 other_inst->opcode() == spv::Op::OpISub) {
1463 std::vector<const analysis::Constant*> other_constants =
1464 const_mgr->GetOperandConstants(other_inst);
1465 const analysis::Constant* const_input2 = ConstInput(other_constants);
1466 if (!const_input2) return false;
1467
1468 Instruction* non_const_input =
1469 NonConstInput(context, other_constants[0], other_inst);
1470
1471 // Merge the constants.
1472 uint32_t merged_id = 0;
1473 spv::Op merge_op = inst->opcode();
1474 if (other_constants[0] == nullptr) {
1475 merge_op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd;
1476 } else if (constants[0] == nullptr) {
1477 std::swap(const_input1, const_input2);
1478 }
1479 merged_id =
1480 PerformOperation(const_mgr, merge_op, const_input1, const_input2);
1481 if (merged_id == 0) return false;
1482
1483 spv::Op op = inst->opcode();
1484 if (constants[0] != nullptr && other_constants[0] != nullptr) {
1485 // Change the operation.
1486 op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd;
1487 }
1488
1489 uint32_t op1 = 0;
1490 uint32_t op2 = 0;
1491 if ((constants[0] == nullptr) ^ (other_constants[0] == nullptr)) {
1492 op1 = merged_id;
1493 op2 = non_const_input->result_id();

Callers 1

AddFoldingRulesMethod · 0.85

Calls 15

ElementWidthFunction · 0.85
ConstInputFunction · 0.85
NonConstInputFunction · 0.85
PerformOperationFunction · 0.85
get_type_mgrMethod · 0.80
IsCooperativeMatrixMethod · 0.80
get_constant_mgrMethod · 0.80
GetOperandConstantsMethod · 0.80
SetOpcodeMethod · 0.80
SetInOperandsMethod · 0.80
HasFloatingPointFunction · 0.70

Tested by

no test coverage detected