From 229ebc06657c1c2186d2ec3dc0add54d82d93c98 Mon Sep 17 00:00:00 2001 From: Alan Baker Date: Wed, 14 Feb 2018 09:39:11 -0500 Subject: [PATCH] Fixes #1295. Mark undef values as varying in ccp. * Undef now marked as varying in ccp * this prevents incorrect meet operations since phis were always not interesting * added a test to catch the bug --- source/opt/ccp_pass.cpp | 10 ++++++---- test/opt/ccp_test.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/source/opt/ccp_pass.cpp b/source/opt/ccp_pass.cpp index 3c85e4f..d81364b 100644 --- a/source/opt/ccp_pass.cpp +++ b/source/opt/ccp_pass.cpp @@ -273,10 +273,12 @@ void CCPPass::Initialize(ir::IRContext* c) { // Populate the constant table with values from constant declarations in the // 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()) { - // Skip specialization constants. - if (inst->IsConstant()) { - values_[inst->result_id()] = inst->result_id(); + for (const auto& inst : get_module()->types_values()) { + // Skip specialization constants. Treat undef as varying. + if (inst.IsConstant()) { + values_[inst.result_id()] = inst.result_id(); + } else if (inst.opcode() == SpvOpUndef) { + values_[inst.result_id()] = kVaryingSSAId; } } } diff --git a/test/opt/ccp_test.cpp b/test/opt/ccp_test.cpp index 3ebf65b..a221c42 100644 --- a/test/opt/ccp_test.cpp +++ b/test/opt/ccp_test.cpp @@ -641,6 +641,44 @@ OpFunctionEnd auto res = SinglePassRunToBinary(text, true); EXPECT_EQ(std::get<1>(res), opt::Pass::Status::SuccessWithoutChange); } + +TEST_F(CCPTest, UndefInPhi) { + const std::string text = R"( +; CHECK: [[uint1:%\w+]] = OpConstant {{%\w+}} 1 +; CHECK: [[phi:%\w+]] = OpPhi +; CHECK: OpIAdd {{%\w+}} [[phi]] [[uint1]] + OpCapability Kernel + OpCapability Linkage + OpMemoryModel Logical OpenCL + OpDecorate %1 LinkageAttributes "func" Export + %void = OpTypeVoid + %bool = OpTypeBool + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %7 = OpUndef %uint + %8 = OpTypeFunction %void %bool + %1 = OpFunction %void None %8 + %9 = OpFunctionParameter %bool + %10 = OpLabel + OpBranchConditional %9 %11 %12 + %11 = OpLabel + OpBranch %13 + %12 = OpLabel + OpBranch %14 + %14 = OpLabel + OpBranchConditional %9 %13 %15 + %15 = OpLabel + OpBranch %13 + %13 = OpLabel + %16 = OpPhi %uint %uint_0 %11 %7 %14 %uint_1 %15 + %17 = OpIAdd %uint %16 %uint_1 + OpReturn + OpFunctionEnd +)"; + + SinglePassRunAndMatch(text, true); +} #endif } // namespace -- 2.7.4