// Copyright (c) 2016 Google Inc.
-//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
%int = OpTypeInt 32 1
%long = OpTypeInt 64 1
%uint = OpTypeInt 32 1
+%v4int = OpTypeVector %int 4
%_ptr_int = OpTypePointer Function %int
%_ptr_uint = OpTypePointer Function %uint
%_ptr_bool = OpTypePointer Function %bool
%short_0 = OpConstant %short 0
%short_3 = OpConstant %short 3
%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
%100 = OpConstant %int 0 ; Need a def with an numerical id to define id maps.
%int_3 = OpConstant %int 3
%int_min = OpConstant %int -2147483648
%uint_3 = OpConstant %uint 3
%uint_32 = OpConstant %uint 32
%uint_max = OpConstant %uint -1
+%v4int_0_0_0_0 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
)";
return header;
));
// clang-format on
-using InstructionNotFoldedTest =
- ::testing::TestWithParam<InstructionFoldingCase<void*>>;
-
-TEST_P(InstructionNotFoldedTest, Case) {
- const auto& tc = GetParam();
-
- // Build module.
- std::unique_ptr<ir::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
-
- // Fold the instruction to test.
- opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- inst = opt::FoldInstruction(inst);
-
- // Make sure the instruction folded as expected.
- EXPECT_EQ(inst, nullptr);
-}
-
-// clang-format off
-INSTANTIATE_TEST_CASE_P(TestCase, InstructionNotFoldedTest,
- ::testing::Values(
- // Test case 0: Don't fold n * m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpIMul %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 1: Don't fold n / m (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUDiv %uint %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 2: Don't fold n / m (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpSDiv %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 3: Don't fold n remainder m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpSRem %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 4: Don't fold n % m (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpSMod %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 5: Don't fold n % m (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUMod %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 6: Don't fold n << m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpShiftRightLogical %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 7: Don't fold n >> m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpShiftLeftLogical %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 8: Don't fold n | m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpBitwiseOr %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 9: Don't fold n & m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpBitwiseAnd %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 10: Don't fold n < m (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpULessThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 11: Don't fold n > m (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUGreaterThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 12: Don't fold n <= m (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpULessThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 13: Don't fold n >= m (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 14: Don't fold n < m (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpULessThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 15: Don't fold n > m (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpUGreaterThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 16: Don't fold n <= m (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpULessThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 17: Don't fold n >= m (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 18: Don't fold n || m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%m = OpVariable %_ptr_bool Function\n" +
- "%load_n = OpLoad %bool %n\n" +
- "%load_m = OpLoad %bool %m\n" +
- "%2 = OpLogicalOr %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 19: Don't fold n && m
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%m = OpVariable %_ptr_bool Function\n" +
- "%load_n = OpLoad %bool %n\n" +
- "%load_m = OpLoad %bool %m\n" +
- "%2 = OpLogicalAnd %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 20: Don't fold n * 3
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpIMul %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 21: Don't fold n / 3 (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUDiv %uint %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 22: Don't fold n / 3 (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpSDiv %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 23: Don't fold n remainder 3
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpSRem %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 24: Don't fold n % 3 (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpSMod %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 25: Don't fold n % 3 (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUMod %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 26: Don't fold n << 3
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpShiftRightLogical %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 27: Don't fold n >> 3
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpShiftLeftLogical %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 28: Don't fold n | 3
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpBitwiseOr %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 29: Don't fold n & 3
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpBitwiseAnd %uint %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 30: Don't fold n < 3 (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpULessThan %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 31: Don't fold n > 3 (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThan %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 32: Don't fold n <= 3 (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpULessThanEqual %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 33: Don't fold n >= 3 (unsigned)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 34: Don't fold n < 3 (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpULessThan %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 35: Don't fold n > 3 (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpUGreaterThan %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 36: Don't fold n <= 3 (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpULessThanEqual %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 37: Don't fold n >= 3 (signed)
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 38: Don't fold 0 + 3 (long), bad length
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %long %long_0 %long_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr),
- // Test case 39: Don't fold 0 + 3 (short), bad length
- InstructionFoldingCase<void*>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %short %short_0 %short_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, nullptr)
- ));
-// clang-format on
-
template <class ResultType>
struct InstructionFoldingCaseWithMap {
InstructionFoldingCaseWithMap(const std::string& tb, uint32_t id,
2, true, [](uint32_t id) {return (id == 3 ? TRUE_ID : id);})
));
// clang-format on
+
+using GeneralInstructionFoldingTest =
+ ::testing::TestWithParam<InstructionFoldingCase<uint32_t>>;
+
+TEST_P(GeneralInstructionFoldingTest, Case) {
+ const auto& tc = GetParam();
+
+ // Build module.
+ std::unique_ptr<ir::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ ASSERT_NE(nullptr, context);
+
+ // Fold the instruction to test.
+ opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
+ ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+ inst = opt::FoldInstruction(inst);
+
+ // Make sure the instruction folded as expected.
+ EXPECT_TRUE((inst == nullptr) == (tc.expected_result == 0));
+ if (inst != nullptr) {
+ EXPECT_EQ(inst->result_id(), tc.expected_result);
+ }
+}
+
+// clang-format off
+INSTANTIATE_TEST_CASE_P(TestCase, GeneralInstructionFoldingTest,
+::testing::Values(
+ // Test case 0: Don't fold n * m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpIMul %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 1: Don't fold n / m (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpUDiv %uint %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 2: Don't fold n / m (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpSDiv %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 3: Don't fold n remainder m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpSRem %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 4: Don't fold n % m (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpSMod %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 5: Don't fold n % m (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpUMod %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 6: Don't fold n << m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpShiftRightLogical %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 7: Don't fold n >> m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpShiftLeftLogical %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 8: Don't fold n | m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpBitwiseOr %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 9: Don't fold n & m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpBitwiseAnd %int %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 10: Don't fold n < m (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpULessThan %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 11: Don't fold n > m (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpUGreaterThan %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 12: Don't fold n <= m (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpULessThanEqual %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 13: Don't fold n >= m (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%m = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%load_m = OpLoad %uint %m\n" +
+ "%2 = OpUGreaterThanEqual %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 14: Don't fold n < m (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpULessThan %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 15: Don't fold n > m (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpUGreaterThan %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 16: Don't fold n <= m (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpULessThanEqual %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 17: Don't fold n >= m (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%m = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%load_m = OpLoad %int %m\n" +
+ "%2 = OpUGreaterThanEqual %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 18: Don't fold n || m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_bool Function\n" +
+ "%m = OpVariable %_ptr_bool Function\n" +
+ "%load_n = OpLoad %bool %n\n" +
+ "%load_m = OpLoad %bool %m\n" +
+ "%2 = OpLogicalOr %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 19: Don't fold n && m
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_bool Function\n" +
+ "%m = OpVariable %_ptr_bool Function\n" +
+ "%load_n = OpLoad %bool %n\n" +
+ "%load_m = OpLoad %bool %m\n" +
+ "%2 = OpLogicalAnd %bool %load_n %load_m\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 20: Don't fold n * 3
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpIMul %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 21: Don't fold n / 3 (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpUDiv %uint %load_n %uint_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 22: Don't fold n / 3 (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpSDiv %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 23: Don't fold n remainder 3
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpSRem %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 24: Don't fold n % 3 (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpSMod %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 25: Don't fold n % 3 (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpUMod %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 26: Don't fold n << 3
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpShiftRightLogical %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 27: Don't fold n >> 3
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpShiftLeftLogical %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 28: Don't fold n | 3
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpBitwiseOr %int %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 29: Don't fold n & 3
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpBitwiseAnd %uint %load_n %uint_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 30: Don't fold n < 3 (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpULessThan %bool %load_n %uint_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 31: Don't fold n > 3 (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpUGreaterThan %bool %load_n %uint_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 32: Don't fold n <= 3 (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpULessThanEqual %bool %load_n %uint_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 33: Don't fold n >= 3 (unsigned)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_uint Function\n" +
+ "%load_n = OpLoad %uint %n\n" +
+ "%2 = OpUGreaterThanEqual %bool %load_n %uint_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 34: Don't fold n < 3 (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpULessThan %bool %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 35: Don't fold n > 3 (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpUGreaterThan %bool %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 36: Don't fold n <= 3 (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpULessThanEqual %bool %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 37: Don't fold n >= 3 (signed)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load_n = OpLoad %int %n\n" +
+ "%2 = OpUGreaterThanEqual %bool %load_n %int_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 38: Don't fold 0 + 3 (long), bad length
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpIAdd %long %long_0 %long_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 39: Don't fold 0 + 3 (short), bad length
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpIAdd %short %short_0 %short_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 40: fold 1*n
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%3 = OpLoad %int %n\n" +
+ "%2 = OpIMul %int %int_1 %3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 3),
+ // Test case 41: fold n*1
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%3 = OpLoad %int %n\n" +
+ "%2 = OpIMul %int %3 %int_1\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 3),
+ // Test case 42: fold Insert feeding extract
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%2 = OpLoad %int %n\n" +
+ "%3 = OpCompositeInsert %v4int %2 %v4int_0_0_0_0 0\n" +
+ "%4 = OpCompositeInsert %v4int %int_1 %3 1\n" +
+ "%5 = OpCompositeInsert %v4int %int_1 %4 2\n" +
+ "%6 = OpCompositeInsert %v4int %int_1 %5 3\n" +
+ "%7 = OpCompositeExtract %int %6 0\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 7, 2)
+));
+// clang-format off
} // anonymous namespace