From: Alan Baker Date: Tue, 27 Feb 2018 21:19:09 +0000 (-0500) Subject: Fixes #1354. Do not merge integer division. X-Git-Tag: upstream/2018.6~455 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9457cabbcea2c092bdaab9c297e497045d41e81a;p=platform%2Fupstream%2FSPIRV-Tools.git Fixes #1354. Do not merge integer division. * Removes merging of div with a div or mul for integers * Updated tests --- diff --git a/source/opt/folding_rules.cpp b/source/opt/folding_rules.cpp index 30f5641..f94ba7b 100644 --- a/source/opt/folding_rules.cpp +++ b/source/opt/folding_rules.cpp @@ -467,30 +467,7 @@ uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, break; case SpvOpSDiv: case SpvOpUDiv: - // To avoid losing precision we won't perform division that would result - // in a remainder. Unfortunate code duplication results. - if (input2->AsIntConstant()->IsZero()) return 0; - if (width == 64) { - if (type->IsSigned()) { - if (input1->GetS64() % input2->GetS64() != 0) return 0; - int64_t val = input1->GetS64() / input2->GetS64(); - words = ExtractInts(static_cast(val)); - } else { - if (input1->GetU64() % input2->GetU64() != 0) return 0; - uint64_t val = input1->GetU64() / input2->GetU64(); - words = ExtractInts(val); - } - } else { - if (type->IsSigned()) { - if (input1->GetS32() % input2->GetS32() != 0) return 0; - int32_t val = input1->GetS32() / input2->GetS32(); - words.push_back(static_cast(val)); - } else { - if (input1->GetU32() % input2->GetU32() != 0) return 0; - uint32_t val = input1->GetU32() / input2->GetU32(); - words.push_back(val); - } - } + assert(false && "Should not merge integer division"); break; case SpvOpIAdd: FOLD_OP(+); @@ -598,22 +575,21 @@ FoldingRule MergeMulMulArithmetic() { } // Merges divides into subsequent multiplies if each instruction contains one -// constant operand. +// constant operand. Does not support integer operations. // Cases: -// 2 * (x / 2) = 4 / x -// 2 * (2 / x) = x * 1 +// 2 * (x / 2) = x * 1 +// 2 * (2 / x) = 4 / x // (x / 2) * 2 = x * 1 // (2 / x) * 2 = 4 / x FoldingRule MergeMulDivArithmetic() { return [](ir::Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFMul || inst->opcode() == SpvOpIMul); + assert(inst->opcode() == SpvOpFMul); ir::IRContext* context = inst->context(); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); - if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed()) - return false; + if (!inst->IsFloatingPointFoldingAllowed()) return false; uint32_t width = ElementWidth(type); if (width != 32 && width != 64) return false; @@ -621,12 +597,9 @@ FoldingRule MergeMulDivArithmetic() { const analysis::Constant* const_input1 = ConstInput(constants); if (!const_input1) return false; ir::Instruction* other_inst = NonConstInput(context, constants[0], inst); - if (HasFloatingPoint(type) && !other_inst->IsFloatingPointFoldingAllowed()) - return false; + if (!other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == SpvOpFDiv || - other_inst->opcode() == SpvOpSDiv || - other_inst->opcode() == SpvOpUDiv) { + if (other_inst->opcode() == SpvOpFDiv) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -702,6 +675,7 @@ FoldingRule MergeMulNegateArithmetic() { } // Merges consecutive divides if each instruction contains one constant operand. +// Does not support integer division. // Cases: // 2 / (x / 2) = 4 / x // 4 / (2 / x) = 2 * x @@ -710,14 +684,12 @@ FoldingRule MergeMulNegateArithmetic() { FoldingRule MergeDivDivArithmetic() { return [](ir::Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFDiv || inst->opcode() == SpvOpSDiv || - inst->opcode() == SpvOpUDiv); + assert(inst->opcode() == SpvOpFDiv); ir::IRContext* context = inst->context(); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); - bool uses_float = HasFloatingPoint(type); - if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + if (!inst->IsFloatingPointFoldingAllowed()) return false; uint32_t width = ElementWidth(type); if (width != 32 && width != 64) return false; @@ -725,8 +697,7 @@ FoldingRule MergeDivDivArithmetic() { const analysis::Constant* const_input1 = ConstInput(constants); if (!const_input1) return false; ir::Instruction* other_inst = NonConstInput(context, constants[0], inst); - if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) - return false; + if (!other_inst->IsFloatingPointFoldingAllowed()) return false; bool first_is_variable = constants[0] == nullptr; if (other_inst->opcode() == inst->opcode()) { @@ -740,7 +711,7 @@ FoldingRule MergeDivDivArithmetic() { SpvOp merge_op = inst->opcode(); if (other_first_is_variable) { // Constants magnify. - merge_op = uses_float ? SpvOpFMul : SpvOpIMul; + merge_op = SpvOpFMul; } // This is an x / (*) case. Swap the inputs. Doesn't harm multiply @@ -757,7 +728,7 @@ FoldingRule MergeDivDivArithmetic() { SpvOp op = inst->opcode(); if (!first_is_variable && !other_first_is_variable) { // Effectively div of 1/x, so change to multiply. - op = uses_float ? SpvOpFMul : SpvOpIMul; + op = SpvOpFMul; } uint32_t op1 = merged_id; @@ -774,7 +745,7 @@ FoldingRule MergeDivDivArithmetic() { } // Fold multiplies succeeded by divides where each instruction contains a -// constant operand. +// constant operand. Does not support integer divide. // Cases: // 4 / (x * 2) = 2 / x // 4 / (2 * x) = 2 / x @@ -783,14 +754,12 @@ FoldingRule MergeDivDivArithmetic() { FoldingRule MergeDivMulArithmetic() { return [](ir::Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == SpvOpFDiv || inst->opcode() == SpvOpSDiv || - inst->opcode() == SpvOpUDiv); + assert(inst->opcode() == SpvOpFDiv); ir::IRContext* context = inst->context(); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); - bool uses_float = HasFloatingPoint(type); - if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + if (!inst->IsFloatingPointFoldingAllowed()) return false; uint32_t width = ElementWidth(type); if (width != 32 && width != 64) return false; @@ -798,12 +767,10 @@ FoldingRule MergeDivMulArithmetic() { const analysis::Constant* const_input1 = ConstInput(constants); if (!const_input1) return false; ir::Instruction* other_inst = NonConstInput(context, constants[0], inst); - if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) - return false; + if (!other_inst->IsFloatingPointFoldingAllowed()) return false; bool first_is_variable = constants[0] == nullptr; - if (other_inst->opcode() == SpvOpFMul || - other_inst->opcode() == SpvOpIMul) { + if (other_inst->opcode() == SpvOpFMul) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -1808,7 +1775,6 @@ spvtools::opt::FoldingRules::FoldingRules() { rules_[SpvOpIMul].push_back(IntMultipleBy1()); rules_[SpvOpIMul].push_back(MergeMulMulArithmetic()); - rules_[SpvOpIMul].push_back(MergeMulDivArithmetic()); rules_[SpvOpIMul].push_back(MergeMulNegateArithmetic()); rules_[SpvOpISub].push_back(MergeSubNegateArithmetic()); @@ -1817,8 +1783,6 @@ spvtools::opt::FoldingRules::FoldingRules() { rules_[SpvOpPhi].push_back(RedundantPhi()); - rules_[SpvOpSDiv].push_back(MergeDivDivArithmetic()); - rules_[SpvOpSDiv].push_back(MergeDivMulArithmetic()); rules_[SpvOpSDiv].push_back(MergeDivNegateArithmetic()); rules_[SpvOpSNegate].push_back(MergeNegateArithmetic()); @@ -1827,8 +1791,6 @@ spvtools::opt::FoldingRules::FoldingRules() { rules_[SpvOpSelect].push_back(RedundantSelect()); - rules_[SpvOpUDiv].push_back(MergeDivDivArithmetic()); - rules_[SpvOpUDiv].push_back(MergeDivMulArithmetic()); rules_[SpvOpUDiv].push_back(MergeDivNegateArithmetic()); } diff --git a/test/opt/fold_test.cpp b/test/opt/fold_test.cpp index 04112df..1816213 100644 --- a/test/opt/fold_test.cpp +++ b/test/opt/fold_test.cpp @@ -193,8 +193,10 @@ OpName %main "main" %float_3 = OpConstant %float 3 %float_4 = OpConstant %float 4 %float_0p5 = OpConstant %float 0.5 +%v2float_2_2 = OpConstantComposite %v2float %float_2 %float_2 %v2float_2_3 = OpConstantComposite %v2float %float_2 %float_3 %v2float_3_2 = OpConstantComposite %v2float %float_3 %float_2 +%v2float_4_4 = OpConstantComposite %v2float %float_4 %float_4 %v2float_2_0p5 = OpConstantComposite %v2float %float_2 %float_0p5 %double_n1 = OpConstant %double -1 %105 = OpConstant %double 0 ; Need a def with an numerical id to define id maps. @@ -3452,14 +3454,10 @@ INSTANTIATE_TEST_CASE_P(MergeMulTest, MatchingInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd\n", 4, true), - // Test case 10: merge imul of sdiv - // 4 * (x / 2) = 2 * x + // Test case 10: Do not merge imul of sdiv + // 4 * (x / 2) InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_2]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3468,15 +3466,11 @@ INSTANTIATE_TEST_CASE_P(MergeMulTest, MatchingInstructionFoldingTest, "%4 = OpIMul %int %int_4 %3\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 11: merge imul of sdiv - // (x / 2) * 4 = 2 * x + 4, false), + // Test case 11: Do not merge imul of sdiv + // (x / 2) * 4 InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_2]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3485,15 +3479,11 @@ INSTANTIATE_TEST_CASE_P(MergeMulTest, MatchingInstructionFoldingTest, "%4 = OpIMul %int %3 %int_4\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 12: merge imul of udiv - // 4 * (x / 2) = 2 * x + 4, false), + // Test case 12: Do not merge imul of udiv + // 4 * (x / 2) InstructionFoldingCase( Header() + - "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" + - "; CHECK: [[uint_2:%\\w+]] = OpConstant [[uint]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[uint]]\n" + - "; CHECK: %4 = OpIMul [[uint]] [[ld]] [[uint_2]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_uint Function\n" + @@ -3502,15 +3492,11 @@ INSTANTIATE_TEST_CASE_P(MergeMulTest, MatchingInstructionFoldingTest, "%4 = OpIMul %uint %uint_4 %3\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 13: merge imul of udiv - // (x / 2) * 4 = 2 * x + 4, false), + // Test case 13: Do not merge imul of udiv + // (x / 2) * 4 InstructionFoldingCase( Header() + - "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" + - "; CHECK: [[uint_2:%\\w+]] = OpConstant [[uint]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[uint]]\n" + - "; CHECK: %4 = OpIMul [[uint]] [[ld]] [[uint_2]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_uint Function\n" + @@ -3519,9 +3505,9 @@ INSTANTIATE_TEST_CASE_P(MergeMulTest, MatchingInstructionFoldingTest, "%4 = OpIMul %uint %3 %uint_4\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 14: Don't fold if would have remainder - // (x / 3) * 4 + 4, false), + // Test case 14: Don't fold + // (x / 3) * 4 InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + @@ -3533,26 +3519,26 @@ INSTANTIATE_TEST_CASE_P(MergeMulTest, MatchingInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd\n", 4, false), - // Test case 15: merge vector imul of sdiv + // Test case 15: merge vector fmul of fdiv // (x / {2,2}) * {4,4} = x * {2,2} InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[v2int_2_2:%\\w+]] = OpConstantComposite [[v2int]] [[int_2]] [[int_2]]\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[v2int]]\n" + - "; CHECK: %4 = OpIMul [[v2int]] [[ld]] [[v2int_2_2]]\n" + + "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" + + "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" + + "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" + + "; CHECK: [[v2float_2_2:%\\w+]] = OpConstantComposite [[v2float]] [[float_2]] [[float_2]]\n" + + "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float]]\n" + + "; CHECK: %4 = OpFMul [[v2float]] [[ld]] [[v2float_2_2]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + - "%var = OpVariable %_ptr_v2int Function\n" + - "%2 = OpLoad %v2int %var\n" + - "%3 = OpSDiv %v2int %2 %v2int_2_2\n" + - "%4 = OpIMul %v2int %3 %v2int_4_4\n" + + "%var = OpVariable %_ptr_v2float Function\n" + + "%2 = OpLoad %v2float %var\n" + + "%3 = OpFDiv %v2float %2 %v2float_2_2\n" + + "%4 = OpFMul %v2float %3 %v2float_4_4\n" + "OpReturn\n" + "OpFunctionEnd\n", 4, true), - // Test case 15: merge vector imul of snegate + // Test case 16: merge vector imul of snegate // (-x) * {2,2} = x * {-2,-2} InstructionFoldingCase( Header() + @@ -3572,7 +3558,7 @@ INSTANTIATE_TEST_CASE_P(MergeMulTest, MatchingInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd\n", 4, true), - // Test case 15: merge vector imul of snegate + // Test case 17: merge vector imul of snegate // {2,2} * (-x) = x * {-2,-2} InstructionFoldingCase( Header() + @@ -3647,14 +3633,10 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd\n", 4, true), - // Test case 3: merge consecutive sdiv - // 4 / (2 / x) = 2 * x + // Test case 3: Do not merge consecutive sdiv + // 4 / (2 / x) InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpIMul [[int]] [[int_2]] [[ld]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3663,15 +3645,11 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %int_4 %3\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 4: merge consecutive sdiv - // 4 / (x / 2) = 8 / x + 4, false), + // Test case 4: Do not merge consecutive sdiv + // 4 / (x / 2) InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_8:%\\w+]] = OpConstant [[int]] 8\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpSDiv [[int]] [[int_8]] [[ld]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3680,15 +3658,11 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %int_4 %3\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 5: merge consecutive sdiv - // (4 / x) / 2 = 2 / x + 4, false), + // Test case 5: Do not merge consecutive sdiv + // (4 / x) / 2 InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpSDiv [[int]] [[int_2]] [[ld]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3697,15 +3671,11 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %3 %int_2\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 6: merge consecutive sdiv - // (x / 4) / 2 = x / 8 + 4, false), + // Test case 6: Do not merge consecutive sdiv + // (x / 4) / 2 InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_8:%\\w+]] = OpConstant [[int]] 8\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpSDiv [[int]] [[ld]] [[int_8]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3714,15 +3684,11 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %3 %int_2\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 7: merge sdiv of imul - // 4 / (2 * x) = 2 / x + 4, false), + // Test case 7: Do not merge sdiv of imul + // 4 / (2 * x) InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpSDiv [[int]] [[int_2]] [[ld]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3731,15 +3697,11 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %int_4 %3\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 8: merge sdiv of imul - // 4 / (x * 2) = 2 / x + 4, false), + // Test case 8: Do not merge sdiv of imul + // 4 / (x * 2) InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpSDiv [[int]] [[int_2]] [[ld]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3748,15 +3710,11 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %int_4 %3\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 9: merge sdiv of imul - // (4 * x) / 2 = x * 2 + 4, false), + // Test case 9: Do not merge sdiv of imul + // (4 * x) / 2 InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_2]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3765,15 +3723,11 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %3 %int_2\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), - // Test case 10: merge sdiv of imul - // (x * 4) / 2 = x * 2 + 4, false), + // Test case 10: Do not merge sdiv of imul + // (x * 4) / 2 InstructionFoldingCase( Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" + - "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_2]]\n" + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%var = OpVariable %_ptr_int Function\n" + @@ -3782,7 +3736,7 @@ INSTANTIATE_TEST_CASE_P(MergeDivTest, MatchingInstructionFoldingTest, "%4 = OpSDiv %int %3 %int_2\n" + "OpReturn\n" + "OpFunctionEnd\n", - 4, true), + 4, false), // Test case 11: merge sdiv of snegate // (-x) / 2 = x / -2 InstructionFoldingCase(