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

Side by Side Diff: src/hydrogen-instructions.cc

Issue 5860009: Fix bugs in the range analysis for integers.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: cleanup Created 10 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 case kTagged: return "t"; 57 case kTagged: return "t";
58 case kDouble: return "d"; 58 case kDouble: return "d";
59 case kInteger32: return "i"; 59 case kInteger32: return "i";
60 default: 60 default:
61 UNREACHABLE(); 61 UNREACHABLE();
62 return NULL; 62 return NULL;
63 } 63 }
64 } 64 }
65 65
66 66
67 static int32_t AddAssertNoOverflow(int32_t a, int32_t b) { 67 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) {
68 ASSERT(static_cast<int64_t>(a + b) == (static_cast<int64_t>(a) + 68 if (result > kMaxInt) {
69 static_cast<int64_t>(b))); 69 *overflow = true;
70 return a + b; 70 return kMaxInt;
71 }
72 if (result < kMinInt) {
73 *overflow = true;
74 return kMinInt;
75 }
76 return static_cast<int32_t>(result);
71 } 77 }
72 78
73 79
74 static int32_t SubAssertNoOverflow(int32_t a, int32_t b) { 80 static int32_t AddWithoutOverflow(int32_t a, int32_t b, bool* overflow) {
75 ASSERT(static_cast<int64_t>(a - b) == (static_cast<int64_t>(a) - 81 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b);
76 static_cast<int64_t>(b))); 82 return ConvertAndSetOverflow(result, overflow);
77 return a - b;
78 } 83 }
79 84
80 85
81 static int32_t MulAssertNoOverflow(int32_t a, int32_t b) { 86 static int32_t SubWithoutOverflow(int32_t a, int32_t b, bool* overflow) {
82 ASSERT(static_cast<int64_t>(a * b) == (static_cast<int64_t>(a) * 87 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b);
83 static_cast<int64_t>(b))); 88 return ConvertAndSetOverflow(result, overflow);
84 return a * b;
85 }
86
87
88 static int32_t AddWithoutOverflow(int32_t a, int32_t b) {
89 if (b > 0) {
90 if (a <= kMaxInt - b) return AddAssertNoOverflow(a, b);
91 return kMaxInt;
92 } else {
93 if (a >= kMinInt - b) return AddAssertNoOverflow(a, b);
94 return kMinInt;
95 }
96 }
97
98
99 static int32_t SubWithoutOverflow(int32_t a, int32_t b) {
100 if (b < 0) {
101 if (a <= kMaxInt + b) return SubAssertNoOverflow(a, b);
102 return kMaxInt;
103 } else {
104 if (a >= kMinInt + b) return SubAssertNoOverflow(a, b);
105 return kMinInt;
106 }
107 } 89 }
108 90
109 91
110 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 92 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) {
111 if (b == 0 || a == 0) return 0; 93 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b);
112 if (a == 1) return b; 94 return ConvertAndSetOverflow(result, overflow);
113 if (b == 1) return a;
114
115 int sign = 1;
116 if ((a < 0 && b > 0) || (a > 0 && b < 0)) sign = -1;
117 if (a < 0) a = -a;
118 if (b < 0) b = -b;
119
120 if (kMaxInt / b > a && a != kMinInt && b != kMinInt) {
121 return MulAssertNoOverflow(a, b) * sign;
122 }
123
124 *overflow = true;
125 if (sign == 1) {
126 return kMaxInt;
127 } else {
128 return kMinInt;
129 }
130 } 95 }
131 96
132 97
133 int32_t Range::Mask() const { 98 int32_t Range::Mask() const {
134 if (lower_ == upper_) return lower_; 99 if (lower_ == upper_) return lower_;
135 if (lower_ >= 0) { 100 if (lower_ >= 0) {
136 int32_t res = 1; 101 int32_t res = 1;
137 while (res < upper_) { 102 while (res < upper_) {
138 res = (res << 1) | 1; 103 res = (res << 1) | 1;
139 } 104 }
140 return res; 105 return res;
141 } 106 }
142 return 0xffffffff; 107 return 0xffffffff;
143 } 108 }
144 109
145 110
146 void Range::Add(int32_t value) { 111 void Range::AddConstant(int32_t value) {
147 if (value == 0) return; 112 if (value == 0) return;
148 lower_ = AddWithoutOverflow(lower_, value); 113 bool may_overflow = false; // Overflow is ignored here.
149 upper_ = AddWithoutOverflow(upper_, value); 114 lower_ = AddWithoutOverflow(lower_, value, &may_overflow);
115 upper_ = AddWithoutOverflow(upper_, value, &may_overflow);
150 Verify(); 116 Verify();
151 } 117 }
152 118
153 119
154 // Returns whether the add may overflow.
155 bool Range::AddAndCheckOverflow(Range* other) { 120 bool Range::AddAndCheckOverflow(Range* other) {
156 int old_lower = lower_; 121 bool may_overflow = false;
157 int old_upper = upper_; 122 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow);
158 lower_ = AddWithoutOverflow(lower_, other->lower()); 123 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow);
159 upper_ = AddWithoutOverflow(upper_, other->upper());
160 bool r = (old_lower + other->lower() != lower_ ||
161 old_upper + other->upper() != upper_);
162 KeepOrder(); 124 KeepOrder();
163 Verify(); 125 Verify();
164 return r; 126 return may_overflow;
165 } 127 }
166 128
167 129
168 // Returns whether the sub may overflow.
169 bool Range::SubAndCheckOverflow(Range* other) { 130 bool Range::SubAndCheckOverflow(Range* other) {
170 int old_lower = lower_; 131 bool may_overflow = false;
171 int old_upper = upper_; 132 lower_ = SubWithoutOverflow(lower_, other->upper(), &may_overflow);
172 lower_ = SubWithoutOverflow(lower_, other->lower()); 133 upper_ = SubWithoutOverflow(upper_, other->lower(), &may_overflow);
173 upper_ = SubWithoutOverflow(upper_, other->upper());
174 bool r = (old_lower - other->lower() != lower_ ||
175 old_upper - other->upper() != upper_);
176 KeepOrder(); 134 KeepOrder();
177 Verify(); 135 Verify();
178 return r; 136 return may_overflow;
179 } 137 }
180 138
181 139
182 void Range::KeepOrder() { 140 void Range::KeepOrder() {
183 if (lower_ > upper_) { 141 if (lower_ > upper_) {
184 int32_t tmp = lower_; 142 int32_t tmp = lower_;
185 lower_ = upper_; 143 lower_ = upper_;
186 upper_ = tmp; 144 upper_ = tmp;
187 } 145 }
188 } 146 }
189 147
190 148
191 void Range::Verify() const { 149 void Range::Verify() const {
192 ASSERT(lower_ <= upper_); 150 ASSERT(lower_ <= upper_);
193 } 151 }
194 152
195 153
196 // Returns whether the mul may overflow.
197 bool Range::MulAndCheckOverflow(Range* other) { 154 bool Range::MulAndCheckOverflow(Range* other) {
198 bool may_overflow = false; 155 bool may_overflow = false;
199 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); 156 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow);
200 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); 157 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow);
201 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); 158 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow);
202 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); 159 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow);
203 lower_ = Min(Min(v1, v2), Min(v3, v4)); 160 lower_ = Min(Min(v1, v2), Min(v3, v4));
204 upper_ = Max(Max(v1, v2), Max(v3, v4)); 161 upper_ = Max(Max(v1, v2), Max(v3, v4));
205 Verify(); 162 Verify();
206 return may_overflow; 163 return may_overflow;
(...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 1430
1474 1431
1475 void HCheckPrototypeMaps::Verify() const { 1432 void HCheckPrototypeMaps::Verify() const {
1476 HInstruction::Verify(); 1433 HInstruction::Verify();
1477 ASSERT(HasNoUses()); 1434 ASSERT(HasNoUses());
1478 } 1435 }
1479 1436
1480 #endif 1437 #endif
1481 1438
1482 } } // namespace v8::internal 1439 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698