Folds subtraction, where one side is a negation. Cases: (-x) - 2 = -2 - x y - (-x) = x + y
| 1198 | // (-x) - 2 = -2 - x |
| 1199 | // y - (-x) = x + y |
| 1200 | FoldingRule MergeSubNegateArithmetic() { |
| 1201 | return [](IRContext* context, Instruction* inst, |
| 1202 | const std::vector<const analysis::Constant*>& constants) { |
| 1203 | assert(inst->opcode() == spv::Op::OpFSub || |
| 1204 | inst->opcode() == spv::Op::OpISub); |
| 1205 | const analysis::Type* type = |
| 1206 | context->get_type_mgr()->GetType(inst->type_id()); |
| 1207 | |
| 1208 | bool uses_float = HasFloatingPoint(type); |
| 1209 | if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; |
| 1210 | |
| 1211 | analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); |
| 1212 | Instruction* lhs = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); |
| 1213 | Instruction* rhs = def_use_mgr->GetDef(inst->GetSingleWordInOperand(1)); |
| 1214 | |
| 1215 | if (IsFoldableNegation(rhs)) { |
| 1216 | inst->SetOpcode(uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd); |
| 1217 | inst->SetInOperands( |
| 1218 | {{SPV_OPERAND_TYPE_ID, {lhs->result_id()}}, |
| 1219 | {SPV_OPERAND_TYPE_ID, {rhs->GetSingleWordInOperand(0)}}}); |
| 1220 | return true; |
| 1221 | } |
| 1222 | |
| 1223 | if (type->IsCooperativeMatrix()) { |
| 1224 | return false; |
| 1225 | } |
| 1226 | |
| 1227 | uint32_t width = ElementWidth(type); |
| 1228 | if (width != 32 && width != 64) return false; |
| 1229 | |
| 1230 | if (constants[1] && IsFoldableNegation(lhs)) { |
| 1231 | inst->SetInOperands( |
| 1232 | {{SPV_OPERAND_TYPE_ID, |
| 1233 | {NegateConstant(context->get_constant_mgr(), constants[1])}}, |
| 1234 | {SPV_OPERAND_TYPE_ID, {lhs->GetSingleWordInOperand(0)}}}); |
| 1235 | return true; |
| 1236 | } |
| 1237 | return false; |
| 1238 | }; |
| 1239 | } |
| 1240 | |
| 1241 | // Folds addition of an addition where each operation has a constant operand. |
| 1242 | // Cases: |
no test coverage detected