Fixes #1354. Do not merge integer division.
authorAlan Baker <alanbaker@google.com>
Tue, 27 Feb 2018 21:19:09 +0000 (16:19 -0500)
committerDavid Neto <dneto@google.com>
Wed, 28 Feb 2018 18:33:21 +0000 (13:33 -0500)
* Removes merging of div with a div or mul for integers
* Updated tests

source/opt/folding_rules.cpp
test/opt/fold_test.cpp

index 30f5641..f94ba7b 100644 (file)
@@ -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<uint64_t>(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<uint32_t>(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<const analysis::Constant*>& 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<const analysis::Constant*> 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<const analysis::Constant*>& 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<const analysis::Constant*>& 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<const analysis::Constant*> 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());
 }
 
index 04112df..1816213 100644 (file)
@@ -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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(
     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<bool>(