| 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/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
| 8 #include "test/cctest/compiler/codegen-tester.h" | 8 #include "test/cctest/compiler/codegen-tester.h" |
| 9 #include "test/cctest/compiler/graph-builder-tester.h" | 9 #include "test/cctest/compiler/graph-builder-tester.h" |
| 10 #include "test/cctest/compiler/value-helper.h" | 10 #include "test/cctest/compiler/value-helper.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 CHECK(m.HasValue()); | 76 CHECK(m.HasValue()); |
| 77 CheckDoubleEq(expected, m.Value()); | 77 CheckDoubleEq(expected, m.Value()); |
| 78 } | 78 } |
| 79 | 79 |
| 80 Node* Parameter(int index = 0) { | 80 Node* Parameter(int index = 0) { |
| 81 Node* n = graph()->NewNode(common()->Parameter(index), graph()->start()); | 81 Node* n = graph()->NewNode(common()->Parameter(index), graph()->start()); |
| 82 NodeProperties::SetType(n, Type::Any()); | 82 NodeProperties::SetType(n, Type::Any()); |
| 83 return n; | 83 return n; |
| 84 } | 84 } |
| 85 | 85 |
| 86 void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) { | 86 void CheckTypeError(MachineType from, MachineRepresentation to) { |
| 87 changer()->testing_type_errors_ = true; | 87 changer()->testing_type_errors_ = true; |
| 88 changer()->type_error_ = false; | 88 changer()->type_error_ = false; |
| 89 Node* n = Parameter(0); | 89 Node* n = Parameter(0); |
| 90 Node* c = changer()->GetRepresentationFor(n, from, to); | 90 Node* c = changer()->GetRepresentationFor(n, from, to); |
| 91 CHECK(changer()->type_error_); | 91 CHECK(changer()->type_error_); |
| 92 CHECK_EQ(n, c); | 92 CHECK_EQ(n, c); |
| 93 } | 93 } |
| 94 | 94 |
| 95 void CheckNop(MachineTypeUnion from, MachineTypeUnion to) { | 95 void CheckNop(MachineType from, MachineRepresentation to) { |
| 96 Node* n = Parameter(0); | 96 Node* n = Parameter(0); |
| 97 Node* c = changer()->GetRepresentationFor(n, from, to); | 97 Node* c = changer()->GetRepresentationFor(n, from, to); |
| 98 CHECK_EQ(n, c); | 98 CHECK_EQ(n, c); |
| 99 } | 99 } |
| 100 }; | 100 }; |
| 101 | 101 |
| 102 | 102 |
| 103 static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64, | 103 const MachineType kMachineTypes[] = { |
| 104 kRepFloat32, kRepFloat64, kRepTagged}; | 104 MachineType::Float32(), MachineType::Float64(), MachineType::Int8(), |
| 105 MachineType::Uint8(), MachineType::Int16(), MachineType::Uint16(), |
| 106 MachineType::Int32(), MachineType::Uint32(), MachineType::Int64(), |
| 107 MachineType::Uint64(), MachineType::AnyTagged()}; |
| 105 | 108 |
| 106 | 109 |
| 107 TEST(BoolToBit_constant) { | 110 TEST(BoolToBit_constant) { |
| 108 RepresentationChangerTester r; | 111 RepresentationChangerTester r; |
| 109 | 112 |
| 110 Node* true_node = r.jsgraph()->TrueConstant(); | 113 Node* true_node = r.jsgraph()->TrueConstant(); |
| 111 Node* true_bit = | 114 Node* true_bit = r.changer()->GetRepresentationFor( |
| 112 r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit); | 115 true_node, MachineType::RepTagged(), MachineRepresentation::kBit); |
| 113 r.CheckInt32Constant(true_bit, 1); | 116 r.CheckInt32Constant(true_bit, 1); |
| 114 | 117 |
| 115 Node* false_node = r.jsgraph()->FalseConstant(); | 118 Node* false_node = r.jsgraph()->FalseConstant(); |
| 116 Node* false_bit = | 119 Node* false_bit = r.changer()->GetRepresentationFor( |
| 117 r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit); | 120 false_node, MachineType::RepTagged(), MachineRepresentation::kBit); |
| 118 r.CheckInt32Constant(false_bit, 0); | 121 r.CheckInt32Constant(false_bit, 0); |
| 119 } | 122 } |
| 120 | 123 |
| 121 | 124 |
| 122 TEST(BitToBool_constant) { | 125 TEST(BitToBool_constant) { |
| 123 RepresentationChangerTester r; | 126 RepresentationChangerTester r; |
| 124 | 127 |
| 125 for (int i = -5; i < 5; i++) { | 128 for (int i = -5; i < 5; i++) { |
| 126 Node* node = r.jsgraph()->Int32Constant(i); | 129 Node* node = r.jsgraph()->Int32Constant(i); |
| 127 Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged); | 130 Node* val = r.changer()->GetRepresentationFor( |
| 131 node, MachineType::RepBit(), MachineRepresentation::kTagged); |
| 128 r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() | 132 r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() |
| 129 : r.isolate()->heap()->true_value()); | 133 : r.isolate()->heap()->true_value()); |
| 130 } | 134 } |
| 131 } | 135 } |
| 132 | 136 |
| 133 | 137 |
| 134 TEST(ToTagged_constant) { | 138 TEST(ToTagged_constant) { |
| 135 RepresentationChangerTester r; | 139 RepresentationChangerTester r; |
| 136 | 140 |
| 137 { | 141 { |
| 138 FOR_FLOAT64_INPUTS(i) { | 142 FOR_FLOAT64_INPUTS(i) { |
| 139 Node* n = r.jsgraph()->Float64Constant(*i); | 143 Node* n = r.jsgraph()->Float64Constant(*i); |
| 140 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); | 144 Node* c = r.changer()->GetRepresentationFor( |
| 145 n, MachineType::RepFloat64(), MachineRepresentation::kTagged); |
| 141 r.CheckNumberConstant(c, *i); | 146 r.CheckNumberConstant(c, *i); |
| 142 } | 147 } |
| 143 } | 148 } |
| 144 | 149 |
| 145 { | 150 { |
| 146 FOR_FLOAT64_INPUTS(i) { | 151 FOR_FLOAT64_INPUTS(i) { |
| 147 Node* n = r.jsgraph()->Constant(*i); | 152 Node* n = r.jsgraph()->Constant(*i); |
| 148 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); | 153 Node* c = r.changer()->GetRepresentationFor( |
| 154 n, MachineType::RepFloat64(), MachineRepresentation::kTagged); |
| 149 r.CheckNumberConstant(c, *i); | 155 r.CheckNumberConstant(c, *i); |
| 150 } | 156 } |
| 151 } | 157 } |
| 152 | 158 |
| 153 { | 159 { |
| 154 FOR_FLOAT32_INPUTS(i) { | 160 FOR_FLOAT32_INPUTS(i) { |
| 155 Node* n = r.jsgraph()->Float32Constant(*i); | 161 Node* n = r.jsgraph()->Float32Constant(*i); |
| 156 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepTagged); | 162 Node* c = r.changer()->GetRepresentationFor( |
| 163 n, MachineType::RepFloat32(), MachineRepresentation::kTagged); |
| 157 r.CheckNumberConstant(c, *i); | 164 r.CheckNumberConstant(c, *i); |
| 158 } | 165 } |
| 159 } | 166 } |
| 160 | 167 |
| 161 { | 168 { |
| 162 FOR_INT32_INPUTS(i) { | 169 FOR_INT32_INPUTS(i) { |
| 163 Node* n = r.jsgraph()->Int32Constant(*i); | 170 Node* n = r.jsgraph()->Int32Constant(*i); |
| 164 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 171 Node* c = r.changer()->GetRepresentationFor( |
| 165 kRepTagged); | 172 n, MachineType::Int32(), MachineRepresentation::kTagged); |
| 166 r.CheckNumberConstant(c, *i); | 173 r.CheckNumberConstant(c, *i); |
| 167 } | 174 } |
| 168 } | 175 } |
| 169 | 176 |
| 170 { | 177 { |
| 171 FOR_UINT32_INPUTS(i) { | 178 FOR_UINT32_INPUTS(i) { |
| 172 Node* n = r.jsgraph()->Int32Constant(*i); | 179 Node* n = r.jsgraph()->Int32Constant(*i); |
| 173 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 180 Node* c = r.changer()->GetRepresentationFor( |
| 174 kRepTagged); | 181 n, MachineType::Uint32(), MachineRepresentation::kTagged); |
| 175 r.CheckNumberConstant(c, *i); | 182 r.CheckNumberConstant(c, *i); |
| 176 } | 183 } |
| 177 } | 184 } |
| 178 } | 185 } |
| 179 | 186 |
| 180 | 187 |
| 181 TEST(ToFloat64_constant) { | 188 TEST(ToFloat64_constant) { |
| 182 RepresentationChangerTester r; | 189 RepresentationChangerTester r; |
| 183 | 190 |
| 184 { | 191 { |
| 185 FOR_FLOAT64_INPUTS(i) { | 192 FOR_FLOAT64_INPUTS(i) { |
| 186 Node* n = r.jsgraph()->Float64Constant(*i); | 193 Node* n = r.jsgraph()->Float64Constant(*i); |
| 187 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat64); | 194 Node* c = r.changer()->GetRepresentationFor( |
| 195 n, MachineType::RepFloat64(), MachineRepresentation::kFloat64); |
| 188 CHECK_EQ(n, c); | 196 CHECK_EQ(n, c); |
| 189 } | 197 } |
| 190 } | 198 } |
| 191 | 199 |
| 192 { | 200 { |
| 193 FOR_FLOAT64_INPUTS(i) { | 201 FOR_FLOAT64_INPUTS(i) { |
| 194 Node* n = r.jsgraph()->Constant(*i); | 202 Node* n = r.jsgraph()->Constant(*i); |
| 195 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat64); | 203 Node* c = r.changer()->GetRepresentationFor( |
| 204 n, MachineType::RepTagged(), MachineRepresentation::kFloat64); |
| 196 r.CheckFloat64Constant(c, *i); | 205 r.CheckFloat64Constant(c, *i); |
| 197 } | 206 } |
| 198 } | 207 } |
| 199 | 208 |
| 200 { | 209 { |
| 201 FOR_FLOAT32_INPUTS(i) { | 210 FOR_FLOAT32_INPUTS(i) { |
| 202 Node* n = r.jsgraph()->Float32Constant(*i); | 211 Node* n = r.jsgraph()->Float32Constant(*i); |
| 203 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat64); | 212 Node* c = r.changer()->GetRepresentationFor( |
| 213 n, MachineType::RepFloat32(), MachineRepresentation::kFloat64); |
| 204 r.CheckFloat64Constant(c, *i); | 214 r.CheckFloat64Constant(c, *i); |
| 205 } | 215 } |
| 206 } | 216 } |
| 207 | 217 |
| 208 { | 218 { |
| 209 FOR_INT32_INPUTS(i) { | 219 FOR_INT32_INPUTS(i) { |
| 210 Node* n = r.jsgraph()->Int32Constant(*i); | 220 Node* n = r.jsgraph()->Int32Constant(*i); |
| 211 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 221 Node* c = r.changer()->GetRepresentationFor( |
| 212 kRepFloat64); | 222 n, MachineType::Int32(), MachineRepresentation::kFloat64); |
| 213 r.CheckFloat64Constant(c, *i); | 223 r.CheckFloat64Constant(c, *i); |
| 214 } | 224 } |
| 215 } | 225 } |
| 216 | 226 |
| 217 { | 227 { |
| 218 FOR_UINT32_INPUTS(i) { | 228 FOR_UINT32_INPUTS(i) { |
| 219 Node* n = r.jsgraph()->Int32Constant(*i); | 229 Node* n = r.jsgraph()->Int32Constant(*i); |
| 220 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 230 Node* c = r.changer()->GetRepresentationFor( |
| 221 kRepFloat64); | 231 n, MachineType::Uint32(), MachineRepresentation::kFloat64); |
| 222 r.CheckFloat64Constant(c, *i); | 232 r.CheckFloat64Constant(c, *i); |
| 223 } | 233 } |
| 224 } | 234 } |
| 225 } | 235 } |
| 226 | 236 |
| 227 | 237 |
| 228 static bool IsFloat32Int32(int32_t val) { | 238 static bool IsFloat32Int32(int32_t val) { |
| 229 return val >= -(1 << 23) && val <= (1 << 23); | 239 return val >= -(1 << 23) && val <= (1 << 23); |
| 230 } | 240 } |
| 231 | 241 |
| 232 | 242 |
| 233 static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); } | 243 static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); } |
| 234 | 244 |
| 235 | 245 |
| 236 TEST(ToFloat32_constant) { | 246 TEST(ToFloat32_constant) { |
| 237 RepresentationChangerTester r; | 247 RepresentationChangerTester r; |
| 238 | 248 |
| 239 { | 249 { |
| 240 FOR_FLOAT32_INPUTS(i) { | 250 FOR_FLOAT32_INPUTS(i) { |
| 241 Node* n = r.jsgraph()->Float32Constant(*i); | 251 Node* n = r.jsgraph()->Float32Constant(*i); |
| 242 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat32); | 252 Node* c = r.changer()->GetRepresentationFor( |
| 253 n, MachineType::RepFloat32(), MachineRepresentation::kFloat32); |
| 243 CHECK_EQ(n, c); | 254 CHECK_EQ(n, c); |
| 244 } | 255 } |
| 245 } | 256 } |
| 246 | 257 |
| 247 { | 258 { |
| 248 FOR_FLOAT32_INPUTS(i) { | 259 FOR_FLOAT32_INPUTS(i) { |
| 249 Node* n = r.jsgraph()->Constant(*i); | 260 Node* n = r.jsgraph()->Constant(*i); |
| 250 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat32); | 261 Node* c = r.changer()->GetRepresentationFor( |
| 262 n, MachineType::RepTagged(), MachineRepresentation::kFloat32); |
| 251 r.CheckFloat32Constant(c, *i); | 263 r.CheckFloat32Constant(c, *i); |
| 252 } | 264 } |
| 253 } | 265 } |
| 254 | 266 |
| 255 { | 267 { |
| 256 FOR_FLOAT32_INPUTS(i) { | 268 FOR_FLOAT32_INPUTS(i) { |
| 257 Node* n = r.jsgraph()->Float64Constant(*i); | 269 Node* n = r.jsgraph()->Float64Constant(*i); |
| 258 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat32); | 270 Node* c = r.changer()->GetRepresentationFor( |
| 271 n, MachineType::RepFloat64(), MachineRepresentation::kFloat32); |
| 259 r.CheckFloat32Constant(c, *i); | 272 r.CheckFloat32Constant(c, *i); |
| 260 } | 273 } |
| 261 } | 274 } |
| 262 | 275 |
| 263 { | 276 { |
| 264 FOR_INT32_INPUTS(i) { | 277 FOR_INT32_INPUTS(i) { |
| 265 if (!IsFloat32Int32(*i)) continue; | 278 if (!IsFloat32Int32(*i)) continue; |
| 266 Node* n = r.jsgraph()->Int32Constant(*i); | 279 Node* n = r.jsgraph()->Int32Constant(*i); |
| 267 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 280 Node* c = r.changer()->GetRepresentationFor( |
| 268 kRepFloat32); | 281 n, MachineType::Int32(), MachineRepresentation::kFloat32); |
| 269 r.CheckFloat32Constant(c, static_cast<float>(*i)); | 282 r.CheckFloat32Constant(c, static_cast<float>(*i)); |
| 270 } | 283 } |
| 271 } | 284 } |
| 272 | 285 |
| 273 { | 286 { |
| 274 FOR_UINT32_INPUTS(i) { | 287 FOR_UINT32_INPUTS(i) { |
| 275 if (!IsFloat32Uint32(*i)) continue; | 288 if (!IsFloat32Uint32(*i)) continue; |
| 276 Node* n = r.jsgraph()->Int32Constant(*i); | 289 Node* n = r.jsgraph()->Int32Constant(*i); |
| 277 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 290 Node* c = r.changer()->GetRepresentationFor( |
| 278 kRepFloat32); | 291 n, MachineType::Uint32(), MachineRepresentation::kFloat32); |
| 279 r.CheckFloat32Constant(c, static_cast<float>(*i)); | 292 r.CheckFloat32Constant(c, static_cast<float>(*i)); |
| 280 } | 293 } |
| 281 } | 294 } |
| 282 } | 295 } |
| 283 | 296 |
| 284 | 297 |
| 285 TEST(ToInt32_constant) { | 298 TEST(ToInt32_constant) { |
| 286 RepresentationChangerTester r; | 299 RepresentationChangerTester r; |
| 287 | 300 |
| 288 { | 301 { |
| 289 FOR_INT32_INPUTS(i) { | 302 FOR_INT32_INPUTS(i) { |
| 290 Node* n = r.jsgraph()->Int32Constant(*i); | 303 Node* n = r.jsgraph()->Int32Constant(*i); |
| 291 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 304 Node* c = r.changer()->GetRepresentationFor( |
| 292 kRepWord32); | 305 n, MachineType::Int32(), MachineRepresentation::kWord32); |
| 293 r.CheckInt32Constant(c, *i); | 306 r.CheckInt32Constant(c, *i); |
| 294 } | 307 } |
| 295 } | 308 } |
| 296 | 309 |
| 297 { | 310 { |
| 298 FOR_INT32_INPUTS(i) { | 311 FOR_INT32_INPUTS(i) { |
| 299 if (!IsFloat32Int32(*i)) continue; | 312 if (!IsFloat32Int32(*i)) continue; |
| 300 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); | 313 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); |
| 301 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeInt32, | 314 Node* c = r.changer()->GetRepresentationFor( |
| 302 kRepWord32); | 315 n, |
| 316 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kInt32), |
| 317 MachineRepresentation::kWord32); |
| 303 r.CheckInt32Constant(c, *i); | 318 r.CheckInt32Constant(c, *i); |
| 304 } | 319 } |
| 305 } | 320 } |
| 306 | 321 |
| 307 { | 322 { |
| 308 FOR_INT32_INPUTS(i) { | 323 FOR_INT32_INPUTS(i) { |
| 309 Node* n = r.jsgraph()->Float64Constant(*i); | 324 Node* n = r.jsgraph()->Float64Constant(*i); |
| 310 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeInt32, | 325 Node* c = r.changer()->GetRepresentationFor( |
| 311 kRepWord32); | 326 n, |
| 327 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kInt32), |
| 328 MachineRepresentation::kWord32); |
| 312 r.CheckInt32Constant(c, *i); | 329 r.CheckInt32Constant(c, *i); |
| 313 } | 330 } |
| 314 } | 331 } |
| 315 | 332 |
| 316 { | 333 { |
| 317 FOR_INT32_INPUTS(i) { | 334 FOR_INT32_INPUTS(i) { |
| 318 Node* n = r.jsgraph()->Constant(*i); | 335 Node* n = r.jsgraph()->Constant(*i); |
| 319 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeInt32, | 336 Node* c = r.changer()->GetRepresentationFor( |
| 320 kRepWord32); | 337 n, |
| 338 MachineType(MachineRepresentation::kTagged, MachineSemantic::kInt32), |
| 339 MachineRepresentation::kWord32); |
| 321 r.CheckInt32Constant(c, *i); | 340 r.CheckInt32Constant(c, *i); |
| 322 } | 341 } |
| 323 } | 342 } |
| 324 } | 343 } |
| 325 | 344 |
| 326 | 345 |
| 327 TEST(ToUint32_constant) { | 346 TEST(ToUint32_constant) { |
| 328 RepresentationChangerTester r; | 347 RepresentationChangerTester r; |
| 329 | 348 |
| 330 { | 349 { |
| 331 FOR_UINT32_INPUTS(i) { | 350 FOR_UINT32_INPUTS(i) { |
| 332 Node* n = r.jsgraph()->Int32Constant(*i); | 351 Node* n = r.jsgraph()->Int32Constant(*i); |
| 333 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 352 Node* c = r.changer()->GetRepresentationFor( |
| 334 kRepWord32); | 353 n, MachineType::Uint32(), MachineRepresentation::kWord32); |
| 335 r.CheckUint32Constant(c, *i); | 354 r.CheckUint32Constant(c, *i); |
| 336 } | 355 } |
| 337 } | 356 } |
| 338 | 357 |
| 339 { | 358 { |
| 340 FOR_UINT32_INPUTS(i) { | 359 FOR_UINT32_INPUTS(i) { |
| 341 if (!IsFloat32Uint32(*i)) continue; | 360 if (!IsFloat32Uint32(*i)) continue; |
| 342 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); | 361 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); |
| 343 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeUint32, | 362 Node* c = r.changer()->GetRepresentationFor( |
| 344 kRepWord32); | 363 n, MachineType(MachineRepresentation::kFloat32, |
| 364 MachineSemantic::kUint32), |
| 365 MachineRepresentation::kWord32); |
| 345 r.CheckUint32Constant(c, *i); | 366 r.CheckUint32Constant(c, *i); |
| 346 } | 367 } |
| 347 } | 368 } |
| 348 | 369 |
| 349 { | 370 { |
| 350 FOR_UINT32_INPUTS(i) { | 371 FOR_UINT32_INPUTS(i) { |
| 351 Node* n = r.jsgraph()->Float64Constant(*i); | 372 Node* n = r.jsgraph()->Float64Constant(*i); |
| 352 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeUint32, | 373 Node* c = r.changer()->GetRepresentationFor( |
| 353 kRepWord32); | 374 n, MachineType(MachineRepresentation::kFloat64, |
| 375 MachineSemantic::kUint32), |
| 376 MachineRepresentation::kWord32); |
| 354 r.CheckUint32Constant(c, *i); | 377 r.CheckUint32Constant(c, *i); |
| 355 } | 378 } |
| 356 } | 379 } |
| 357 | 380 |
| 358 { | 381 { |
| 359 FOR_UINT32_INPUTS(i) { | 382 FOR_UINT32_INPUTS(i) { |
| 360 Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); | 383 Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); |
| 361 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32, | 384 Node* c = r.changer()->GetRepresentationFor( |
| 362 kRepWord32); | 385 n, |
| 386 MachineType(MachineRepresentation::kTagged, MachineSemantic::kUint32), |
| 387 MachineRepresentation::kWord32); |
| 363 r.CheckUint32Constant(c, *i); | 388 r.CheckUint32Constant(c, *i); |
| 364 } | 389 } |
| 365 } | 390 } |
| 366 } | 391 } |
| 367 | 392 |
| 368 | 393 |
| 369 static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, | 394 static void CheckChange(IrOpcode::Value expected, MachineType from, |
| 370 MachineTypeUnion to) { | 395 MachineRepresentation to) { |
| 371 RepresentationChangerTester r; | 396 RepresentationChangerTester r; |
| 372 | 397 |
| 373 Node* n = r.Parameter(); | 398 Node* n = r.Parameter(); |
| 374 Node* c = r.changer()->GetRepresentationFor(n, from, to); | 399 Node* c = r.changer()->GetRepresentationFor(n, from, to); |
| 375 | 400 |
| 376 CHECK_NE(c, n); | 401 CHECK_NE(c, n); |
| 377 CHECK_EQ(expected, c->opcode()); | 402 CHECK_EQ(expected, c->opcode()); |
| 378 CHECK_EQ(n, c->InputAt(0)); | 403 CHECK_EQ(n, c->InputAt(0)); |
| 379 } | 404 } |
| 380 | 405 |
| 381 | 406 |
| 382 static void CheckTwoChanges(IrOpcode::Value expected2, | 407 static void CheckTwoChanges(IrOpcode::Value expected2, |
| 383 IrOpcode::Value expected1, MachineTypeUnion from, | 408 IrOpcode::Value expected1, MachineType from, |
| 384 MachineTypeUnion to) { | 409 MachineRepresentation to) { |
| 385 RepresentationChangerTester r; | 410 RepresentationChangerTester r; |
| 386 | 411 |
| 387 Node* n = r.Parameter(); | 412 Node* n = r.Parameter(); |
| 388 Node* c1 = r.changer()->GetRepresentationFor(n, from, to); | 413 Node* c1 = r.changer()->GetRepresentationFor(n, from, to); |
| 389 | 414 |
| 390 CHECK_NE(c1, n); | 415 CHECK_NE(c1, n); |
| 391 CHECK_EQ(expected1, c1->opcode()); | 416 CHECK_EQ(expected1, c1->opcode()); |
| 392 Node* c2 = c1->InputAt(0); | 417 Node* c2 = c1->InputAt(0); |
| 393 CHECK_NE(c2, n); | 418 CHECK_NE(c2, n); |
| 394 CHECK_EQ(expected2, c2->opcode()); | 419 CHECK_EQ(expected2, c2->opcode()); |
| 395 CHECK_EQ(n, c2->InputAt(0)); | 420 CHECK_EQ(n, c2->InputAt(0)); |
| 396 } | 421 } |
| 397 | 422 |
| 398 | 423 |
| 399 TEST(SingleChanges) { | 424 TEST(SingleChanges) { |
| 400 CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit); | 425 CheckChange(IrOpcode::kChangeBoolToBit, MachineType::RepTagged(), |
| 401 CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged); | 426 MachineRepresentation::kBit); |
| 427 CheckChange(IrOpcode::kChangeBitToBool, MachineType::RepBit(), |
| 428 MachineRepresentation::kTagged); |
| 402 | 429 |
| 403 CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32, | 430 CheckChange(IrOpcode::kChangeInt32ToTagged, MachineType::Int32(), |
| 404 kRepTagged); | 431 MachineRepresentation::kTagged); |
| 405 CheckChange(IrOpcode::kChangeUint32ToTagged, kRepWord32 | kTypeUint32, | 432 CheckChange(IrOpcode::kChangeUint32ToTagged, MachineType::Uint32(), |
| 406 kRepTagged); | 433 MachineRepresentation::kTagged); |
| 407 CheckChange(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, kRepTagged); | 434 CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineType::RepFloat64(), |
| 435 MachineRepresentation::kTagged); |
| 408 | 436 |
| 409 CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32, | 437 CheckChange( |
| 410 kRepWord32); | 438 IrOpcode::kChangeTaggedToInt32, |
| 411 CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged | kTypeUint32, | 439 MachineType(MachineRepresentation::kTagged, MachineSemantic::kInt32), |
| 412 kRepWord32); | 440 MachineRepresentation::kWord32); |
| 413 CheckChange(IrOpcode::kChangeTaggedToFloat64, kRepTagged, kRepFloat64); | 441 CheckChange( |
| 442 IrOpcode::kChangeTaggedToUint32, |
| 443 MachineType(MachineRepresentation::kTagged, MachineSemantic::kUint32), |
| 444 MachineRepresentation::kWord32); |
| 445 CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineType::RepTagged(), |
| 446 MachineRepresentation::kFloat64); |
| 414 | 447 |
| 415 // Int32,Uint32 <-> Float64 are actually machine conversions. | 448 // Int32,Uint32 <-> Float64 are actually machine conversions. |
| 416 CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32 | kTypeInt32, | 449 CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineType::Int32(), |
| 417 kRepFloat64); | 450 MachineRepresentation::kFloat64); |
| 418 CheckChange(IrOpcode::kChangeUint32ToFloat64, kRepWord32 | kTypeUint32, | 451 CheckChange(IrOpcode::kChangeUint32ToFloat64, MachineType::Uint32(), |
| 419 kRepFloat64); | 452 MachineRepresentation::kFloat64); |
| 420 CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64 | kTypeInt32, | 453 CheckChange( |
| 421 kRepWord32); | 454 IrOpcode::kChangeFloat64ToInt32, |
| 422 CheckChange(IrOpcode::kChangeFloat64ToUint32, kRepFloat64 | kTypeUint32, | 455 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kInt32), |
| 423 kRepWord32); | 456 MachineRepresentation::kWord32); |
| 457 CheckChange( |
| 458 IrOpcode::kChangeFloat64ToUint32, |
| 459 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kUint32), |
| 460 MachineRepresentation::kWord32); |
| 424 | 461 |
| 425 CheckChange(IrOpcode::kTruncateFloat64ToFloat32, kRepFloat64, kRepFloat32); | 462 CheckChange(IrOpcode::kTruncateFloat64ToFloat32, MachineType::RepFloat64(), |
| 463 MachineRepresentation::kFloat32); |
| 426 | 464 |
| 427 // Int32,Uint32 <-> Float32 require two changes. | 465 // Int32,Uint32 <-> Float32 require two changes. |
| 428 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, | 466 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, |
| 429 IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeInt32, | 467 IrOpcode::kTruncateFloat64ToFloat32, MachineType::Int32(), |
| 430 kRepFloat32); | 468 MachineRepresentation::kFloat32); |
| 431 CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64, | 469 CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64, |
| 432 IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeUint32, | 470 IrOpcode::kTruncateFloat64ToFloat32, MachineType::Uint32(), |
| 433 kRepFloat32); | 471 MachineRepresentation::kFloat32); |
| 434 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 472 CheckTwoChanges( |
| 435 IrOpcode::kChangeFloat64ToInt32, kRepFloat32 | kTypeInt32, | 473 IrOpcode::kChangeFloat32ToFloat64, IrOpcode::kChangeFloat64ToInt32, |
| 436 kRepWord32); | 474 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kInt32), |
| 437 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 475 MachineRepresentation::kWord32); |
| 438 IrOpcode::kChangeFloat64ToUint32, kRepFloat32 | kTypeUint32, | 476 CheckTwoChanges( |
| 439 kRepWord32); | 477 IrOpcode::kChangeFloat32ToFloat64, IrOpcode::kChangeFloat64ToUint32, |
| 478 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kUint32), |
| 479 MachineRepresentation::kWord32); |
| 440 | 480 |
| 441 // Float32 <-> Tagged require two changes. | 481 // Float32 <-> Tagged require two changes. |
| 442 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 482 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, |
| 443 IrOpcode::kChangeFloat64ToTagged, kRepFloat32, kRepTagged); | 483 IrOpcode::kChangeFloat64ToTagged, MachineType::RepFloat32(), |
| 484 MachineRepresentation::kTagged); |
| 444 CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, | 485 CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, |
| 445 IrOpcode::kTruncateFloat64ToFloat32, kRepTagged, kRepFloat32); | 486 IrOpcode::kTruncateFloat64ToFloat32, MachineType::RepTagged(), |
| 487 MachineRepresentation::kFloat32); |
| 446 } | 488 } |
| 447 | 489 |
| 448 | 490 |
| 449 TEST(SignednessInWord32) { | 491 TEST(SignednessInWord32) { |
| 450 RepresentationChangerTester r; | 492 RepresentationChangerTester r; |
| 451 | 493 |
| 452 CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32, | 494 CheckChange( |
| 453 kRepWord32); | 495 IrOpcode::kChangeTaggedToInt32, |
| 454 CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged | kTypeUint32, | 496 MachineType(MachineRepresentation::kTagged, MachineSemantic::kInt32), |
| 455 kRepWord32); | 497 MachineRepresentation::kWord32); |
| 456 CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64); | 498 CheckChange( |
| 457 CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64 | kTypeInt32, | 499 IrOpcode::kChangeTaggedToUint32, |
| 458 kRepWord32); | 500 MachineType(MachineRepresentation::kTagged, MachineSemantic::kUint32), |
| 459 CheckChange(IrOpcode::kTruncateFloat64ToInt32, kRepFloat64, kRepWord32); | 501 MachineRepresentation::kWord32); |
| 502 CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineType::RepWord32(), |
| 503 MachineRepresentation::kFloat64); |
| 504 CheckChange( |
| 505 IrOpcode::kChangeFloat64ToInt32, |
| 506 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kInt32), |
| 507 MachineRepresentation::kWord32); |
| 508 CheckChange(IrOpcode::kTruncateFloat64ToInt32, MachineType::RepFloat64(), |
| 509 MachineRepresentation::kWord32); |
| 460 | 510 |
| 461 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, | 511 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, |
| 462 IrOpcode::kTruncateFloat64ToFloat32, kRepWord32, kRepFloat32); | 512 IrOpcode::kTruncateFloat64ToFloat32, MachineType::RepWord32(), |
| 513 MachineRepresentation::kFloat32); |
| 463 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 514 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, |
| 464 IrOpcode::kTruncateFloat64ToInt32, kRepFloat32, kRepWord32); | 515 IrOpcode::kTruncateFloat64ToInt32, MachineType::RepFloat32(), |
| 516 MachineRepresentation::kWord32); |
| 465 } | 517 } |
| 466 | 518 |
| 467 | 519 |
| 468 TEST(Nops) { | 520 TEST(Nops) { |
| 469 RepresentationChangerTester r; | 521 RepresentationChangerTester r; |
| 470 | 522 |
| 471 // X -> X is always a nop for any single representation X. | 523 // X -> X is always a nop for any single representation X. |
| 472 for (size_t i = 0; i < arraysize(all_reps); i++) { | 524 for (size_t i = 0; i < arraysize(kMachineTypes); i++) { |
| 473 r.CheckNop(all_reps[i], all_reps[i]); | 525 r.CheckNop(kMachineTypes[i], kMachineTypes[i].representation()); |
| 474 } | 526 } |
| 475 | 527 |
| 476 // 32-bit floats. | 528 // 32-bit floats. |
| 477 r.CheckNop(kRepFloat32, kRepFloat32); | 529 r.CheckNop(MachineType::RepFloat32(), MachineRepresentation::kFloat32); |
| 478 r.CheckNop(kRepFloat32 | kTypeNumber, kRepFloat32); | 530 r.CheckNop(MachineType::Float32(), MachineRepresentation::kFloat32); |
| 479 | 531 |
| 480 // 32-bit words can be used as smaller word sizes and vice versa, because | 532 // 32-bit words can be used as smaller word sizes and vice versa, because |
| 481 // loads from memory implicitly sign or zero extend the value to the | 533 // loads from memory implicitly sign or zero extend the value to the |
| 482 // full machine word size, and stores implicitly truncate. | 534 // full machine word size, and stores implicitly truncate. |
| 483 r.CheckNop(kRepWord32, kRepWord8); | 535 r.CheckNop(MachineType::Int32(), MachineRepresentation::kWord8); |
| 484 r.CheckNop(kRepWord32, kRepWord16); | 536 r.CheckNop(MachineType::Int32(), MachineRepresentation::kWord16); |
| 485 r.CheckNop(kRepWord32, kRepWord32); | 537 r.CheckNop(MachineType::Int32(), MachineRepresentation::kWord32); |
| 486 r.CheckNop(kRepWord8, kRepWord32); | 538 r.CheckNop(MachineType::Int8(), MachineRepresentation::kWord32); |
| 487 r.CheckNop(kRepWord16, kRepWord32); | 539 r.CheckNop(MachineType::Int16(), MachineRepresentation::kWord32); |
| 488 | 540 |
| 489 // kRepBit (result of comparison) is implicitly a wordish thing. | 541 // kRepBit (result of comparison) is implicitly a wordish thing. |
| 490 r.CheckNop(kRepBit, kRepWord8); | 542 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord8); |
| 491 r.CheckNop(kRepBit | kTypeBool, kRepWord8); | 543 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord16); |
| 492 r.CheckNop(kRepBit, kRepWord16); | 544 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord32); |
| 493 r.CheckNop(kRepBit | kTypeBool, kRepWord16); | 545 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord64); |
| 494 r.CheckNop(kRepBit, kRepWord32); | 546 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord8); |
| 495 r.CheckNop(kRepBit | kTypeBool, kRepWord32); | 547 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord16); |
| 496 r.CheckNop(kRepBit, kRepWord64); | 548 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord32); |
| 497 r.CheckNop(kRepBit | kTypeBool, kRepWord64); | 549 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord64); |
| 498 } | 550 } |
| 499 | 551 |
| 500 | 552 |
| 501 TEST(TypeErrors) { | 553 TEST(TypeErrors) { |
| 502 RepresentationChangerTester r; | 554 RepresentationChangerTester r; |
| 503 | 555 |
| 504 // Wordish cannot be implicitly converted to/from comparison conditions. | 556 // Wordish cannot be implicitly converted to/from comparison conditions. |
| 505 r.CheckTypeError(kRepWord8, kRepBit); | 557 r.CheckTypeError(MachineType::RepWord8(), MachineRepresentation::kBit); |
| 506 r.CheckTypeError(kRepWord16, kRepBit); | 558 r.CheckTypeError(MachineType::RepWord16(), MachineRepresentation::kBit); |
| 507 r.CheckTypeError(kRepWord32, kRepBit); | 559 r.CheckTypeError(MachineType::RepWord32(), MachineRepresentation::kBit); |
| 508 r.CheckTypeError(kRepWord64, kRepBit); | 560 r.CheckTypeError(MachineType::RepWord64(), MachineRepresentation::kBit); |
| 509 | 561 |
| 510 // Floats cannot be implicitly converted to/from comparison conditions. | 562 // Floats cannot be implicitly converted to/from comparison conditions. |
| 511 r.CheckTypeError(kRepFloat64, kRepBit); | 563 r.CheckTypeError(MachineType::RepFloat64(), MachineRepresentation::kBit); |
| 512 r.CheckTypeError(kRepBit, kRepFloat64); | 564 r.CheckTypeError(MachineType::RepBit(), MachineRepresentation::kFloat64); |
| 513 r.CheckTypeError(kRepBit | kTypeBool, kRepFloat64); | 565 r.CheckTypeError(MachineType::Bool(), MachineRepresentation::kFloat64); |
| 514 | 566 |
| 515 // Floats cannot be implicitly converted to/from comparison conditions. | 567 // Floats cannot be implicitly converted to/from comparison conditions. |
| 516 r.CheckTypeError(kRepFloat32, kRepBit); | 568 r.CheckTypeError(MachineType::RepFloat32(), MachineRepresentation::kBit); |
| 517 r.CheckTypeError(kRepBit, kRepFloat32); | 569 r.CheckTypeError(MachineType::RepBit(), MachineRepresentation::kFloat32); |
| 518 r.CheckTypeError(kRepBit | kTypeBool, kRepFloat32); | 570 r.CheckTypeError(MachineType::Bool(), MachineRepresentation::kFloat32); |
| 519 | 571 |
| 520 // Word64 is internal and shouldn't be implicitly converted. | 572 // Word64 is internal and shouldn't be implicitly converted. |
| 521 r.CheckTypeError(kRepWord64, kRepTagged); | 573 r.CheckTypeError(MachineType::RepWord64(), MachineRepresentation::kTagged); |
| 522 r.CheckTypeError(kRepTagged, kRepWord64); | 574 r.CheckTypeError(MachineType::RepTagged(), MachineRepresentation::kWord64); |
| 523 r.CheckTypeError(kRepTagged | kTypeBool, kRepWord64); | 575 r.CheckTypeError(MachineType::TaggedBool(), MachineRepresentation::kWord64); |
| 524 | 576 |
| 525 // Word64 / Word32 shouldn't be implicitly converted. | 577 // Word64 / Word32 shouldn't be implicitly converted. |
| 526 r.CheckTypeError(kRepWord64, kRepWord32); | 578 r.CheckTypeError(MachineType::RepWord64(), MachineRepresentation::kWord32); |
| 527 r.CheckTypeError(kRepWord32, kRepWord64); | 579 r.CheckTypeError(MachineType::RepWord32(), MachineRepresentation::kWord64); |
| 528 r.CheckTypeError(kRepWord32 | kTypeInt32, kRepWord64); | 580 r.CheckTypeError(MachineType::Int32(), MachineRepresentation::kWord64); |
| 529 r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64); | 581 r.CheckTypeError(MachineType::Uint32(), MachineRepresentation::kWord64); |
| 530 | |
| 531 for (size_t i = 0; i < arraysize(all_reps); i++) { | |
| 532 for (size_t j = 0; j < arraysize(all_reps); j++) { | |
| 533 if (i == j) continue; | |
| 534 // Only a single from representation is allowed. | |
| 535 r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged); | |
| 536 } | |
| 537 } | |
| 538 } | 582 } |
| 539 | 583 |
| 540 } // namespace compiler | 584 } // namespace compiler |
| 541 } // namespace internal | 585 } // namespace internal |
| 542 } // namespace v8 | 586 } // namespace v8 |
| OLD | NEW |