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

Function RedundantAndAddSub

source/opt/folding_rules.cpp:3978–4028  ·  view source on GitHub ↗

Folds redundant add and sub ops that are part of an and. Cases handled: 1 & (b + 2) = b & 1 1 & (b - 2) = b & 1

Source from the content-addressed store, hash-verified

3976// 1 & (b + 2) = b & 1
3977// 1 & (b - 2) = b & 1
3978FoldingRule RedundantAndAddSub() {
3979 return [](IRContext* context, Instruction* inst,
3980 const std::vector<const analysis::Constant*>& constants) {
3981 assert(inst->opcode() == spv::Op::OpBitwiseAnd && "Wrong opcode.");
3982 const analysis::Type* type =
3983 context->get_type_mgr()->GetType(inst->type_id());
3984 uint32_t width = ElementWidth(type);
3985 if ((width != 32) && (width != 64)) return false;
3986
3987 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
3988 const analysis::Constant* const_input1 = ConstInput(constants);
3989 if (!const_input1) return false;
3990 Instruction* other_inst = NonConstInput(context, constants[0], inst);
3991
3992 if (other_inst->opcode() != spv::Op::OpIAdd &&
3993 other_inst->opcode() != spv::Op::OpISub) {
3994 return false;
3995 }
3996 std::vector<const analysis::Constant*> other_constants =
3997 const_mgr->GetOperandConstants(other_inst);
3998 const analysis::Constant* const_input2 = ConstInput(other_constants);
3999 if (!const_input2) return false;
4000
4001 // Only valid for subtraction if const is on the right
4002 if ((other_inst->opcode() == spv::Op::OpISub) && other_constants[0]) {
4003 return false;
4004 }
4005
4006 bool can_remove_inner = true;
4007 ForEachIntegerConstantPair(const_mgr, const_input1, const_input2,
4008 [&can_remove_inner](auto and_op, auto add_op) {
4009 if (can_remove_inner) {
4010 // Only valid if no bits from the +/- could
4011 // affect bits from the & operation.
4012 can_remove_inner =
4013 utils::LSB(add_op) > and_op;
4014 }
4015 });
4016
4017 if (can_remove_inner) {
4018 Instruction* non_const_input =
4019 NonConstInput(context, other_constants[0], other_inst);
4020 Instruction* const_inst = const_mgr->GetDefiningInstruction(const_input1);
4021 inst->SetInOperands(
4022 {{SPV_OPERAND_TYPE_ID, {non_const_input->result_id()}},
4023 {SPV_OPERAND_TYPE_ID, {const_inst->result_id()}}});
4024 return true;
4025 }
4026 return false;
4027 };
4028}
4029
4030// Folds redundant shift ops that are part of an and.
4031// Cases handled:

Callers 1

AddFoldingRulesMethod · 0.85

Calls 14

ElementWidthFunction · 0.85
ConstInputFunction · 0.85
NonConstInputFunction · 0.85
LSBFunction · 0.85
get_type_mgrMethod · 0.80
get_constant_mgrMethod · 0.80
GetOperandConstantsMethod · 0.80
SetInOperandsMethod · 0.80
opcodeMethod · 0.45
GetTypeMethod · 0.45

Tested by

no test coverage detected