@@ -119,14 +119,76 @@ private Sign certainInstructionSign(Instruction inst) {
119119 i > 0 and result = TPos ( )
120120 )
121121 or
122- not inst instanceof IntegerConstantInstruction and
123122 exists ( float f | f = inst .( FloatConstantInstruction ) .getValue ( ) .toFloat ( ) |
124123 f < 0 and result = TNeg ( ) or
125124 f = 0 and result = TZero ( ) or
126125 f > 0 and result = TPos ( )
127126 )
128127}
129128
129+ private newtype CastKind = TWiden ( ) or TSame ( ) or TNarrow ( )
130+
131+ private CastKind getCastKind ( ConvertInstruction ci ) {
132+ exists ( int fromSize , int toSize |
133+ toSize = ci .getResultSize ( ) and
134+ fromSize = ci .getOperand ( ) .getResultSize ( )
135+ |
136+ fromSize < toSize and
137+ result = TWiden ( )
138+ or
139+ fromSize = toSize and
140+ result = TSame ( )
141+ or
142+ fromSize > toSize and
143+ result = TNarrow ( )
144+ )
145+ }
146+
147+ private predicate bindBool ( boolean bool ) {
148+ bool = true or
149+ bool = false
150+ }
151+
152+ private Sign castSign ( Sign s , boolean fromSigned , boolean toSigned , CastKind ck ) {
153+ result = TZero ( ) and
154+ (
155+ bindBool ( fromSigned ) and
156+ bindBool ( toSigned ) and
157+ s = TZero ( )
158+ or
159+ bindBool ( fromSigned ) and
160+ bindBool ( toSigned ) and
161+ ck = TNarrow ( )
162+ )
163+ or
164+ result = TPos ( ) and
165+ (
166+ bindBool ( fromSigned ) and
167+ bindBool ( toSigned ) and
168+ s = TPos ( )
169+ or
170+ bindBool ( fromSigned ) and
171+ bindBool ( toSigned ) and
172+ s = TNeg ( ) and
173+ ck = TNarrow ( )
174+ or
175+ fromSigned = true and
176+ toSigned = false and
177+ s = TNeg ( )
178+ )
179+ or
180+ result = TNeg ( ) and
181+ (
182+ fromSigned = true and
183+ toSigned = true and
184+ s = TNeg ( )
185+ or
186+ fromSigned = false and
187+ toSigned = true and
188+ s = TPos ( ) and
189+ ck != TWiden ( )
190+ )
191+ }
130192
131193/** Holds if the sign of `e` is too complicated to determine. */
132194private predicate unknownSign ( Instruction i ) {
@@ -140,9 +202,6 @@ private predicate unknownSign(Instruction i) {
140202 i instanceof BuiltInInstruction
141203 or
142204 i instanceof CallInstruction
143- or
144- i instanceof ConvertInstruction and
145- i .getResultType ( ) .( IntegralType ) .isSigned ( )
146205 )
147206}
148207
@@ -154,6 +213,7 @@ private predicate lowerBound(IRGuardCondition comp, Instruction lowerbound, Inst
154213 exists ( int adjustment , Instruction compared |
155214 valueNumber ( bounded ) = valueNumber ( compared ) and
156215 bounded = pos .getAnOperand ( ) and
216+ not unknownSign ( lowerbound ) and
157217 /*
158218 * Java library uses guardControlsSsaRead here. I think that the phi node logic doesn't need to
159219 * be duplicated but the implication predicates may need to be ported
@@ -178,6 +238,8 @@ private predicate upperBound(IRGuardCondition comp, Instruction upperbound, Inst
178238 exists ( int adjustment , Instruction compared |
179239 valueNumber ( bounded ) = valueNumber ( compared ) and
180240 bounded = pos .getAnOperand ( ) and
241+ not unknownSign ( upperbound ) and
242+
181243 /*
182244 * Java library uses guardControlsSsaRead here. I think that the phi node logic doesn't need to
183245 * be duplicated but the implication predicates may need to be ported
@@ -202,6 +264,7 @@ private predicate upperBound(IRGuardCondition comp, Instruction upperbound, Inst
202264 */
203265private predicate eqBound ( IRGuardCondition guard , Instruction eqbound , Instruction bounded , Instruction pos , boolean isEq ) {
204266 exists ( Instruction compared |
267+ not unknownSign ( eqbound ) and
205268 valueNumber ( bounded ) = valueNumber ( compared ) and
206269 bounded = pos .getAnOperand ( ) and
207270 guard .ensuresEq ( compared , eqbound , 0 , pos .getBlock ( ) , isEq )
@@ -316,9 +379,29 @@ private Sign instructionSign(Instruction i) {
316379 result = certainInstructionSign ( i )
317380 or
318381 not exists ( certainInstructionSign ( i ) ) and
382+ not (
383+ result = TNeg ( ) and
384+ i .getResultType ( ) .( IntegralType ) .isUnsigned ( )
385+ ) and
319386 (
320387 unknownSign ( i )
321388 or
389+ exists ( ConvertInstruction ci , Instruction prior , boolean fromSigned , boolean toSigned |
390+ i = ci and
391+ prior = ci .getOperand ( ) and
392+ (
393+ if ci .getResultType ( ) .( IntegralType ) .isSigned ( )
394+ then toSigned = true
395+ else toSigned = false
396+ ) and
397+ (
398+ if prior .getResultType ( ) .( IntegralType ) .isSigned ( )
399+ then fromSigned = true
400+ else fromSigned = false
401+ ) and
402+ result = castSign ( operandSign ( ci , prior ) , fromSigned , toSigned , getCastKind ( ci ) )
403+ )
404+ or
322405 exists ( Instruction prior |
323406 prior = i .( CopyInstruction ) .getSourceValue ( )
324407 |
0 commit comments