Fix folding insert feeding extract
authorSteven Perron <stevenperron@google.com>
Mon, 19 Feb 2018 01:58:05 +0000 (20:58 -0500)
committerSteven Perron <31666470+s-perron@users.noreply.github.com>
Tue, 20 Feb 2018 16:22:51 +0000 (11:22 -0500)
I mixed up two cases when folding an OpCompositeExtract that is feed by
and OpCompositeInsert.  The specific cases are demonstracted in the new
test.  I mixed up the conditions for the cases, and treated one like the
other.

Fixes #1323.

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

index 10208bd..681c070 100644 (file)
@@ -216,18 +216,18 @@ FoldingRule InsertFeedingExtract() {
 
     // Extracting the value that was inserted along with values for the base
     // composite.  Cannot do anything.
-    if (i + 1 == cinst->NumInOperands()) {
+    if (i == inst->NumInOperands()) {
       return false;
     }
 
     // Extracting an element of the value that was inserted.  Extract from
     // that value directly.
-    if (i == inst->NumInOperands()) {
+    if (i + 1 == cinst->NumInOperands()) {
       std::vector<ir::Operand> operands;
       operands.push_back(
           {SPV_OPERAND_TYPE_ID,
            {cinst->GetSingleWordInOperand(kInsertObjectIdInIdx)}});
-      for (i = i + 1; i < cinst->NumInOperands(); ++i) {
+      for (; i < inst->NumInOperands(); ++i) {
         operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER,
                             {cinst->GetSingleWordInOperand(i)}});
       }
index 81a2289..5c2053d 100644 (file)
@@ -107,6 +107,7 @@ OpName %main "main"
 %_ptr_int = OpTypePointer Function %int
 %_ptr_uint = OpTypePointer Function %uint
 %_ptr_bool = OpTypePointer Function %bool
+%_ptr_struct_v2int_int_int = OpTypePointer Function %struct_v2int_int_int
 %short_0 = OpConstant %short 0
 %short_3 = OpConstant %short 3
 %100 = OpConstant %int 0 ; Need a def with an numerical id to define id maps.
@@ -2047,7 +2048,29 @@ INSTANTIATE_TEST_CASE_P(CompositeExtractFoldingTest, GeneralInstructionFoldingTe
             "%2 = OpCompositeExtract %int %struct_undef_0_0 0 1\n" +
             "OpReturn\n" +
             "OpFunctionEnd",
-        2, 0)
+        2, 0),
+    // Test case 9: constant struct has OpUndef
+    InstructionFoldingCase<uint32_t>(
+        Header() + "%main = OpFunction %void None %void_func\n" +
+            "%main_lab = OpLabel\n" +
+            "%n = OpVariable %_ptr_struct_v2int_int_int Function\n" +
+            "%2 = OpLoad %struct_v2int_int_int %n\n" +
+            "%3 = OpCompositeInsert %struct_v2int_int_int %102 %2 0\n" +
+            "%4 = OpCompositeExtract %int %3 0 1\n" +
+            "OpReturn\n" +
+            "OpFunctionEnd",
+        4, 103),
+    // Test case 10: constant struct has OpUndef
+    InstructionFoldingCase<uint32_t>(
+        Header() + "%main = OpFunction %void None %void_func\n" +
+            "%main_lab = OpLabel\n" +
+            "%n = OpVariable %_ptr_struct_v2int_int_int Function\n" +
+            "%2 = OpLoad %struct_v2int_int_int %n\n" +
+            "%3 = OpCompositeInsert %struct_v2int_int_int %int_0 %2 0 1\n" +
+            "%4 = OpCompositeExtract %v2int %3 0\n" +
+            "OpReturn\n" +
+            "OpFunctionEnd",
+        4, 0)
 ));
 
 INSTANTIATE_TEST_CASE_P(CompositeConstructFoldingTest, GeneralInstructionFoldingTest,