Get CCP to use the constant floating point rules.

Fixes #1311
This commit is contained in:
Steven Perron 2018-02-15 10:41:01 -05:00 committed by Steven Perron
parent efe286cd32
commit 3756b387f3
5 changed files with 49 additions and 9 deletions

View File

@ -41,11 +41,6 @@ namespace {
#define UINT32_MAX 0xffffffff /* 4294967295U */
#endif
const ConstantFoldingRules& GetConstantFoldingRules() {
static ConstantFoldingRules* rules = new ConstantFoldingRules();
return *rules;
}
// Returns the single-word result from performing the given unary operation on
// the operand value which is passed in as a 32-bit word.
uint32_t UnaryOperate(SpvOp opcode, uint32_t operand) {
@ -225,6 +220,11 @@ bool FoldInstructionInternal(ir::Instruction* inst) {
} // namespace
const ConstantFoldingRules& GetConstantFoldingRules() {
static ConstantFoldingRules* rules = new ConstantFoldingRules();
return *rules;
}
// Returns the result of performing an operation on scalar constant operands.
// This function extracts the operand values as 32 bit words and returns the
// result in 32 bit word. Scalar constants with longer than 32-bit width are
@ -612,7 +612,7 @@ ir::Instruction* FoldInstructionToConstant(
ir::IRContext* context = inst->context();
analysis::ConstantManager* const_mgr = context->get_constant_mgr();
if (!inst->IsFoldable() &&
if (!inst->IsFoldableByFoldScalar() &&
!GetConstantFoldingRules().HasFoldingRule(inst->opcode())) {
return nullptr;
}
@ -649,12 +649,12 @@ ir::Instruction* FoldInstructionToConstant(
uint32_t result_val = 0;
bool successful = false;
// If all parameters are constant, fold the instruction to a constant.
if (!missing_constants && inst->IsFoldable()) {
if (!missing_constants && inst->IsFoldableByFoldScalar()) {
result_val = FoldScalars(inst->opcode(), constants);
successful = true;
}
if (!successful && inst->IsFoldable()) {
if (!successful && inst->IsFoldableByFoldScalar()) {
successful = FoldIntegerOpToConstant(inst, id_map, &result_val);
}

View File

@ -18,12 +18,16 @@
#include <cstdint>
#include <vector>
#include "const_folding_rules.h"
#include "constants.h"
#include "def_use_manager.h"
namespace spvtools {
namespace opt {
// Returns a reference to the ConstnatFoldingRules instance.
const ConstantFoldingRules& GetConstantFoldingRules();
// Returns the result of folding a scalar instruction with the given |opcode|
// and |operands|. Each entry in |operands| is a pointer to an
// analysis::Constant instance, which should've been created with the constant

View File

@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "instruction.h"
#include <initializer_list>
#include "disassemble.h"
#include "fold.h"
#include "instruction.h"
#include "ir_context.h"
#include "reflect.h"
@ -470,6 +471,11 @@ bool Instruction::IsOpaqueType() const {
}
bool Instruction::IsFoldable() const {
return IsFoldableByFoldScalar() ||
opt::GetConstantFoldingRules().HasFoldingRule(opcode());
}
bool Instruction::IsFoldableByFoldScalar() const {
if (!opt::IsFoldableOpcode(opcode())) {
return false;
}

View File

@ -368,6 +368,10 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
// constant value.
bool IsFoldable() const;
// Returns true if |this| is an instruction which could be folded into a
// constant value by |FoldScalar|.
bool IsFoldableByFoldScalar() const;
inline bool operator==(const Instruction&) const;
inline bool operator!=(const Instruction&) const;
inline bool operator<(const Instruction&) const;

View File

@ -679,6 +679,32 @@ TEST_F(CCPTest, UndefInPhi) {
SinglePassRunAndMatch<opt::CCPPass>(text, true);
}
// Just test to make sure the constant fold rules are being used. Will rely on
// the folding test for specific testing of specific rules.
TEST_F(CCPTest, UseConstantFoldingRules) {
const std::string text = R"(
; CHECK: [[float1:%\w+]] = OpConstant {{%\w+}} 1
; CHECK: OpReturnValue [[float1]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %1 LinkageAttributes "func" Export
%void = OpTypeVoid
%bool = OpTypeBool
%float = OpTypeFloat 32
%float_0 = OpConstant %float 0
%float_1 = OpConstant %float 1
%8 = OpTypeFunction %float
%1 = OpFunction %float None %8
%10 = OpLabel
%17 = OpFAdd %float %float_0 %float_1
OpReturnValue %17
OpFunctionEnd
)";
SinglePassRunAndMatch<opt::CCPPass>(text, true);
}
#endif
} // namespace