@@ -1982,6 +1982,26 @@ static int64_t RepresentationMask(Representation r) {
19821982 (64 - RepresentationBits (r)));
19831983}
19841984
1985+ static int64_t TruncateTo (int64_t v, Representation r) {
1986+ switch (r) {
1987+ case kTagged : {
1988+ // Smi occupies word minus kSmiTagShift bits.
1989+ const intptr_t kTruncateBits =
1990+ (kBitsPerInt64 - kBitsPerWord ) + kSmiTagShift ;
1991+ return Utils::ShiftLeftWithTruncation (v, kTruncateBits ) >> kTruncateBits ;
1992+ }
1993+ case kUnboxedInt32 :
1994+ return Utils::ShiftLeftWithTruncation (v, kBitsPerInt32 ) >> kBitsPerInt32 ;
1995+ case kUnboxedUint32 :
1996+ return v & kMaxUint32 ;
1997+ case kUnboxedInt64 :
1998+ return v;
1999+ default :
2000+ UNREACHABLE ();
2001+ return 0 ;
2002+ }
2003+ }
2004+
19852005static bool ToIntegerConstant (Value* value, int64_t * result) {
19862006 if (!value->BindsToConstant ()) {
19872007 UnboxInstr* unbox = value->definition ()->AsUnbox ();
@@ -1993,7 +2013,7 @@ static bool ToIntegerConstant(Value* value, int64_t* result) {
19932013
19942014 case kUnboxedUint32 :
19952015 if (ToIntegerConstant (unbox->value (), result)) {
1996- *result &= RepresentationMask ( kUnboxedUint32 );
2016+ *result = TruncateTo (*result, kUnboxedUint32 );
19972017 return true ;
19982018 }
19992019 break ;
@@ -2341,8 +2361,8 @@ RawInteger* BinaryIntegerOpInstr::Evaluate(const Integer& left,
23412361
23422362 if (!result.IsNull ()) {
23432363 if (is_truncating ()) {
2344- int64_t truncated = result. AsTruncatedInt64Value ();
2345- truncated &= RepresentationMask ( representation ());
2364+ const int64_t truncated =
2365+ TruncateTo (result. AsTruncatedInt64Value (), representation ());
23462366 result = Integer::New (truncated, Heap::kOld );
23472367 ASSERT (IsRepresentable (result, representation ()));
23482368 } else if (!IsRepresentable (result, representation ())) {
@@ -2475,7 +2495,6 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
24752495 return this ;
24762496 }
24772497
2478- const int64_t range_mask = RepresentationMask (representation ());
24792498 if (is_truncating ()) {
24802499 switch (op_kind ()) {
24812500 case Token::kMUL :
@@ -2484,7 +2503,7 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
24842503 case Token::kBIT_AND :
24852504 case Token::kBIT_OR :
24862505 case Token::kBIT_XOR :
2487- rhs = (rhs & range_mask );
2506+ rhs = TruncateTo (rhs, representation () );
24882507 break ;
24892508 default :
24902509 break ;
@@ -2527,21 +2546,21 @@ Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
25272546 case Token::kBIT_AND :
25282547 if (rhs == 0 ) {
25292548 return right ()->definition ();
2530- } else if (rhs == range_mask ) {
2549+ } else if (rhs == RepresentationMask ( representation ()) ) {
25312550 return left ()->definition ();
25322551 }
25332552 break ;
25342553 case Token::kBIT_OR :
25352554 if (rhs == 0 ) {
25362555 return left ()->definition ();
2537- } else if (rhs == range_mask ) {
2556+ } else if (rhs == RepresentationMask ( representation ()) ) {
25382557 return right ()->definition ();
25392558 }
25402559 break ;
25412560 case Token::kBIT_XOR :
25422561 if (rhs == 0 ) {
25432562 return left ()->definition ();
2544- } else if (rhs == range_mask ) {
2563+ } else if (rhs == RepresentationMask ( representation ()) ) {
25452564 UnaryIntegerOpInstr* bit_not = UnaryIntegerOpInstr::Make (
25462565 representation (), Token::kBIT_NOT , left ()->CopyWithType (),
25472566 GetDeoptId (), range ());
0 commit comments