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

Function ReassociateNestedAddSub

source/opt/folding_rules.cpp:1878–2024  ·  view source on GitHub ↗

Reassociate add/sub instructions, which have add/sub inputs, both of which contain a constant. e.g: (a + C0) - (C1 - b) = (C0 - C1) + (a + b) (C0 - a) + (b - C1) = (C0 - C1) + (b - a) (a - C0) - (b + C1) = (-C0 - C1) + (a - b)

Source from the content-addressed store, hash-verified

1876// (C0 - a) + (b - C1) = (C0 - C1) + (b - a)
1877// (a - C0) - (b + C1) = (-C0 - C1) + (a - b)
1878FoldingRule ReassociateNestedAddSub() {
1879 return [](IRContext* context, Instruction* inst,
1880 const std::vector<const analysis::Constant*>& constants) {
1881 assert(inst->opcode() == spv::Op::OpFAdd ||
1882 inst->opcode() == spv::Op::OpIAdd ||
1883 inst->opcode() == spv::Op::OpFSub ||
1884 inst->opcode() == spv::Op::OpISub);
1885
1886 // Handled by other folding rules.
1887 if (constants[0] || constants[1]) {
1888 return false;
1889 }
1890
1891 const analysis::Type* type =
1892 context->get_type_mgr()->GetType(inst->type_id());
1893
1894 if (type->IsCooperativeMatrix()) {
1895 return false;
1896 }
1897
1898 uint32_t width = ElementWidth(type);
1899 if (width != 32 && width != 64) return false;
1900
1901 bool uses_float = HasFloatingPoint(type);
1902 if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false;
1903
1904 analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
1905 Instruction* lhs = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
1906 Instruction* rhs = def_use_mgr->GetDef(inst->GetSingleWordInOperand(1));
1907
1908 spv::Op add_op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd;
1909 spv::Op sub_op = uses_float ? spv::Op::OpFSub : spv::Op::OpISub;
1910
1911 bool lhs_is_add = lhs->opcode() == add_op;
1912 bool lhs_is_sub = lhs->opcode() == sub_op;
1913 bool rhs_is_add = rhs->opcode() == add_op;
1914 bool rhs_is_sub = rhs->opcode() == sub_op;
1915 if (!(lhs_is_add || lhs_is_sub) || !(rhs_is_add || rhs_is_sub)) {
1916 return false;
1917 }
1918
1919 if (uses_float && (!lhs->IsFloatingPointFoldingAllowed() ||
1920 !rhs->IsFloatingPointFoldingAllowed())) {
1921 return false;
1922 }
1923
1924 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
1925 std::vector<const analysis::Constant*> lhs_constants =
1926 const_mgr->GetOperandConstants(lhs);
1927 if (!lhs_constants[0] && !lhs_constants[1]) {
1928 return false;
1929 }
1930
1931 std::vector<const analysis::Constant*> rhs_constants =
1932 const_mgr->GetOperandConstants(rhs);
1933 if (!rhs_constants[0] && !rhs_constants[1]) {
1934 return false;
1935 }

Callers 1

AddFoldingRulesMethod · 0.85

Calls 15

ElementWidthFunction · 0.85
NegateConstantFunction · 0.85
PerformOperationFunction · 0.85
get_type_mgrMethod · 0.80
IsCooperativeMatrixMethod · 0.80
get_constant_mgrMethod · 0.80
GetOperandConstantsMethod · 0.80
AddBinaryOpMethod · 0.80
SetOpcodeMethod · 0.80
SetInOperandsMethod · 0.80

Tested by

no test coverage detected