Get CCP to use the constant floating point rules.
authorSteven Perron <stevenperron@google.com>
Thu, 15 Feb 2018 15:41:01 +0000 (10:41 -0500)
committerSteven Perron <31666470+s-perron@users.noreply.github.com>
Fri, 16 Feb 2018 18:49:47 +0000 (13:49 -0500)
Fixes #1311

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

index ab7239d..6cc486a 100644 (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);
   }
 
index 439ed2b..9c6028d 100644 (file)
 #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
index 99e50d3..9510ee9 100644 (file)
 // 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;
   }
index b04f66d..fccd4c4 100644 (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;
index a221c42..1514065 100644 (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