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

Function MergeSubAddArithmetic

source/opt/folding_rules.cpp:1365–1428  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

1363// 2 - (x + 2) = 0 - x
1364// 2 - (2 + x) = 0 - x
1365FoldingRule MergeSubAddArithmetic() {
1366 return [](IRContext* context, Instruction* inst,
1367 const std::vector<const analysis::Constant*>& constants) {
1368 assert(inst->opcode() == spv::Op::OpFSub ||
1369 inst->opcode() == spv::Op::OpISub);
1370 const analysis::Type* type =
1371 context->get_type_mgr()->GetType(inst->type_id());
1372
1373 if (type->IsCooperativeMatrix()) {
1374 return false;
1375 }
1376
1377 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
1378 bool uses_float = HasFloatingPoint(type);
1379 if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false;
1380
1381 uint32_t width = ElementWidth(type);
1382 if (width != 32 && width != 64) return false;
1383
1384 const analysis::Constant* const_input1 = ConstInput(constants);
1385 if (!const_input1) return false;
1386 Instruction* other_inst = NonConstInput(context, constants[0], inst);
1387 if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
1388 return false;
1389
1390 if (other_inst->opcode() == spv::Op::OpFAdd ||
1391 other_inst->opcode() == spv::Op::OpIAdd) {
1392 std::vector<const analysis::Constant*> other_constants =
1393 const_mgr->GetOperandConstants(other_inst);
1394 const analysis::Constant* const_input2 = ConstInput(other_constants);
1395 if (!const_input2) return false;
1396
1397 Instruction* non_const_input =
1398 NonConstInput(context, other_constants[0], other_inst);
1399
1400 // If the first operand of the sub is not a constant, swap the constants
1401 // so the subtraction has the correct operands.
1402 if (constants[0] == nullptr) std::swap(const_input1, const_input2);
1403 // Subtract the constants.
1404 uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(),
1405 const_input1, const_input2);
1406 spv::Op op = inst->opcode();
1407 uint32_t op1 = 0;
1408 uint32_t op2 = 0;
1409 if (constants[0] == nullptr) {
1410 // Non-constant operand is first. Change the opcode.
1411 op1 = non_const_input->result_id();
1412 op2 = merged_id;
1413 op = other_inst->opcode();
1414 } else {
1415 // Constant operand is first.
1416 op1 = merged_id;
1417 op2 = non_const_input->result_id();
1418 }
1419 if (op1 == 0 || op2 == 0) return false;
1420
1421 inst->SetOpcode(op);
1422 inst->SetInOperands(

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