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

Function MergeAddSubArithmetic

source/opt/folding_rules.cpp:1300–1357  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

1298// 2 + (x - 2) = x + 0
1299// 2 + (2 - x) = 4 - x
1300FoldingRule MergeAddSubArithmetic() {
1301 return [](IRContext* context, Instruction* inst,
1302 const std::vector<const analysis::Constant*>& constants) {
1303 assert(inst->opcode() == spv::Op::OpFAdd ||
1304 inst->opcode() == spv::Op::OpIAdd);
1305 const analysis::Type* type =
1306 context->get_type_mgr()->GetType(inst->type_id());
1307
1308 if (type->IsCooperativeMatrix()) {
1309 return false;
1310 }
1311
1312 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
1313 bool uses_float = HasFloatingPoint(type);
1314 if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false;
1315
1316 uint32_t width = ElementWidth(type);
1317 if (width != 32 && width != 64) return false;
1318
1319 const analysis::Constant* const_input1 = ConstInput(constants);
1320 if (!const_input1) return false;
1321 Instruction* other_inst = NonConstInput(context, constants[0], inst);
1322 if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
1323 return false;
1324
1325 if (other_inst->opcode() == spv::Op::OpFSub ||
1326 other_inst->opcode() == spv::Op::OpISub) {
1327 std::vector<const analysis::Constant*> other_constants =
1328 const_mgr->GetOperandConstants(other_inst);
1329 const analysis::Constant* const_input2 = ConstInput(other_constants);
1330 if (!const_input2) return false;
1331
1332 bool first_is_variable = other_constants[0] == nullptr;
1333 spv::Op op = inst->opcode();
1334 uint32_t op1 = 0;
1335 uint32_t op2 = 0;
1336 if (first_is_variable) {
1337 // Subtract constants. Non-constant operand is first.
1338 op1 = other_inst->GetSingleWordInOperand(0u);
1339 op2 = PerformOperation(const_mgr, other_inst->opcode(), const_input1,
1340 const_input2);
1341 } else {
1342 // Add constants. Constant operand is first. Change the opcode.
1343 op1 = PerformOperation(const_mgr, inst->opcode(), const_input1,
1344 const_input2);
1345 op2 = other_inst->GetSingleWordInOperand(1u);
1346 op = other_inst->opcode();
1347 }
1348 if (op1 == 0 || op2 == 0) return false;
1349
1350 inst->SetOpcode(op);
1351 inst->SetInOperands(
1352 {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}});
1353 return true;
1354 }
1355 return false;
1356 };
1357}

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

Tested by

no test coverage detected