| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits> | 5 #include <limits> |
| 6 | 6 |
| 7 #include "test/unittests/compiler/instruction-selector-unittest.h" | 7 #include "test/unittests/compiler/instruction-selector-unittest.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 2061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2072 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); | 2072 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); |
| 2073 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 2073 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 2074 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); | 2074 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); |
| 2075 } | 2075 } |
| 2076 } | 2076 } |
| 2077 | 2077 |
| 2078 TEST_P(InstructionSelectorFlagSettingTest, CmpZeroOnlyUserInBasicBlock) { | 2078 TEST_P(InstructionSelectorFlagSettingTest, CmpZeroOnlyUserInBasicBlock) { |
| 2079 const FlagSettingInst inst = GetParam(); | 2079 const FlagSettingInst inst = GetParam(); |
| 2080 // Binop with additional users, but in a different basic block. | 2080 // Binop with additional users, but in a different basic block. |
| 2081 TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { | 2081 TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { |
| 2082 // We don't optimise this case at the moment. | |
| 2083 if (cmp.flags_condition == kEqual || cmp.flags_condition == kNotEqual) { | |
| 2084 continue; | |
| 2085 } | |
| 2086 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), | 2082 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2087 MachineType::Int32()); | 2083 MachineType::Int32()); |
| 2088 RawMachineLabel a, b; | 2084 RawMachineLabel a, b; |
| 2089 Node* binop = (m.*inst.constructor)(m.Parameter(0), m.Parameter(1)); | 2085 Node* binop = (m.*inst.constructor)(m.Parameter(0), m.Parameter(1)); |
| 2090 Node* comp = (m.*cmp.constructor)(binop, m.Int32Constant(0)); | 2086 Node* comp = (m.*cmp.constructor)(binop, m.Int32Constant(0)); |
| 2091 m.Branch(comp, &a, &b); | 2087 m.Branch(comp, &a, &b); |
| 2092 m.Bind(&a); | 2088 m.Bind(&a); |
| 2093 m.Return(binop); | 2089 m.Return(binop); |
| 2094 m.Bind(&b); | 2090 m.Bind(&b); |
| 2095 m.Return(m.Int32Constant(0)); | 2091 m.Return(m.Int32Constant(0)); |
| 2096 Stream s = m.Build(); | 2092 Stream s = m.Build(); |
| 2097 ASSERT_EQ(1U, s.size()); | 2093 ASSERT_EQ(1U, s.size()); |
| 2098 ASSERT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. | 2094 ASSERT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. |
| 2099 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); | 2095 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 2100 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); | 2096 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 2101 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); | 2097 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); |
| 2102 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 2098 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 2103 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); | 2099 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition()); |
| 2104 } | 2100 } |
| 2105 } | 2101 } |
| 2106 | 2102 |
| 2107 TEST_P(InstructionSelectorFlagSettingTest, ShiftedOperand) { | 2103 TEST_P(InstructionSelectorFlagSettingTest, ShiftedOperand) { |
| 2108 const FlagSettingInst inst = GetParam(); | 2104 const FlagSettingInst inst = GetParam(); |
| 2109 // Like the test above, but with a shifted input to the binary operator. | 2105 // Like the test above, but with a shifted input to the binary operator. |
| 2110 TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { | 2106 TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { |
| 2111 // We don't optimise this case at the moment. | |
| 2112 if (cmp.flags_condition == kEqual || cmp.flags_condition == kNotEqual) { | |
| 2113 continue; | |
| 2114 } | |
| 2115 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), | 2107 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 2116 MachineType::Int32()); | 2108 MachineType::Int32()); |
| 2117 RawMachineLabel a, b; | 2109 RawMachineLabel a, b; |
| 2118 Node* imm = m.Int32Constant(5); | 2110 Node* imm = m.Int32Constant(5); |
| 2119 Node* shift = m.Word32Shl(m.Parameter(1), imm); | 2111 Node* shift = m.Word32Shl(m.Parameter(1), imm); |
| 2120 Node* binop = (m.*inst.constructor)(m.Parameter(0), shift); | 2112 Node* binop = (m.*inst.constructor)(m.Parameter(0), shift); |
| 2121 Node* comp = (m.*cmp.constructor)(binop, m.Int32Constant(0)); | 2113 Node* comp = (m.*cmp.constructor)(binop, m.Int32Constant(0)); |
| 2122 m.Branch(comp, &a, &b); | 2114 m.Branch(comp, &a, &b); |
| 2123 m.Bind(&a); | 2115 m.Bind(&a); |
| 2124 m.Return(binop); | 2116 m.Return(binop); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2151 m.Branch(comp, &a, &b); | 2143 m.Branch(comp, &a, &b); |
| 2152 m.Bind(&a); | 2144 m.Bind(&a); |
| 2153 m.Return(mul); | 2145 m.Return(mul); |
| 2154 m.Bind(&b); | 2146 m.Bind(&b); |
| 2155 m.Return(m.Int32Constant(0)); | 2147 m.Return(m.Int32Constant(0)); |
| 2156 Stream s = m.Build(); | 2148 Stream s = m.Build(); |
| 2157 ASSERT_EQ(3U, s.size()); | 2149 ASSERT_EQ(3U, s.size()); |
| 2158 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); | 2150 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); |
| 2159 EXPECT_NE(kFlags_branch, s[0]->flags_mode()); | 2151 EXPECT_NE(kFlags_branch, s[0]->flags_mode()); |
| 2160 EXPECT_EQ(kArmMul, s[1]->arch_opcode()); | 2152 EXPECT_EQ(kArmMul, s[1]->arch_opcode()); |
| 2161 EXPECT_EQ(cmp.flags_condition == kEqual ? kArmTst : kArmCmp, | 2153 EXPECT_EQ(kArmCmp, s[2]->arch_opcode()); |
| 2162 s[2]->arch_opcode()); | |
| 2163 EXPECT_EQ(kFlags_branch, s[2]->flags_mode()); | 2154 EXPECT_EQ(kFlags_branch, s[2]->flags_mode()); |
| 2164 EXPECT_EQ(cmp.flags_condition, s[2]->flags_condition()); | 2155 EXPECT_EQ(cmp.flags_condition, s[2]->flags_condition()); |
| 2165 } | 2156 } |
| 2166 } | 2157 } |
| 2167 | 2158 |
| 2168 TEST_P(InstructionSelectorFlagSettingTest, CommuteImmediate) { | 2159 TEST_P(InstructionSelectorFlagSettingTest, CommuteImmediate) { |
| 2169 const FlagSettingInst inst = GetParam(); | 2160 const FlagSettingInst inst = GetParam(); |
| 2170 // Immediate on left hand side of the binary operator. | 2161 // Immediate on left hand side of the binary operator. |
| 2171 TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { | 2162 TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { |
| 2172 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 2163 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| (...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3052 } | 3043 } |
| 3053 } | 3044 } |
| 3054 | 3045 |
| 3055 | 3046 |
| 3056 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { | 3047 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { |
| 3057 { | 3048 { |
| 3058 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 3049 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3059 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); | 3050 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); |
| 3060 Stream s = m.Build(); | 3051 Stream s = m.Build(); |
| 3061 ASSERT_EQ(1U, s.size()); | 3052 ASSERT_EQ(1U, s.size()); |
| 3062 EXPECT_EQ(kArmTst, s[0]->arch_opcode()); | 3053 EXPECT_EQ(kArmCmp, s[0]->arch_opcode()); |
| 3063 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode()); | 3054 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode()); |
| 3064 ASSERT_EQ(2U, s[0]->InputCount()); | 3055 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3065 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 3056 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 3057 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); |
| 3066 EXPECT_EQ(1U, s[0]->OutputCount()); | 3058 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 3067 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 3059 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 3068 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 3060 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 3069 } | 3061 } |
| 3070 { | 3062 { |
| 3071 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 3063 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3072 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); | 3064 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); |
| 3073 Stream s = m.Build(); | 3065 Stream s = m.Build(); |
| 3074 ASSERT_EQ(1U, s.size()); | 3066 ASSERT_EQ(1U, s.size()); |
| 3075 EXPECT_EQ(kArmTst, s[0]->arch_opcode()); | 3067 EXPECT_EQ(kArmCmp, s[0]->arch_opcode()); |
| 3076 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode()); | 3068 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode()); |
| 3077 ASSERT_EQ(2U, s[0]->InputCount()); | 3069 ASSERT_EQ(2U, s[0]->InputCount()); |
| 3078 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); | 3070 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 3071 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); |
| 3079 EXPECT_EQ(1U, s[0]->OutputCount()); | 3072 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 3080 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 3073 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 3081 EXPECT_EQ(kEqual, s[0]->flags_condition()); | 3074 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 3082 } | 3075 } |
| 3083 } | 3076 } |
| 3084 | 3077 |
| 3085 | 3078 |
| 3086 TEST_F(InstructionSelectorTest, Word32NotWithParameter) { | 3079 TEST_F(InstructionSelectorTest, Word32NotWithParameter) { |
| 3087 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 3080 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3088 m.Return(m.Word32Not(m.Parameter(0))); | 3081 m.Return(m.Word32Not(m.Parameter(0))); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3261 EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode()); | 3254 EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode()); |
| 3262 ASSERT_EQ(1U, s[0]->InputCount()); | 3255 ASSERT_EQ(1U, s[0]->InputCount()); |
| 3263 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 3256 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 3264 ASSERT_EQ(1U, s[0]->OutputCount()); | 3257 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 3265 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 3258 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
| 3266 } | 3259 } |
| 3267 | 3260 |
| 3268 } // namespace compiler | 3261 } // namespace compiler |
| 3269 } // namespace internal | 3262 } // namespace internal |
| 3270 } // namespace v8 | 3263 } // namespace v8 |
| OLD | NEW |