| 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 "src/compiler/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
| 6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
| 7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
| 8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
| 9 #include "src/compiler/machine-operator.h" | 9 #include "src/compiler/machine-operator.h" |
| 10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
| 11 #include "src/compiler/typer.h" | 11 #include "src/compiler/typer.h" |
| 12 #include "test/unittests/compiler/compiler-test-utils.h" | 12 #include "test/unittests/compiler/compiler-test-utils.h" |
| 13 #include "test/unittests/compiler/graph-unittest.h" | 13 #include "test/unittests/compiler/graph-unittest.h" |
| 14 #include "test/unittests/compiler/node-test-utils.h" | 14 #include "test/unittests/compiler/node-test-utils.h" |
| 15 #include "testing/gmock-support.h" |
| 16 |
| 17 using testing::BitEq; |
| 18 |
| 15 | 19 |
| 16 namespace v8 { | 20 namespace v8 { |
| 17 namespace internal { | 21 namespace internal { |
| 18 namespace compiler { | 22 namespace compiler { |
| 19 | 23 |
| 20 namespace { | 24 namespace { |
| 21 | 25 |
| 22 const ExternalArrayType kExternalArrayTypes[] = { | 26 const ExternalArrayType kExternalArrayTypes[] = { |
| 23 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array, | 27 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array, |
| 24 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array, | 28 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 | 132 |
| 129 | 133 |
| 130 TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) { | 134 TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) { |
| 131 Node* input = Parameter(Type::OrderedNumber()); | 135 Node* input = Parameter(Type::OrderedNumber()); |
| 132 Node* context = UndefinedConstant(); | 136 Node* context = UndefinedConstant(); |
| 133 | 137 |
| 134 Reduction r = | 138 Reduction r = |
| 135 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); | 139 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); |
| 136 ASSERT_TRUE(r.Changed()); | 140 ASSERT_TRUE(r.Changed()); |
| 137 EXPECT_THAT(r.replacement(), | 141 EXPECT_THAT(r.replacement(), |
| 138 IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0)))); | 142 IsBooleanNot(IsNumberEqual(input, IsNumberConstant(BitEq(0.0))))); |
| 139 } | 143 } |
| 140 | 144 |
| 141 | 145 |
| 142 TEST_F(JSTypedLoweringTest, JSToBooleanWithString) { | 146 TEST_F(JSTypedLoweringTest, JSToBooleanWithString) { |
| 143 Node* input = Parameter(Type::String()); | 147 Node* input = Parameter(Type::String()); |
| 144 Node* context = UndefinedConstant(); | 148 Node* context = UndefinedConstant(); |
| 145 | 149 |
| 146 Reduction r = | 150 Reduction r = |
| 147 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); | 151 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); |
| 148 ASSERT_TRUE(r.Changed()); | 152 ASSERT_TRUE(r.Changed()); |
| 149 EXPECT_THAT(r.replacement(), | 153 EXPECT_THAT(r.replacement(), |
| 150 IsBooleanNot(IsNumberEqual( | 154 IsBooleanNot(IsNumberEqual( |
| 151 IsLoadField(AccessBuilder::ForStringLength(), input, | 155 IsLoadField(AccessBuilder::ForStringLength(), input, |
| 152 graph()->start(), graph()->start()), | 156 graph()->start(), graph()->start()), |
| 153 IsNumberConstant(0)))); | 157 IsNumberConstant(BitEq(0.0))))); |
| 154 } | 158 } |
| 155 | 159 |
| 156 | 160 |
| 157 TEST_F(JSTypedLoweringTest, JSToBooleanWithPhi) { | 161 TEST_F(JSTypedLoweringTest, JSToBooleanWithPhi) { |
| 158 Node* p0 = Parameter(Type::OrderedNumber(), 0); | 162 Node* p0 = Parameter(Type::OrderedNumber(), 0); |
| 159 Node* p1 = Parameter(Type::Boolean(), 1); | 163 Node* p1 = Parameter(Type::Boolean(), 1); |
| 160 Node* context = UndefinedConstant(); | 164 Node* context = UndefinedConstant(); |
| 161 Node* control = graph()->start(); | 165 Node* control = graph()->start(); |
| 162 | 166 |
| 163 Reduction r = Reduce(graph()->NewNode( | 167 Reduction r = Reduce(graph()->NewNode( |
| 164 javascript()->ToBoolean(), | 168 javascript()->ToBoolean(), |
| 165 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, control), | 169 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, control), |
| 166 context)); | 170 context)); |
| 167 ASSERT_TRUE(r.Changed()); | 171 ASSERT_TRUE(r.Changed()); |
| 168 EXPECT_THAT( | 172 EXPECT_THAT(r.replacement(), |
| 169 r.replacement(), | 173 IsPhi(kMachAnyTagged, IsBooleanNot(IsNumberEqual( |
| 170 IsPhi(kMachAnyTagged, | 174 p0, IsNumberConstant(BitEq(0.0)))), |
| 171 IsBooleanNot(IsNumberEqual(p0, IsNumberConstant(0))), p1, control)); | 175 p1, control)); |
| 172 } | 176 } |
| 173 | 177 |
| 174 | 178 |
| 175 TEST_F(JSTypedLoweringTest, JSToBooleanWithSelect) { | 179 TEST_F(JSTypedLoweringTest, JSToBooleanWithSelect) { |
| 176 Node* p0 = Parameter(Type::Boolean(), 0); | 180 Node* p0 = Parameter(Type::Boolean(), 0); |
| 177 Node* p1 = Parameter(Type::DetectableReceiver(), 1); | 181 Node* p1 = Parameter(Type::DetectableReceiver(), 1); |
| 178 Node* p2 = Parameter(Type::OrderedNumber(), 2); | 182 Node* p2 = Parameter(Type::OrderedNumber(), 2); |
| 179 Node* context = UndefinedConstant(); | 183 Node* context = UndefinedConstant(); |
| 180 | 184 |
| 181 Reduction r = Reduce(graph()->NewNode( | 185 Reduction r = Reduce(graph()->NewNode( |
| 182 javascript()->ToBoolean(), | 186 javascript()->ToBoolean(), |
| 183 graph()->NewNode(common()->Select(kMachAnyTagged, BranchHint::kTrue), p0, | 187 graph()->NewNode(common()->Select(kMachAnyTagged, BranchHint::kTrue), p0, |
| 184 p1, p2), | 188 p1, p2), |
| 185 context)); | 189 context)); |
| 186 ASSERT_TRUE(r.Changed()); | 190 ASSERT_TRUE(r.Changed()); |
| 187 EXPECT_THAT(r.replacement(), | 191 EXPECT_THAT( |
| 188 IsSelect(kMachAnyTagged, p0, IsTrueConstant(), | 192 r.replacement(), |
| 189 IsBooleanNot(IsNumberEqual(p2, IsNumberConstant(0))))); | 193 IsSelect(kMachAnyTagged, p0, IsTrueConstant(), |
| 194 IsBooleanNot(IsNumberEqual(p2, IsNumberConstant(BitEq(0.0)))))); |
| 190 } | 195 } |
| 191 | 196 |
| 192 | 197 |
| 193 // ----------------------------------------------------------------------------- | 198 // ----------------------------------------------------------------------------- |
| 194 // JSToNumber | 199 // JSToNumber |
| 195 | 200 |
| 196 | 201 |
| 197 TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) { | 202 TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) { |
| 198 Node* const input = Parameter(Type::PlainPrimitive(), 0); | 203 Node* const input = Parameter(Type::PlainPrimitive(), 0); |
| 199 Node* const context = Parameter(Type::Any(), 1); | 204 Node* const context = Parameter(Type::Any(), 1); |
| 200 Node* const effect = graph()->start(); | 205 Node* const effect = graph()->start(); |
| 201 Node* const control = graph()->start(); | 206 Node* const control = graph()->start(); |
| 202 Reduction r = Reduce(graph()->NewNode(javascript()->ToNumber(), input, | 207 Reduction r = Reduce(graph()->NewNode(javascript()->ToNumber(), input, |
| 203 context, effect, control)); | 208 context, effect, control)); |
| 204 ASSERT_TRUE(r.Changed()); | 209 ASSERT_TRUE(r.Changed()); |
| 205 EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(0), | 210 EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(BitEq(0.0)), |
| 206 graph()->start(), control)); | 211 graph()->start(), control)); |
| 207 } | 212 } |
| 208 | 213 |
| 209 | 214 |
| 210 // ----------------------------------------------------------------------------- | 215 // ----------------------------------------------------------------------------- |
| 211 // JSStrictEqual | 216 // JSStrictEqual |
| 212 | 217 |
| 213 | 218 |
| 214 TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) { | 219 TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) { |
| 215 Node* const the_hole = HeapConstant(factory()->the_hole_value()); | 220 Node* const the_hole = HeapConstant(factory()->the_hole_value()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 228 | 233 |
| 229 // ----------------------------------------------------------------------------- | 234 // ----------------------------------------------------------------------------- |
| 230 // JSShiftLeft | 235 // JSShiftLeft |
| 231 | 236 |
| 232 | 237 |
| 233 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) { | 238 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) { |
| 234 Node* const lhs = Parameter(Type::Signed32()); | 239 Node* const lhs = Parameter(Type::Signed32()); |
| 235 Node* const context = UndefinedConstant(); | 240 Node* const context = UndefinedConstant(); |
| 236 Node* const effect = graph()->start(); | 241 Node* const effect = graph()->start(); |
| 237 Node* const control = graph()->start(); | 242 Node* const control = graph()->start(); |
| 238 TRACED_FORRANGE(int32_t, rhs, 0, 31) { | 243 TRACED_FORRANGE(double, rhs, 0, 31) { |
| 239 Reduction r = | 244 Reduction r = |
| 240 Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, | 245 Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, |
| 241 NumberConstant(rhs), context, effect, control)); | 246 NumberConstant(rhs), context, effect, control)); |
| 242 ASSERT_TRUE(r.Changed()); | 247 ASSERT_TRUE(r.Changed()); |
| 243 EXPECT_THAT(r.replacement(), IsWord32Shl(lhs, IsNumberConstant(rhs))); | 248 EXPECT_THAT(r.replacement(), |
| 249 IsWord32Shl(lhs, IsNumberConstant(BitEq(rhs)))); |
| 244 } | 250 } |
| 245 } | 251 } |
| 246 | 252 |
| 247 | 253 |
| 248 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) { | 254 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) { |
| 249 Node* const lhs = Parameter(Type::Signed32()); | 255 Node* const lhs = Parameter(Type::Signed32()); |
| 250 Node* const rhs = Parameter(Type::Unsigned32()); | 256 Node* const rhs = Parameter(Type::Unsigned32()); |
| 251 Node* const context = UndefinedConstant(); | 257 Node* const context = UndefinedConstant(); |
| 252 Node* const effect = graph()->start(); | 258 Node* const effect = graph()->start(); |
| 253 Node* const control = graph()->start(); | 259 Node* const control = graph()->start(); |
| 254 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, rhs, | 260 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, rhs, |
| 255 context, effect, control)); | 261 context, effect, control)); |
| 256 ASSERT_TRUE(r.Changed()); | 262 ASSERT_TRUE(r.Changed()); |
| 257 EXPECT_THAT(r.replacement(), | 263 EXPECT_THAT(r.replacement(), |
| 258 IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); | 264 IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); |
| 259 } | 265 } |
| 260 | 266 |
| 261 | 267 |
| 262 // ----------------------------------------------------------------------------- | 268 // ----------------------------------------------------------------------------- |
| 263 // JSShiftRight | 269 // JSShiftRight |
| 264 | 270 |
| 265 | 271 |
| 266 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) { | 272 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) { |
| 267 Node* const lhs = Parameter(Type::Signed32()); | 273 Node* const lhs = Parameter(Type::Signed32()); |
| 268 Node* const context = UndefinedConstant(); | 274 Node* const context = UndefinedConstant(); |
| 269 Node* const effect = graph()->start(); | 275 Node* const effect = graph()->start(); |
| 270 Node* const control = graph()->start(); | 276 Node* const control = graph()->start(); |
| 271 TRACED_FORRANGE(int32_t, rhs, 0, 31) { | 277 TRACED_FORRANGE(double, rhs, 0, 31) { |
| 272 Reduction r = | 278 Reduction r = |
| 273 Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, | 279 Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, |
| 274 NumberConstant(rhs), context, effect, control)); | 280 NumberConstant(rhs), context, effect, control)); |
| 275 ASSERT_TRUE(r.Changed()); | 281 ASSERT_TRUE(r.Changed()); |
| 276 EXPECT_THAT(r.replacement(), IsWord32Sar(lhs, IsNumberConstant(rhs))); | 282 EXPECT_THAT(r.replacement(), |
| 283 IsWord32Sar(lhs, IsNumberConstant(BitEq(rhs)))); |
| 277 } | 284 } |
| 278 } | 285 } |
| 279 | 286 |
| 280 | 287 |
| 281 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) { | 288 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) { |
| 282 Node* const lhs = Parameter(Type::Signed32()); | 289 Node* const lhs = Parameter(Type::Signed32()); |
| 283 Node* const rhs = Parameter(Type::Unsigned32()); | 290 Node* const rhs = Parameter(Type::Unsigned32()); |
| 284 Node* const context = UndefinedConstant(); | 291 Node* const context = UndefinedConstant(); |
| 285 Node* const effect = graph()->start(); | 292 Node* const effect = graph()->start(); |
| 286 Node* const control = graph()->start(); | 293 Node* const control = graph()->start(); |
| 287 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, rhs, | 294 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, rhs, |
| 288 context, effect, control)); | 295 context, effect, control)); |
| 289 ASSERT_TRUE(r.Changed()); | 296 ASSERT_TRUE(r.Changed()); |
| 290 EXPECT_THAT(r.replacement(), | 297 EXPECT_THAT(r.replacement(), |
| 291 IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); | 298 IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); |
| 292 } | 299 } |
| 293 | 300 |
| 294 | 301 |
| 295 // ----------------------------------------------------------------------------- | 302 // ----------------------------------------------------------------------------- |
| 296 // JSShiftRightLogical | 303 // JSShiftRightLogical |
| 297 | 304 |
| 298 | 305 |
| 299 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndConstant) { | 306 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndConstant) { |
| 300 Node* const lhs = Parameter(Type::Unsigned32()); | 307 Node* const lhs = Parameter(Type::Unsigned32()); |
| 301 Node* const context = UndefinedConstant(); | 308 Node* const context = UndefinedConstant(); |
| 302 Node* const effect = graph()->start(); | 309 Node* const effect = graph()->start(); |
| 303 Node* const control = graph()->start(); | 310 Node* const control = graph()->start(); |
| 304 TRACED_FORRANGE(int32_t, rhs, 0, 31) { | 311 TRACED_FORRANGE(double, rhs, 0, 31) { |
| 305 Reduction r = | 312 Reduction r = |
| 306 Reduce(graph()->NewNode(javascript()->ShiftRightLogical(), lhs, | 313 Reduce(graph()->NewNode(javascript()->ShiftRightLogical(), lhs, |
| 307 NumberConstant(rhs), context, effect, control)); | 314 NumberConstant(rhs), context, effect, control)); |
| 308 ASSERT_TRUE(r.Changed()); | 315 ASSERT_TRUE(r.Changed()); |
| 309 EXPECT_THAT(r.replacement(), IsWord32Shr(lhs, IsNumberConstant(rhs))); | 316 EXPECT_THAT(r.replacement(), |
| 317 IsWord32Shr(lhs, IsNumberConstant(BitEq(rhs)))); |
| 310 } | 318 } |
| 311 } | 319 } |
| 312 | 320 |
| 313 | 321 |
| 314 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) { | 322 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) { |
| 315 Node* const lhs = Parameter(Type::Unsigned32()); | 323 Node* const lhs = Parameter(Type::Unsigned32()); |
| 316 Node* const rhs = Parameter(Type::Unsigned32()); | 324 Node* const rhs = Parameter(Type::Unsigned32()); |
| 317 Node* const context = UndefinedConstant(); | 325 Node* const context = UndefinedConstant(); |
| 318 Node* const effect = graph()->start(); | 326 Node* const effect = graph()->start(); |
| 319 Node* const control = graph()->start(); | 327 Node* const control = graph()->start(); |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 IsStoreElement( | 634 IsStoreElement( |
| 627 access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])), | 635 access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])), |
| 628 key, value, effect, control)); | 636 key, value, effect, control)); |
| 629 } | 637 } |
| 630 } | 638 } |
| 631 } | 639 } |
| 632 | 640 |
| 633 } // namespace compiler | 641 } // namespace compiler |
| 634 } // namespace internal | 642 } // namespace internal |
| 635 } // namespace v8 | 643 } // namespace v8 |
| OLD | NEW |