def _compare_helper(annotator, int1, int2): r = SomeBool() s_int1, s_int2 = annotator.annotation(int1), annotator.annotation(int2) if s_int1.is_immutable_constant() and s_int2.is_immutable_constant(): r.const = cmp_op.pyfunc(s_int1.const, s_int2.const) # # The rest of the code propagates nonneg information between # the two arguments. # # Doing the right thing when int1 or int2 change from signed # to unsigned (r_uint) is almost impossible. See test_intcmp_bug. # Instead, we only deduce constrains on the operands in the # case where they are both signed. In other words, if y is # nonneg then "assert x>=y" will let the annotator know that # x is nonneg too, but it will not work if y is unsigned. # if not (rarithmetic.signedtype(s_int1.knowntype) and rarithmetic.signedtype(s_int2.knowntype)): return r knowntypedata = defaultdict(dict) def tointtype(s_int0): if s_int0.knowntype is bool: return int return s_int0.knowntype if s_int1.nonneg and isinstance(int2, Variable): case = cmp_op.opname in ('lt', 'le', 'eq') add_knowntypedata( knowntypedata, case, [int2], SomeInteger(nonneg=True, knowntype=tointtype(s_int2)))
def _compare_helper(annotator, int1, int2): r = SomeBool() s_int1, s_int2 = annotator.annotation(int1), annotator.annotation(int2) if s_int1.is_immutable_constant() and s_int2.is_immutable_constant(): r.const = cmp_op.pyfunc(s_int1.const, s_int2.const) # # The rest of the code propagates nonneg information between # the two arguments. # # Doing the right thing when int1 or int2 change from signed # to unsigned (r_uint) is almost impossible. See test_intcmp_bug. # Instead, we only deduce constrains on the operands in the # case where they are both signed. In other words, if y is # nonneg then "assert x>=y" will let the annotator know that # x is nonneg too, but it will not work if y is unsigned. # if not (rarithmetic.signedtype(s_int1.knowntype) and rarithmetic.signedtype(s_int2.knowntype)): return r knowntypedata = defaultdict(dict) def tointtype(s_int0): if s_int0.knowntype is bool: return int return s_int0.knowntype if s_int1.nonneg and isinstance(int2, Variable): case = cmp_op.opname in ('lt', 'le', 'eq') add_knowntypedata(knowntypedata, case, [int2], SomeInteger(nonneg=True, knowntype=tointtype(s_int2))) if s_int2.nonneg and isinstance(int1, Variable): case = cmp_op.opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [int1], SomeInteger(nonneg=True, knowntype=tointtype(s_int1))) r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) if (isinstance(int2, Constant) and type(int2.value) is int and # filter out Symbolics int2.value == 0): if s_int1.nonneg: if cmp_op.opname == 'lt': r.const = False if cmp_op.opname == 'ge': r.const = True return r
def cast_pos(self, i, ll_t): pos = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[i]) value = read_ptr(pos, 0, ll_t) # Handle bitfields for c in unroll_letters_for_numbers: if LL_TYPEMAP[c] is ll_t and self.shape.ll_bitsizes: bitsize = self.shape.ll_bitsizes[i] numbits = NUM_BITS(bitsize) if numbits: lowbit = LOW_BIT(bitsize) bitmask = BIT_MASK(numbits, ll_t) masktype = lltype.typeOf(bitmask) value = rffi.cast(masktype, value) value >>= lowbit value &= bitmask if ll_t is lltype.Bool or signedtype(ll_t._type): sign = (value >> (numbits - 1)) & 1 if sign: value -= bitmask + 1 value = rffi.cast(ll_t, value) break return value