Skip SpecConstants in CCP.
authorSteven Perron <stevenperron@google.com>
Sat, 13 Jan 2018 05:28:40 +0000 (00:28 -0500)
committerSteven Perron <stevenperron@google.com>
Mon, 15 Jan 2018 14:53:23 +0000 (09:53 -0500)
At the moment specialization constants look like constants to ccp.  This
causes a problem because they are handled differently by the constant
manager.

I choose to simply skip over them, and not try to add them to the value
table.  We can do specialization before ccp if we want to be able to
propagate these values.

Fixes #1199.

source/opt/ccp_pass.cpp
source/opt/instruction.h
test/opt/ccp_test.cpp

index 2f10f3a..5852c64 100644 (file)
@@ -270,7 +270,10 @@ void CCPPass::Initialize(ir::IRContext* c) {
   // module.  The values of each OpConstant declaration is the identity
   // assignment (i.e., each constant is its own value).
   for (const auto& inst : context()->module()->GetConstants()) {
-    values_[inst->result_id()] = inst->result_id();
+    // Skip specialization constants.
+    if (inst->IsConstant()) {
+      values_[inst->result_id()] = inst->result_id();
+    }
   }
 }
 
index f1c98ed..b13a78d 100644 (file)
@@ -656,7 +656,9 @@ bool Instruction::IsLoad() const { return spvOpcodeIsLoad(opcode()); }
 
 bool Instruction::IsAtomicOp() const { return spvOpcodeIsAtomicOp(opcode()); }
 
-bool Instruction::IsConstant() const { return IsConstantInst(opcode()); }
+bool Instruction::IsConstant() const {
+  return IsCompileTimeConstantInst(opcode());
+}
 }  // namespace ir
 }  // namespace spvtools
 
index 6f3122e..2e7dabc 100644 (file)
@@ -554,6 +554,33 @@ TEST_F(CCPTest, HandleCompositeWithUndef) {
   auto res = SinglePassRunToBinary<opt::CCPPass>(spv_asm, true);
   EXPECT_EQ(std::get<1>(res), opt::Pass::Status::SuccessWithoutChange);
 }
+
+TEST_F(CCPTest, SkipSpecConstantInstrucitons) {
+  const std::string spv_asm = R"(
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main"
+               OpExecutionMode %main OriginUpperLeft
+               OpSource HLSL 500
+               OpName %main "main"
+       %void = OpTypeVoid
+          %4 = OpTypeFunction %void
+       %bool = OpTypeBool
+         %10 = OpSpecConstantFalse %bool
+       %main = OpFunction %void None %4
+         %11 = OpLabel
+         %12 = OpBranchConditional %10 %l1 %l2
+         %l1 = OpLabel
+               OpReturn
+         %l2 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  auto res = SinglePassRunToBinary<opt::CCPPass>(spv_asm, true);
+  EXPECT_EQ(std::get<1>(res), opt::Pass::Status::SuccessWithoutChange);
+}
 #endif
 
 }  // namespace