// 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 : c->module()->GetConstants()) {
+ for (const auto& inst : context()->module()->GetConstants()) {
values_[inst->result_id()] = inst->result_id();
- if (!const_mgr_->MapInst(inst)) {
- assert(false &&
- "Could not map a new constant value to its defining instruction");
- }
}
}
namespace opt {
namespace analysis {
+ConstantManager::ConstantManager(ir::IRContext* ctx) : ctx_(ctx) {
+ // 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 : ctx_->module()->GetConstants()) {
+ MapInst(inst);
+ }
+}
+
Type* ConstantManager::GetType(const ir::Instruction* inst) const {
return context()->get_type_mgr()->GetType(inst->type_id());
}
// This class represents a pool of constants.
class ConstantManager {
public:
- ConstantManager(ir::IRContext* ctx) : ctx_(ctx) {}
+ ConstantManager(ir::IRContext* ctx);
ir::IRContext* context() const { return ctx_; }
#include "util/ilist_node.h"
#include "latest_version_spirv_header.h"
+#include "reflect.h"
#include "spirv-tools/libspirv.h"
namespace spvtools {
bool Instruction::IsAtomicOp() const { return spvOpcodeIsAtomicOp(opcode()); }
-bool Instruction::IsConstant() const {
- return spvOpcodeIsConstant(opcode()) &&
- !spvOpcodeIsScalarSpecConstant(opcode());
-}
+bool Instruction::IsConstant() const { return IsConstantInst(opcode()); }
} // namespace ir
} // namespace spvtools
SinglePassRunAndMatch<opt::CCPPass>(spv_asm, true);
}
+TEST_F(CCPTest, HandleCompositeWithUndef) {
+ // Check to make sure that CCP does not crash when given a "constant" struct
+ // with an undef. If at a later time CCP is enhanced to optimize this case,
+ // it is not wrong.
+ 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
+ %int = OpTypeInt 32 1
+ %bool = OpTypeBool
+ %_struct_7 = OpTypeStruct %int %int
+ %int_1 = OpConstant %int 1
+ %9 = OpUndef %int
+ %10 = OpConstantComposite %_struct_7 %int_1 %9
+ %main = OpFunction %void None %4
+ %11 = OpLabel
+ %12 = OpCompositeExtract %int %10 0
+ %13 = OpCopyObject %int %12
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ auto res = SinglePassRunToBinary<opt::CCPPass>(spv_asm, true);
+ EXPECT_EQ(std::get<1>(res), opt::Pass::Status::SuccessWithoutChange);
+}
#endif
} // namespace