Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/compiler/operation-typer.cc

Issue 2320753002: [turbofan] increased precision of range types for bitshifts (Closed)
Patch Set: addressed comment Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/operation-typer.h" 5 #include "src/compiler/operation-typer.h"
6 6
7 #include "src/compiler/common-operator.h" 7 #include "src/compiler/common-operator.h"
8 #include "src/compiler/type-cache.h" 8 #include "src/compiler/type-cache.h"
9 #include "src/compiler/types.h" 9 #include "src/compiler/types.h"
10 #include "src/factory.h" 10 #include "src/factory.h"
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // TODO(jarin) Use a range here. 789 // TODO(jarin) Use a range here.
790 return Type::Negative32(); 790 return Type::Negative32();
791 } 791 }
792 return Type::Signed32(); 792 return Type::Signed32();
793 } 793 }
794 794
795 Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) { 795 Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) {
796 DCHECK(lhs->Is(Type::Number())); 796 DCHECK(lhs->Is(Type::Number()));
797 DCHECK(rhs->Is(Type::Number())); 797 DCHECK(rhs->Is(Type::Number()));
798 798
799 // TODO(turbofan): Infer a better type here. 799 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
800 return Type::Signed32(); 800
801 lhs = NumberToInt32(lhs);
802 rhs = NumberToUint32(rhs);
803
804 int32_t min_lhs = lhs->Min();
805 int32_t max_lhs = lhs->Max();
806 uint32_t min_rhs = rhs->Min();
807 uint32_t max_rhs = rhs->Max();
808 if (max_rhs > 31) {
809 // rhs can be larger than the bitmask
810 max_rhs = 31;
811 min_rhs = 0;
812 }
813
814 if (max_lhs > (kMaxInt >> max_rhs) || min_lhs < (kMinInt >> max_rhs)) {
815 // overflow possible
816 return Type::Signed32();
817 }
818
819 double min =
820 std::min(static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << min_rhs),
821 static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << max_rhs));
822 double max =
823 std::max(static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << min_rhs),
824 static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << max_rhs));
825
826 if (max == kMaxInt && min == kMinInt) return Type::Signed32();
827 return Type::Range(min, max, zone());
801 } 828 }
802 829
803 Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) { 830 Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) {
804 DCHECK(lhs->Is(Type::Number())); 831 DCHECK(lhs->Is(Type::Number()));
805 DCHECK(rhs->Is(Type::Number())); 832 DCHECK(rhs->Is(Type::Number()));
806 833
807 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); 834 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
808 835
809 lhs = NumberToInt32(lhs); 836 lhs = NumberToInt32(lhs);
810 rhs = NumberToUint32(rhs); 837 rhs = NumberToUint32(rhs);
811 838
812 double min = kMinInt; 839 int32_t min_lhs = lhs->Min();
813 double max = kMaxInt; 840 int32_t max_lhs = lhs->Max();
814 if (lhs->Min() >= 0) { 841 uint32_t min_rhs = rhs->Min();
815 // Right-shifting a non-negative value cannot make it negative, nor larger. 842 uint32_t max_rhs = rhs->Max();
816 min = std::max(min, 0.0); 843 if (max_rhs > 31) {
817 max = std::min(max, lhs->Max()); 844 // rhs can be larger than the bitmask
818 if (rhs->Min() > 0 && rhs->Max() <= 31) { 845 max_rhs = 31;
819 max = static_cast<int>(max) >> static_cast<int>(rhs->Min()); 846 min_rhs = 0;
820 }
821 } 847 }
822 if (lhs->Max() < 0) { 848 double min = std::min(min_lhs >> min_rhs, min_lhs >> max_rhs);
823 // Right-shifting a negative value cannot make it non-negative, nor smaller. 849 double max = std::max(max_lhs >> min_rhs, max_lhs >> max_rhs);
824 min = std::max(min, lhs->Min()); 850
825 max = std::min(max, -1.0);
826 if (rhs->Min() > 0 && rhs->Max() <= 31) {
827 min = static_cast<int>(min) >> static_cast<int>(rhs->Min());
828 }
829 }
830 if (rhs->Min() > 0 && rhs->Max() <= 31) {
831 // Right-shifting by a positive value yields a small integer value.
832 double shift_min = kMinInt >> static_cast<int>(rhs->Min());
833 double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
834 min = std::max(min, shift_min);
835 max = std::min(max, shift_max);
836 }
837 // TODO(jarin) Ideally, the following micro-optimization should be performed
838 // by the type constructor.
839 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); 851 if (max == kMaxInt && min == kMinInt) return Type::Signed32();
840 return Type::Range(min, max, zone()); 852 return Type::Range(min, max, zone());
841 } 853 }
842 854
843 Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) { 855 Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) {
844 DCHECK(lhs->Is(Type::Number())); 856 DCHECK(lhs->Is(Type::Number()));
845 DCHECK(rhs->Is(Type::Number())); 857 DCHECK(rhs->Is(Type::Number()));
846 858
847 if (!lhs->IsInhabited()) return Type::None(); 859 if (!lhs->IsInhabited()) return Type::None();
848 860
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 return singleton_true(); 984 return singleton_true();
973 } 985 }
974 986
975 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { 987 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) {
976 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); 988 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone());
977 } 989 }
978 990
979 } // namespace compiler 991 } // namespace compiler
980 } // namespace internal 992 } // namespace internal
981 } // namespace v8 993 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698