x / x = 1 -x / x = -1 x / -x = -1
| 1121 | // -x / x = -1 |
| 1122 | // x / -x = -1 |
| 1123 | ConstantFoldingRule FoldRedundantDiv() { |
| 1124 | return [](IRContext* context, Instruction* inst, |
| 1125 | const std::vector<const analysis::Constant*>& constants) |
| 1126 | -> const analysis::Constant* { |
| 1127 | assert(inst->opcode() == spv::Op::OpFDiv || |
| 1128 | inst->opcode() == spv::Op::OpSDiv || |
| 1129 | inst->opcode() == spv::Op::OpUDiv); |
| 1130 | |
| 1131 | if (constants[0] || constants[1]) { |
| 1132 | return nullptr; |
| 1133 | } |
| 1134 | |
| 1135 | analysis::TypeManager* type_mgr = context->get_type_mgr(); |
| 1136 | const analysis::Type* type = type_mgr->GetType(inst->type_id()); |
| 1137 | |
| 1138 | if (type->IsCooperativeMatrix()) { |
| 1139 | return nullptr; |
| 1140 | } |
| 1141 | |
| 1142 | bool use_float = inst->opcode() == spv::Op::OpFDiv; |
| 1143 | if (use_float && !inst->IsFloatingPointFoldingAllowed()) { |
| 1144 | return nullptr; |
| 1145 | } |
| 1146 | |
| 1147 | analysis::ConstantManager* const_mgr = context->get_constant_mgr(); |
| 1148 | |
| 1149 | if (inst->GetSingleWordInOperand(0) == inst->GetSingleWordInOperand(1)) { |
| 1150 | return GetConstantUniformValue(const_mgr, type, 1.0, 1); |
| 1151 | } |
| 1152 | |
| 1153 | if (inst->opcode() == spv::Op::OpUDiv) { |
| 1154 | return nullptr; |
| 1155 | } |
| 1156 | |
| 1157 | analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); |
| 1158 | |
| 1159 | Instruction* lhs = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); |
| 1160 | if ((lhs->opcode() == spv::Op::OpSNegate || |
| 1161 | lhs->opcode() == spv::Op::OpFNegate) && |
| 1162 | lhs->GetSingleWordInOperand(0) == inst->GetSingleWordInOperand(1) && |
| 1163 | (!use_float || lhs->IsFloatingPointFoldingAllowed())) { |
| 1164 | return GetConstantUniformValue(const_mgr, type, -1.0, UINT64_MAX); |
| 1165 | } |
| 1166 | |
| 1167 | Instruction* rhs = def_use_mgr->GetDef(inst->GetSingleWordInOperand(1)); |
| 1168 | if ((rhs->opcode() == spv::Op::OpSNegate || |
| 1169 | rhs->opcode() == spv::Op::OpFNegate) && |
| 1170 | rhs->GetSingleWordInOperand(0) == inst->GetSingleWordInOperand(0) && |
| 1171 | (!use_float || rhs->IsFloatingPointFoldingAllowed())) { |
| 1172 | return GetConstantUniformValue(const_mgr, type, -1.0, UINT64_MAX); |
| 1173 | } |
| 1174 | |
| 1175 | return nullptr; |
| 1176 | }; |
| 1177 | } |
| 1178 | |
| 1179 | bool CompareFloatingPoint(bool op_result, bool op_unordered, |
| 1180 | bool need_ordered) { |
no test coverage detected