2400 {
2401
2402
2406 auto* const replacement =
2407 flow_graph->TryCreateConstantReplacementFor(this, value);
2408 if (replacement != this) {
2409 return replacement;
2410 }
2411 }
2412
2413
2414
2415
2416
2417 if (
left()->BindsToConstant() &&
right()->BindsToConstant()) {
2421
2423 return flow_graph->TryCreateConstantReplacementFor(
this,
result);
2424 }
2425 }
2426
2427 if (
left()->BindsToConstant() && !
right()->BindsToConstant() &&
2431 SetInputAt(0, r);
2432 SetInputAt(1, l);
2433 }
2434
2435 int64_t rhs;
2437 return this;
2438 }
2439
2442 case Token::kMUL:
2443 case Token::kSUB:
2444 case Token::kADD:
2445 case Token::kBIT_AND:
2446 case Token::kBIT_OR:
2447 case Token::kBIT_XOR:
2449 break;
2450 default:
2451 break;
2452 }
2453 }
2454
2455 if (IsBinaryUint32Op() && HasUnmatchedInputRepresentations()) {
2456
2457
2458
2459 return this;
2460 }
2461
2463 case Token::kMUL:
2464 if (rhs == 1) {
2466 } else if (rhs == 0) {
2471 (SpeculativeModeOfInputs() == kNotSpeculative) ? kUnboxedInt64
2472 : kTagged;
2473 ConstantInstr* constant_shift_amount = flow_graph->GetConstant(
2476 representation(), Token::kSHL,
left()->CopyWithType(),
2479 if (shift != nullptr) {
2480
2481
2482 if (auto shift_with_range = shift->AsShiftIntegerOp()) {
2483 shift_with_range->set_shift_range(
2486 }
2488 ASSERT(!shift->MayThrow());
2489 }
2490 if (!CanDeoptimize()) {
2491 ASSERT(!shift->CanDeoptimize());
2492 }
2494 return shift;
2495 }
2496 }
2497
2498 break;
2499 case Token::kADD:
2500 if (rhs == 0) {
2502 }
2503 break;
2504 case Token::kBIT_AND:
2505 if (rhs == 0) {
2509 }
2510 break;
2511 case Token::kBIT_OR:
2512 if (rhs == 0) {
2516 }
2517 break;
2518 case Token::kBIT_XOR:
2519 if (rhs == 0) {
2523 representation(), Token::kBIT_NOT,
left()->CopyWithType(),
2524 GetDeoptId(), SpeculativeModeOfInputs(), range());
2525 if (bit_not != nullptr) {
2527 return bit_not;
2528 }
2529 }
2530 break;
2531
2532 case Token::kSUB:
2533 if (rhs == 0) {
2535 }
2536 break;
2537
2538 case Token::kTRUNCDIV:
2539 if (rhs == 1) {
2541 } else if (rhs == -1) {
2543 representation(), Token::kNEGATE,
left()->CopyWithType(),
2544 GetDeoptId(), SpeculativeModeOfInputs(), range());
2545 if (negation != nullptr) {
2547 return negation;
2548 }
2549 }
2550 break;
2551
2552 case Token::kMOD:
2553 if (std::abs(rhs) == 1) {
2554 return flow_graph->TryCreateConstantReplacementFor(this,
2555 Object::smi_zero());
2556 }
2557 break;
2558
2559 case Token::kUSHR:
2561 return flow_graph->TryCreateConstantReplacementFor(this,
2562 Object::smi_zero());
2563 }
2565 case Token::kSHR:
2566 if (rhs == 0) {
2568 } else if (rhs < 0) {
2569
2570 if (!CanDeoptimize()) {
2571
2572
2573 break;
2574 }
2576 DeoptimizeInstr* deopt =
2577 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId());
2579
2580 return flow_graph->TryCreateConstantReplacementFor(this,
2581 Object::smi_zero());
2582 }
2583 break;
2584
2585 case Token::kSHL: {
2587 if (rhs == 0) {
2591 return flow_graph->TryCreateConstantReplacementFor(this,
2592 Object::smi_zero());
2593 }
else if ((rhs < 0) || ((rhs >= result_bits) && !
is_truncating())) {
2594
2595
2596 if (!CanDeoptimize()) {
2597
2598
2599 break;
2600 }
2602 DeoptimizeInstr* deopt =
2603 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId());
2605
2606 return flow_graph->TryCreateConstantReplacementFor(this,
2607 Object::smi_zero());
2608 }
2609 break;
2610 }
2611
2612 default:
2613 break;
2614 }
2615
2616 return this;
2617}
static BinaryIntegerOpInstr * Make(Representation representation, Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
BinaryIntegerOpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id)
static constexpr intptr_t kNone
static int64_t TruncateTo(int64_t v, Representation r)
static IntegerPtr BinaryIntegerEvaluate(const Object &left, const Object &right, Token::Kind token_kind, bool is_truncating, Representation representation, Thread *thread)
static bool ToIntegerConstant(Value *value, int64_t *result)
static IntegerPtr NewCanonical(const String &str)
static RangeBoundary FromConstant(int64_t val)
static bool IsSingleton(Range *range)
static SmiPtr New(intptr_t value)
virtual bool MayThrow() const
static Thread * Current()
static UnaryIntegerOpInstr * Make(Representation representation, Token::Kind op_kind, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode, Range *range)
static constexpr int ShiftForPowerOfTwo(T x)
static constexpr bool IsPowerOfTwo(T x)
Definition * definition() const
static int64_t RepresentationMask(Representation r)
static intptr_t RepresentationBits(Representation r)
static bool IsCommutative(Token::Kind op)
constexpr intptr_t kBitsPerInt64