Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/numba/cpython/numbers.py: 10%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

897 statements  

1import math 

2import numbers 

3 

4import numpy as np 

5import operator 

6 

7from llvmlite import ir 

8from llvmlite.ir import Constant 

9 

10from numba.core.imputils import (lower_builtin, lower_getattr, 

11 lower_getattr_generic, lower_cast, 

12 lower_constant, impl_ret_borrowed, 

13 impl_ret_untracked) 

14from numba.core import typing, types, utils, errors, cgutils, optional 

15from numba.core.extending import intrinsic, overload_method 

16from numba.cpython.unsafe.numbers import viewer 

17 

18def _int_arith_flags(rettype): 

19 """ 

20 Return the modifier flags for integer arithmetic. 

21 """ 

22 if rettype.signed: 

23 # Ignore the effects of signed overflow. This is important for 

24 # optimization of some indexing operations. For example 

25 # array[i+1] could see `i+1` trigger a signed overflow and 

26 # give a negative number. With Python's indexing, a negative 

27 # index is treated differently: its resolution has a runtime cost. 

28 # Telling LLVM to ignore signed overflows allows it to optimize 

29 # away the check for a negative `i+1` if it knows `i` is positive. 

30 return ['nsw'] 

31 else: 

32 return [] 

33 

34 

35def int_add_impl(context, builder, sig, args): 

36 [va, vb] = args 

37 [ta, tb] = sig.args 

38 a = context.cast(builder, va, ta, sig.return_type) 

39 b = context.cast(builder, vb, tb, sig.return_type) 

40 res = builder.add(a, b, flags=_int_arith_flags(sig.return_type)) 

41 return impl_ret_untracked(context, builder, sig.return_type, res) 

42 

43 

44def int_sub_impl(context, builder, sig, args): 

45 [va, vb] = args 

46 [ta, tb] = sig.args 

47 a = context.cast(builder, va, ta, sig.return_type) 

48 b = context.cast(builder, vb, tb, sig.return_type) 

49 res = builder.sub(a, b, flags=_int_arith_flags(sig.return_type)) 

50 return impl_ret_untracked(context, builder, sig.return_type, res) 

51 

52 

53def int_mul_impl(context, builder, sig, args): 

54 [va, vb] = args 

55 [ta, tb] = sig.args 

56 a = context.cast(builder, va, ta, sig.return_type) 

57 b = context.cast(builder, vb, tb, sig.return_type) 

58 res = builder.mul(a, b, flags=_int_arith_flags(sig.return_type)) 

59 return impl_ret_untracked(context, builder, sig.return_type, res) 

60 

61 

62def int_divmod_signed(context, builder, ty, x, y): 

63 """ 

64 Reference Objects/intobject.c 

65 xdivy = x / y; 

66 xmody = (long)(x - (unsigned long)xdivy * y); 

67 /* If the signs of x and y differ, and the remainder is non-0, 

68 * C89 doesn't define whether xdivy is now the floor or the 

69 * ceiling of the infinitely precise quotient. We want the floor, 

70 * and we have it iff the remainder's sign matches y's. 

71 */ 

72 if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) { 

73 xmody += y; 

74 --xdivy; 

75 assert(xmody && ((y ^ xmody) >= 0)); 

76 } 

77 *p_xdivy = xdivy; 

78 *p_xmody = xmody; 

79 """ 

80 assert x.type == y.type 

81 

82 ZERO = y.type(0) 

83 ONE = y.type(1) 

84 

85 # NOTE: On x86 at least, dividing the lowest representable integer 

86 # (e.g. 0x80000000 for int32) by -1 causes a SIFGPE (division overflow), 

87 # causing the process to crash. 

88 # We return 0, 0 instead (more or less like Numpy). 

89 

90 resdiv = cgutils.alloca_once_value(builder, ZERO) 

91 resmod = cgutils.alloca_once_value(builder, ZERO) 

92 

93 is_overflow = builder.and_( 

94 builder.icmp_signed('==', x, x.type(ty.minval)), 

95 builder.icmp_signed('==', y, y.type(-1))) 

96 

97 with builder.if_then(builder.not_(is_overflow), likely=True): 

98 # Note LLVM will optimize this to a single divmod instruction, 

99 # if available on the target CPU (e.g. x86). 

100 xdivy = builder.sdiv(x, y) 

101 xmody = builder.srem(x, y) 

102 

103 y_xor_xmody_ltz = builder.icmp_signed('<', builder.xor(y, xmody), ZERO) 

104 xmody_istrue = builder.icmp_signed('!=', xmody, ZERO) 

105 cond = builder.and_(xmody_istrue, y_xor_xmody_ltz) 

106 

107 with builder.if_else(cond) as (if_different_signs, if_same_signs): 

108 with if_same_signs: 

109 builder.store(xdivy, resdiv) 

110 builder.store(xmody, resmod) 

111 

112 with if_different_signs: 

113 builder.store(builder.sub(xdivy, ONE), resdiv) 

114 builder.store(builder.add(xmody, y), resmod) 

115 

116 return builder.load(resdiv), builder.load(resmod) 

117 

118 

119def int_divmod(context, builder, ty, x, y): 

120 """ 

121 Integer divmod(x, y). The caller must ensure that y != 0. 

122 """ 

123 if ty.signed: 

124 return int_divmod_signed(context, builder, ty, x, y) 

125 else: 

126 return builder.udiv(x, y), builder.urem(x, y) 

127 

128 

129def _int_divmod_impl(context, builder, sig, args, zerodiv_message): 

130 va, vb = args 

131 ta, tb = sig.args 

132 

133 ty = sig.return_type 

134 if isinstance(ty, types.UniTuple): 

135 ty = ty.dtype 

136 a = context.cast(builder, va, ta, ty) 

137 b = context.cast(builder, vb, tb, ty) 

138 quot = cgutils.alloca_once(builder, a.type, name="quot") 

139 rem = cgutils.alloca_once(builder, a.type, name="rem") 

140 

141 with builder.if_else(cgutils.is_scalar_zero(builder, b), likely=False 

142 ) as (if_zero, if_non_zero): 

143 with if_zero: 

144 if not context.error_model.fp_zero_division( 

145 builder, (zerodiv_message,)): 

146 # No exception raised => return 0 

147 # XXX We should also set the FPU exception status, but 

148 # there's no easy way to do that from LLVM. 

149 builder.store(b, quot) 

150 builder.store(b, rem) 

151 with if_non_zero: 

152 q, r = int_divmod(context, builder, ty, a, b) 

153 builder.store(q, quot) 

154 builder.store(r, rem) 

155 

156 return quot, rem 

157 

158 

159@lower_builtin(divmod, types.Integer, types.Integer) 

160def int_divmod_impl(context, builder, sig, args): 

161 quot, rem = _int_divmod_impl(context, builder, sig, args, 

162 "integer divmod by zero") 

163 

164 return cgutils.pack_array(builder, 

165 (builder.load(quot), builder.load(rem))) 

166 

167 

168@lower_builtin(operator.floordiv, types.Integer, types.Integer) 

169@lower_builtin(operator.ifloordiv, types.Integer, types.Integer) 

170def int_floordiv_impl(context, builder, sig, args): 

171 quot, rem = _int_divmod_impl(context, builder, sig, args, 

172 "integer division by zero") 

173 return builder.load(quot) 

174 

175 

176@lower_builtin(operator.truediv, types.Integer, types.Integer) 

177@lower_builtin(operator.itruediv, types.Integer, types.Integer) 

178def int_truediv_impl(context, builder, sig, args): 

179 [va, vb] = args 

180 [ta, tb] = sig.args 

181 a = context.cast(builder, va, ta, sig.return_type) 

182 b = context.cast(builder, vb, tb, sig.return_type) 

183 with cgutils.if_zero(builder, b): 

184 context.error_model.fp_zero_division(builder, ("division by zero",)) 

185 res = builder.fdiv(a, b) 

186 return impl_ret_untracked(context, builder, sig.return_type, res) 

187 

188 

189@lower_builtin(operator.mod, types.Integer, types.Integer) 

190@lower_builtin(operator.imod, types.Integer, types.Integer) 

191def int_rem_impl(context, builder, sig, args): 

192 quot, rem = _int_divmod_impl(context, builder, sig, args, 

193 "integer modulo by zero") 

194 return builder.load(rem) 

195 

196 

197def _get_power_zerodiv_return(context, return_type): 

198 if (isinstance(return_type, types.Integer) 

199 and not context.error_model.raise_on_fp_zero_division): 

200 # If not raising, return 0x8000... when computing 0 ** <negative number> 

201 return -1 << (return_type.bitwidth - 1) 

202 else: 

203 return False 

204 

205 

206def int_power_impl(context, builder, sig, args): 

207 """ 

208 a ^ b, where a is an integer or real, and b an integer 

209 """ 

210 is_integer = isinstance(sig.args[0], types.Integer) 

211 tp = sig.return_type 

212 zerodiv_return = _get_power_zerodiv_return(context, tp) 

213 

214 def int_power(a, b): 

215 # Ensure computations are done with a large enough width 

216 r = tp(1) 

217 a = tp(a) 

218 if b < 0: 

219 invert = True 

220 exp = -b 

221 if exp < 0: 

222 raise OverflowError 

223 if is_integer: 

224 if a == 0: 

225 if zerodiv_return: 

226 return zerodiv_return 

227 else: 

228 raise ZeroDivisionError("0 cannot be raised to a negative power") 

229 if a != 1 and a != -1: 

230 return 0 

231 else: 

232 invert = False 

233 exp = b 

234 if exp > 0x10000: 

235 # Optimization cutoff: fallback on the generic algorithm 

236 return math.pow(a, float(b)) 

237 while exp != 0: 

238 if exp & 1: 

239 r *= a 

240 exp >>= 1 

241 a *= a 

242 

243 return 1.0 / r if invert else r 

244 

245 res = context.compile_internal(builder, int_power, sig, args) 

246 return impl_ret_untracked(context, builder, sig.return_type, res) 

247 

248 

249@lower_builtin(operator.pow, types.Integer, types.IntegerLiteral) 

250@lower_builtin(operator.ipow, types.Integer, types.IntegerLiteral) 

251@lower_builtin(operator.pow, types.Float, types.IntegerLiteral) 

252@lower_builtin(operator.ipow, types.Float, types.IntegerLiteral) 

253def static_power_impl(context, builder, sig, args): 

254 """ 

255 a ^ b, where a is an integer or real, and b a constant integer 

256 """ 

257 exp = sig.args[1].value 

258 if not isinstance(exp, numbers.Integral): 

259 raise NotImplementedError 

260 if abs(exp) > 0x10000: 

261 # Optimization cutoff: fallback on the generic algorithm above 

262 raise NotImplementedError 

263 invert = exp < 0 

264 exp = abs(exp) 

265 

266 tp = sig.return_type 

267 is_integer = isinstance(tp, types.Integer) 

268 zerodiv_return = _get_power_zerodiv_return(context, tp) 

269 

270 val = context.cast(builder, args[0], sig.args[0], tp) 

271 lty = val.type 

272 

273 def mul(a, b): 

274 if is_integer: 

275 return builder.mul(a, b) 

276 else: 

277 return builder.fmul(a, b) 

278 

279 # Unroll the exponentiation loop 

280 res = lty(1) 

281 a = val 

282 while exp != 0: 

283 if exp & 1: 

284 res = mul(res, val) 

285 exp >>= 1 

286 val = mul(val, val) 

287 

288 if invert: 

289 # If the exponent was negative, fix the result by inverting it 

290 if is_integer: 

291 # Integer inversion 

292 def invert_impl(a): 

293 if a == 0: 

294 if zerodiv_return: 

295 return zerodiv_return 

296 else: 

297 raise ZeroDivisionError("0 cannot be raised to a negative power") 

298 if a != 1 and a != -1: 

299 return 0 

300 else: 

301 return a 

302 

303 else: 

304 # Real inversion 

305 def invert_impl(a): 

306 return 1.0 / a 

307 

308 res = context.compile_internal(builder, invert_impl, 

309 typing.signature(tp, tp), (res,)) 

310 

311 return res 

312 

313 

314def int_slt_impl(context, builder, sig, args): 

315 res = builder.icmp_signed('<', *args) 

316 return impl_ret_untracked(context, builder, sig.return_type, res) 

317 

318 

319def int_sle_impl(context, builder, sig, args): 

320 res = builder.icmp_signed('<=', *args) 

321 return impl_ret_untracked(context, builder, sig.return_type, res) 

322 

323 

324def int_sgt_impl(context, builder, sig, args): 

325 res = builder.icmp_signed('>', *args) 

326 return impl_ret_untracked(context, builder, sig.return_type, res) 

327 

328 

329def int_sge_impl(context, builder, sig, args): 

330 res = builder.icmp_signed('>=', *args) 

331 return impl_ret_untracked(context, builder, sig.return_type, res) 

332 

333 

334def int_ult_impl(context, builder, sig, args): 

335 res = builder.icmp_unsigned('<', *args) 

336 return impl_ret_untracked(context, builder, sig.return_type, res) 

337 

338 

339def int_ule_impl(context, builder, sig, args): 

340 res = builder.icmp_unsigned('<=', *args) 

341 return impl_ret_untracked(context, builder, sig.return_type, res) 

342 

343 

344def int_ugt_impl(context, builder, sig, args): 

345 res = builder.icmp_unsigned('>', *args) 

346 return impl_ret_untracked(context, builder, sig.return_type, res) 

347 

348 

349def int_uge_impl(context, builder, sig, args): 

350 res = builder.icmp_unsigned('>=', *args) 

351 return impl_ret_untracked(context, builder, sig.return_type, res) 

352 

353 

354def int_eq_impl(context, builder, sig, args): 

355 res = builder.icmp_unsigned('==', *args) 

356 return impl_ret_untracked(context, builder, sig.return_type, res) 

357 

358 

359def int_ne_impl(context, builder, sig, args): 

360 res = builder.icmp_unsigned('!=', *args) 

361 return impl_ret_untracked(context, builder, sig.return_type, res) 

362 

363 

364def int_signed_unsigned_cmp(op): 

365 def impl(context, builder, sig, args): 

366 (left, right) = args 

367 # This code is translated from the NumPy source. 

368 # What we're going to do is divide the range of a signed value at zero. 

369 # If the signed value is less than zero, then we can treat zero as the 

370 # unsigned value since the unsigned value is necessarily zero or larger 

371 # and any signed comparison between a negative value and zero/infinity 

372 # will yield the same result. If the signed value is greater than or 

373 # equal to zero, then we can safely cast it to an unsigned value and do 

374 # the expected unsigned-unsigned comparison operation. 

375 # Original: https://github.com/numpy/numpy/pull/23713 

376 cmp_zero = builder.icmp_signed('<', left, Constant(left.type, 0)) 

377 lt_zero = builder.icmp_signed(op, left, Constant(left.type, 0)) 

378 ge_zero = builder.icmp_unsigned(op, left, right) 

379 res = builder.select(cmp_zero, lt_zero, ge_zero) 

380 return impl_ret_untracked(context, builder, sig.return_type, res) 

381 return impl 

382 

383 

384def int_unsigned_signed_cmp(op): 

385 def impl(context, builder, sig, args): 

386 (left, right) = args 

387 # See the function `int_signed_unsigned_cmp` for implementation notes. 

388 cmp_zero = builder.icmp_signed('<', right, Constant(right.type, 0)) 

389 lt_zero = builder.icmp_signed(op, Constant(right.type, 0), right) 

390 ge_zero = builder.icmp_unsigned(op, left, right) 

391 res = builder.select(cmp_zero, lt_zero, ge_zero) 

392 return impl_ret_untracked(context, builder, sig.return_type, res) 

393 return impl 

394 

395 

396def int_abs_impl(context, builder, sig, args): 

397 [x] = args 

398 ZERO = Constant(x.type, None) 

399 ltz = builder.icmp_signed('<', x, ZERO) 

400 negated = builder.neg(x) 

401 res = builder.select(ltz, negated, x) 

402 return impl_ret_untracked(context, builder, sig.return_type, res) 

403 

404 

405def uint_abs_impl(context, builder, sig, args): 

406 [x] = args 

407 return impl_ret_untracked(context, builder, sig.return_type, x) 

408 

409 

410def int_shl_impl(context, builder, sig, args): 

411 [valty, amtty] = sig.args 

412 [val, amt] = args 

413 val = context.cast(builder, val, valty, sig.return_type) 

414 amt = context.cast(builder, amt, amtty, sig.return_type) 

415 res = builder.shl(val, amt) 

416 return impl_ret_untracked(context, builder, sig.return_type, res) 

417 

418 

419def int_shr_impl(context, builder, sig, args): 

420 [valty, amtty] = sig.args 

421 [val, amt] = args 

422 val = context.cast(builder, val, valty, sig.return_type) 

423 amt = context.cast(builder, amt, amtty, sig.return_type) 

424 if sig.return_type.signed: 

425 res = builder.ashr(val, amt) 

426 else: 

427 res = builder.lshr(val, amt) 

428 return impl_ret_untracked(context, builder, sig.return_type, res) 

429 

430 

431def int_and_impl(context, builder, sig, args): 

432 [at, bt] = sig.args 

433 [av, bv] = args 

434 cav = context.cast(builder, av, at, sig.return_type) 

435 cbc = context.cast(builder, bv, bt, sig.return_type) 

436 res = builder.and_(cav, cbc) 

437 return impl_ret_untracked(context, builder, sig.return_type, res) 

438 

439 

440def int_or_impl(context, builder, sig, args): 

441 [at, bt] = sig.args 

442 [av, bv] = args 

443 cav = context.cast(builder, av, at, sig.return_type) 

444 cbc = context.cast(builder, bv, bt, sig.return_type) 

445 res = builder.or_(cav, cbc) 

446 return impl_ret_untracked(context, builder, sig.return_type, res) 

447 

448 

449def int_xor_impl(context, builder, sig, args): 

450 [at, bt] = sig.args 

451 [av, bv] = args 

452 cav = context.cast(builder, av, at, sig.return_type) 

453 cbc = context.cast(builder, bv, bt, sig.return_type) 

454 res = builder.xor(cav, cbc) 

455 return impl_ret_untracked(context, builder, sig.return_type, res) 

456 

457 

458def int_negate_impl(context, builder, sig, args): 

459 [typ] = sig.args 

460 [val] = args 

461 # Negate before upcasting, for unsigned numbers 

462 res = builder.neg(val) 

463 res = context.cast(builder, res, typ, sig.return_type) 

464 return impl_ret_untracked(context, builder, sig.return_type, res) 

465 

466 

467def int_positive_impl(context, builder, sig, args): 

468 [typ] = sig.args 

469 [val] = args 

470 res = context.cast(builder, val, typ, sig.return_type) 

471 return impl_ret_untracked(context, builder, sig.return_type, res) 

472 

473 

474def int_invert_impl(context, builder, sig, args): 

475 [typ] = sig.args 

476 [val] = args 

477 # Invert before upcasting, for unsigned numbers 

478 res = builder.xor(val, Constant(val.type, int('1' * val.type.width, 2))) 

479 res = context.cast(builder, res, typ, sig.return_type) 

480 return impl_ret_untracked(context, builder, sig.return_type, res) 

481 

482 

483def int_sign_impl(context, builder, sig, args): 

484 """ 

485 np.sign(int) 

486 """ 

487 [x] = args 

488 POS = Constant(x.type, 1) 

489 NEG = Constant(x.type, -1) 

490 ZERO = Constant(x.type, 0) 

491 

492 cmp_zero = builder.icmp_unsigned('==', x, ZERO) 

493 cmp_pos = builder.icmp_signed('>', x, ZERO) 

494 

495 presult = cgutils.alloca_once(builder, x.type) 

496 

497 bb_zero = builder.append_basic_block(".zero") 

498 bb_postest = builder.append_basic_block(".postest") 

499 bb_pos = builder.append_basic_block(".pos") 

500 bb_neg = builder.append_basic_block(".neg") 

501 bb_exit = builder.append_basic_block(".exit") 

502 

503 builder.cbranch(cmp_zero, bb_zero, bb_postest) 

504 

505 with builder.goto_block(bb_zero): 

506 builder.store(ZERO, presult) 

507 builder.branch(bb_exit) 

508 

509 with builder.goto_block(bb_postest): 

510 builder.cbranch(cmp_pos, bb_pos, bb_neg) 

511 

512 with builder.goto_block(bb_pos): 

513 builder.store(POS, presult) 

514 builder.branch(bb_exit) 

515 

516 with builder.goto_block(bb_neg): 

517 builder.store(NEG, presult) 

518 builder.branch(bb_exit) 

519 

520 builder.position_at_end(bb_exit) 

521 res = builder.load(presult) 

522 return impl_ret_untracked(context, builder, sig.return_type, res) 

523 

524 

525def bool_negate_impl(context, builder, sig, args): 

526 [typ] = sig.args 

527 [val] = args 

528 res = context.cast(builder, val, typ, sig.return_type) 

529 res = builder.neg(res) 

530 return impl_ret_untracked(context, builder, sig.return_type, res) 

531 

532 

533def bool_unary_positive_impl(context, builder, sig, args): 

534 [typ] = sig.args 

535 [val] = args 

536 res = context.cast(builder, val, typ, sig.return_type) 

537 return impl_ret_untracked(context, builder, sig.return_type, res) 

538 

539 

540lower_builtin(operator.eq, types.boolean, types.boolean)(int_eq_impl) 

541lower_builtin(operator.ne, types.boolean, types.boolean)(int_ne_impl) 

542lower_builtin(operator.lt, types.boolean, types.boolean)(int_ult_impl) 

543lower_builtin(operator.le, types.boolean, types.boolean)(int_ule_impl) 

544lower_builtin(operator.gt, types.boolean, types.boolean)(int_ugt_impl) 

545lower_builtin(operator.ge, types.boolean, types.boolean)(int_uge_impl) 

546lower_builtin(operator.neg, types.boolean)(bool_negate_impl) 

547lower_builtin(operator.pos, types.boolean)(bool_unary_positive_impl) 

548 

549 

550def _implement_integer_operators(): 

551 ty = types.Integer 

552 

553 lower_builtin(operator.add, ty, ty)(int_add_impl) 

554 lower_builtin(operator.iadd, ty, ty)(int_add_impl) 

555 lower_builtin(operator.sub, ty, ty)(int_sub_impl) 

556 lower_builtin(operator.isub, ty, ty)(int_sub_impl) 

557 lower_builtin(operator.mul, ty, ty)(int_mul_impl) 

558 lower_builtin(operator.imul, ty, ty)(int_mul_impl) 

559 lower_builtin(operator.eq, ty, ty)(int_eq_impl) 

560 lower_builtin(operator.ne, ty, ty)(int_ne_impl) 

561 

562 lower_builtin(operator.lshift, ty, ty)(int_shl_impl) 

563 lower_builtin(operator.ilshift, ty, ty)(int_shl_impl) 

564 lower_builtin(operator.rshift, ty, ty)(int_shr_impl) 

565 lower_builtin(operator.irshift, ty, ty)(int_shr_impl) 

566 

567 lower_builtin(operator.neg, ty)(int_negate_impl) 

568 lower_builtin(operator.pos, ty)(int_positive_impl) 

569 

570 lower_builtin(operator.pow, ty, ty)(int_power_impl) 

571 lower_builtin(operator.ipow, ty, ty)(int_power_impl) 

572 lower_builtin(pow, ty, ty)(int_power_impl) 

573 

574 for ty in types.unsigned_domain: 

575 lower_builtin(operator.lt, ty, ty)(int_ult_impl) 

576 lower_builtin(operator.le, ty, ty)(int_ule_impl) 

577 lower_builtin(operator.gt, ty, ty)(int_ugt_impl) 

578 lower_builtin(operator.ge, ty, ty)(int_uge_impl) 

579 lower_builtin(operator.pow, types.Float, ty)(int_power_impl) 

580 lower_builtin(operator.ipow, types.Float, ty)(int_power_impl) 

581 lower_builtin(pow, types.Float, ty)(int_power_impl) 

582 lower_builtin(abs, ty)(uint_abs_impl) 

583 

584 lower_builtin(operator.lt, types.IntegerLiteral, types.IntegerLiteral)(int_slt_impl) 

585 lower_builtin(operator.gt, types.IntegerLiteral, types.IntegerLiteral)(int_slt_impl) 

586 lower_builtin(operator.le, types.IntegerLiteral, types.IntegerLiteral)(int_slt_impl) 

587 lower_builtin(operator.ge, types.IntegerLiteral, types.IntegerLiteral)(int_slt_impl) 

588 for ty in types.signed_domain: 

589 lower_builtin(operator.lt, ty, ty)(int_slt_impl) 

590 lower_builtin(operator.le, ty, ty)(int_sle_impl) 

591 lower_builtin(operator.gt, ty, ty)(int_sgt_impl) 

592 lower_builtin(operator.ge, ty, ty)(int_sge_impl) 

593 lower_builtin(operator.pow, types.Float, ty)(int_power_impl) 

594 lower_builtin(operator.ipow, types.Float, ty)(int_power_impl) 

595 lower_builtin(pow, types.Float, ty)(int_power_impl) 

596 lower_builtin(abs, ty)(int_abs_impl) 

597 

598def _implement_bitwise_operators(): 

599 for ty in (types.Boolean, types.Integer): 

600 lower_builtin(operator.and_, ty, ty)(int_and_impl) 

601 lower_builtin(operator.iand, ty, ty)(int_and_impl) 

602 lower_builtin(operator.or_, ty, ty)(int_or_impl) 

603 lower_builtin(operator.ior, ty, ty)(int_or_impl) 

604 lower_builtin(operator.xor, ty, ty)(int_xor_impl) 

605 lower_builtin(operator.ixor, ty, ty)(int_xor_impl) 

606 

607 lower_builtin(operator.invert, ty)(int_invert_impl) 

608 

609_implement_integer_operators() 

610 

611_implement_bitwise_operators() 

612 

613 

614def real_add_impl(context, builder, sig, args): 

615 res = builder.fadd(*args) 

616 return impl_ret_untracked(context, builder, sig.return_type, res) 

617 

618 

619def real_sub_impl(context, builder, sig, args): 

620 res = builder.fsub(*args) 

621 return impl_ret_untracked(context, builder, sig.return_type, res) 

622 

623 

624def real_mul_impl(context, builder, sig, args): 

625 res = builder.fmul(*args) 

626 return impl_ret_untracked(context, builder, sig.return_type, res) 

627 

628 

629def real_div_impl(context, builder, sig, args): 

630 with cgutils.if_zero(builder, args[1]): 

631 context.error_model.fp_zero_division(builder, ("division by zero",)) 

632 res = builder.fdiv(*args) 

633 return impl_ret_untracked(context, builder, sig.return_type, res) 

634 

635 

636def real_divmod(context, builder, x, y): 

637 assert x.type == y.type 

638 floatty = x.type 

639 

640 module = builder.module 

641 fname = context.mangler(".numba.python.rem", [x.type]) 

642 fnty = ir.FunctionType(floatty, (floatty, floatty, ir.PointerType(floatty))) 

643 fn = cgutils.get_or_insert_function(module, fnty, fname) 

644 

645 if fn.is_declaration: 

646 fn.linkage = 'linkonce_odr' 

647 fnbuilder = ir.IRBuilder(fn.append_basic_block('entry')) 

648 fx, fy, pmod = fn.args 

649 div, mod = real_divmod_func_body(context, fnbuilder, fx, fy) 

650 fnbuilder.store(mod, pmod) 

651 fnbuilder.ret(div) 

652 

653 pmod = cgutils.alloca_once(builder, floatty) 

654 quotient = builder.call(fn, (x, y, pmod)) 

655 return quotient, builder.load(pmod) 

656 

657 

658def real_divmod_func_body(context, builder, vx, wx): 

659 # Reference Objects/floatobject.c 

660 # 

661 # float_divmod(PyObject *v, PyObject *w) 

662 # { 

663 # double vx, wx; 

664 # double div, mod, floordiv; 

665 # CONVERT_TO_DOUBLE(v, vx); 

666 # CONVERT_TO_DOUBLE(w, wx); 

667 # mod = fmod(vx, wx); 

668 # /* fmod is typically exact, so vx-mod is *mathematically* an 

669 # exact multiple of wx. But this is fp arithmetic, and fp 

670 # vx - mod is an approximation; the result is that div may 

671 # not be an exact integral value after the division, although 

672 # it will always be very close to one. 

673 # */ 

674 # div = (vx - mod) / wx; 

675 # if (mod) { 

676 # /* ensure the remainder has the same sign as the denominator */ 

677 # if ((wx < 0) != (mod < 0)) { 

678 # mod += wx; 

679 # div -= 1.0; 

680 # } 

681 # } 

682 # else { 

683 # /* the remainder is zero, and in the presence of signed zeroes 

684 # fmod returns different results across platforms; ensure 

685 # it has the same sign as the denominator; we'd like to do 

686 # "mod = wx * 0.0", but that may get optimized away */ 

687 # mod *= mod; /* hide "mod = +0" from optimizer */ 

688 # if (wx < 0.0) 

689 # mod = -mod; 

690 # } 

691 # /* snap quotient to nearest integral value */ 

692 # if (div) { 

693 # floordiv = floor(div); 

694 # if (div - floordiv > 0.5) 

695 # floordiv += 1.0; 

696 # } 

697 # else { 

698 # /* div is zero - get the same sign as the true quotient */ 

699 # div *= div; /* hide "div = +0" from optimizers */ 

700 # floordiv = div * vx / wx; /* zero w/ sign of vx/wx */ 

701 # } 

702 # return Py_BuildValue("(dd)", floordiv, mod); 

703 # } 

704 pmod = cgutils.alloca_once(builder, vx.type) 

705 pdiv = cgutils.alloca_once(builder, vx.type) 

706 pfloordiv = cgutils.alloca_once(builder, vx.type) 

707 

708 mod = builder.frem(vx, wx) 

709 div = builder.fdiv(builder.fsub(vx, mod), wx) 

710 

711 builder.store(mod, pmod) 

712 builder.store(div, pdiv) 

713 

714 # Note the use of negative zero for proper negating with `ZERO - x` 

715 ZERO = vx.type(0.0) 

716 NZERO = vx.type(-0.0) 

717 ONE = vx.type(1.0) 

718 mod_istrue = builder.fcmp_unordered('!=', mod, ZERO) 

719 wx_ltz = builder.fcmp_ordered('<', wx, ZERO) 

720 mod_ltz = builder.fcmp_ordered('<', mod, ZERO) 

721 

722 with builder.if_else(mod_istrue, likely=True) as (if_nonzero_mod, if_zero_mod): 

723 with if_nonzero_mod: 

724 # `mod` is non-zero or NaN 

725 # Ensure the remainder has the same sign as the denominator 

726 wx_ltz_ne_mod_ltz = builder.icmp_unsigned('!=', wx_ltz, mod_ltz) 

727 

728 with builder.if_then(wx_ltz_ne_mod_ltz): 

729 builder.store(builder.fsub(div, ONE), pdiv) 

730 builder.store(builder.fadd(mod, wx), pmod) 

731 

732 with if_zero_mod: 

733 # `mod` is zero, select the proper sign depending on 

734 # the denominator's sign 

735 mod = builder.select(wx_ltz, NZERO, ZERO) 

736 builder.store(mod, pmod) 

737 

738 del mod, div 

739 

740 div = builder.load(pdiv) 

741 div_istrue = builder.fcmp_ordered('!=', div, ZERO) 

742 

743 with builder.if_then(div_istrue): 

744 realtypemap = {'float': types.float32, 

745 'double': types.float64} 

746 realtype = realtypemap[str(wx.type)] 

747 floorfn = context.get_function(math.floor, 

748 typing.signature(realtype, realtype)) 

749 floordiv = floorfn(builder, [div]) 

750 floordivdiff = builder.fsub(div, floordiv) 

751 floordivincr = builder.fadd(floordiv, ONE) 

752 HALF = Constant(wx.type, 0.5) 

753 pred = builder.fcmp_ordered('>', floordivdiff, HALF) 

754 floordiv = builder.select(pred, floordivincr, floordiv) 

755 builder.store(floordiv, pfloordiv) 

756 

757 with cgutils.ifnot(builder, div_istrue): 

758 div = builder.fmul(div, div) 

759 builder.store(div, pdiv) 

760 floordiv = builder.fdiv(builder.fmul(div, vx), wx) 

761 builder.store(floordiv, pfloordiv) 

762 

763 return builder.load(pfloordiv), builder.load(pmod) 

764 

765 

766@lower_builtin(divmod, types.Float, types.Float) 

767def real_divmod_impl(context, builder, sig, args, loc=None): 

768 x, y = args 

769 quot = cgutils.alloca_once(builder, x.type, name="quot") 

770 rem = cgutils.alloca_once(builder, x.type, name="rem") 

771 

772 with builder.if_else(cgutils.is_scalar_zero(builder, y), likely=False 

773 ) as (if_zero, if_non_zero): 

774 with if_zero: 

775 if not context.error_model.fp_zero_division( 

776 builder, ("modulo by zero",), loc): 

777 # No exception raised => compute the nan result, 

778 # and set the FP exception word for Numpy warnings. 

779 q = builder.fdiv(x, y) 

780 r = builder.frem(x, y) 

781 builder.store(q, quot) 

782 builder.store(r, rem) 

783 with if_non_zero: 

784 q, r = real_divmod(context, builder, x, y) 

785 builder.store(q, quot) 

786 builder.store(r, rem) 

787 

788 return cgutils.pack_array(builder, 

789 (builder.load(quot), builder.load(rem))) 

790 

791 

792def real_mod_impl(context, builder, sig, args, loc=None): 

793 x, y = args 

794 res = cgutils.alloca_once(builder, x.type) 

795 with builder.if_else(cgutils.is_scalar_zero(builder, y), likely=False 

796 ) as (if_zero, if_non_zero): 

797 with if_zero: 

798 if not context.error_model.fp_zero_division( 

799 builder, ("modulo by zero",), loc): 

800 # No exception raised => compute the nan result, 

801 # and set the FP exception word for Numpy warnings. 

802 rem = builder.frem(x, y) 

803 builder.store(rem, res) 

804 with if_non_zero: 

805 _, rem = real_divmod(context, builder, x, y) 

806 builder.store(rem, res) 

807 return impl_ret_untracked(context, builder, sig.return_type, 

808 builder.load(res)) 

809 

810 

811def real_floordiv_impl(context, builder, sig, args, loc=None): 

812 x, y = args 

813 res = cgutils.alloca_once(builder, x.type) 

814 with builder.if_else(cgutils.is_scalar_zero(builder, y), likely=False 

815 ) as (if_zero, if_non_zero): 

816 with if_zero: 

817 if not context.error_model.fp_zero_division( 

818 builder, ("division by zero",), loc): 

819 # No exception raised => compute the +/-inf or nan result, 

820 # and set the FP exception word for Numpy warnings. 

821 quot = builder.fdiv(x, y) 

822 builder.store(quot, res) 

823 with if_non_zero: 

824 quot, _ = real_divmod(context, builder, x, y) 

825 builder.store(quot, res) 

826 return impl_ret_untracked(context, builder, sig.return_type, 

827 builder.load(res)) 

828 

829 

830def real_power_impl(context, builder, sig, args): 

831 x, y = args 

832 module = builder.module 

833 if context.implement_powi_as_math_call: 

834 imp = context.get_function(math.pow, sig) 

835 res = imp(builder, args) 

836 else: 

837 fn = module.declare_intrinsic('llvm.pow', [y.type]) 

838 res = builder.call(fn, (x, y)) 

839 return impl_ret_untracked(context, builder, sig.return_type, res) 

840 

841 

842def real_lt_impl(context, builder, sig, args): 

843 res = builder.fcmp_ordered('<', *args) 

844 return impl_ret_untracked(context, builder, sig.return_type, res) 

845 

846 

847def real_le_impl(context, builder, sig, args): 

848 res = builder.fcmp_ordered('<=', *args) 

849 return impl_ret_untracked(context, builder, sig.return_type, res) 

850 

851 

852def real_gt_impl(context, builder, sig, args): 

853 res = builder.fcmp_ordered('>', *args) 

854 return impl_ret_untracked(context, builder, sig.return_type, res) 

855 

856 

857def real_ge_impl(context, builder, sig, args): 

858 res = builder.fcmp_ordered('>=', *args) 

859 return impl_ret_untracked(context, builder, sig.return_type, res) 

860 

861 

862def real_eq_impl(context, builder, sig, args): 

863 res = builder.fcmp_ordered('==', *args) 

864 return impl_ret_untracked(context, builder, sig.return_type, res) 

865 

866 

867def real_ne_impl(context, builder, sig, args): 

868 res = builder.fcmp_unordered('!=', *args) 

869 return impl_ret_untracked(context, builder, sig.return_type, res) 

870 

871 

872def real_abs_impl(context, builder, sig, args): 

873 [ty] = sig.args 

874 sig = typing.signature(ty, ty) 

875 impl = context.get_function(math.fabs, sig) 

876 return impl(builder, args) 

877 

878 

879def real_negate_impl(context, builder, sig, args): 

880 from numba.cpython import mathimpl 

881 res = mathimpl.negate_real(builder, args[0]) 

882 return impl_ret_untracked(context, builder, sig.return_type, res) 

883 

884 

885def real_positive_impl(context, builder, sig, args): 

886 [typ] = sig.args 

887 [val] = args 

888 res = context.cast(builder, val, typ, sig.return_type) 

889 return impl_ret_untracked(context, builder, sig.return_type, res) 

890 

891 

892def real_sign_impl(context, builder, sig, args): 

893 """ 

894 np.sign(float) 

895 """ 

896 [x] = args 

897 POS = Constant(x.type, 1) 

898 NEG = Constant(x.type, -1) 

899 ZERO = Constant(x.type, 0) 

900 

901 presult = cgutils.alloca_once(builder, x.type) 

902 

903 is_pos = builder.fcmp_ordered('>', x, ZERO) 

904 is_neg = builder.fcmp_ordered('<', x, ZERO) 

905 

906 with builder.if_else(is_pos) as (gt_zero, not_gt_zero): 

907 with gt_zero: 

908 builder.store(POS, presult) 

909 with not_gt_zero: 

910 with builder.if_else(is_neg) as (lt_zero, not_lt_zero): 

911 with lt_zero: 

912 builder.store(NEG, presult) 

913 with not_lt_zero: 

914 # For both NaN and 0, the result of sign() is simply 

915 # the input value. 

916 builder.store(x, presult) 

917 

918 res = builder.load(presult) 

919 return impl_ret_untracked(context, builder, sig.return_type, res) 

920 

921 

922ty = types.Float 

923 

924lower_builtin(operator.add, ty, ty)(real_add_impl) 

925lower_builtin(operator.iadd, ty, ty)(real_add_impl) 

926lower_builtin(operator.sub, ty, ty)(real_sub_impl) 

927lower_builtin(operator.isub, ty, ty)(real_sub_impl) 

928lower_builtin(operator.mul, ty, ty)(real_mul_impl) 

929lower_builtin(operator.imul, ty, ty)(real_mul_impl) 

930lower_builtin(operator.floordiv, ty, ty)(real_floordiv_impl) 

931lower_builtin(operator.ifloordiv, ty, ty)(real_floordiv_impl) 

932lower_builtin(operator.truediv, ty, ty)(real_div_impl) 

933lower_builtin(operator.itruediv, ty, ty)(real_div_impl) 

934lower_builtin(operator.mod, ty, ty)(real_mod_impl) 

935lower_builtin(operator.imod, ty, ty)(real_mod_impl) 

936lower_builtin(operator.pow, ty, ty)(real_power_impl) 

937lower_builtin(operator.ipow, ty, ty)(real_power_impl) 

938lower_builtin(pow, ty, ty)(real_power_impl) 

939 

940lower_builtin(operator.eq, ty, ty)(real_eq_impl) 

941lower_builtin(operator.ne, ty, ty)(real_ne_impl) 

942lower_builtin(operator.lt, ty, ty)(real_lt_impl) 

943lower_builtin(operator.le, ty, ty)(real_le_impl) 

944lower_builtin(operator.gt, ty, ty)(real_gt_impl) 

945lower_builtin(operator.ge, ty, ty)(real_ge_impl) 

946 

947lower_builtin(abs, ty)(real_abs_impl) 

948 

949lower_builtin(operator.neg, ty)(real_negate_impl) 

950lower_builtin(operator.pos, ty)(real_positive_impl) 

951 

952del ty 

953 

954 

955@lower_getattr(types.Complex, "real") 

956def complex_real_impl(context, builder, typ, value): 

957 cplx = context.make_complex(builder, typ, value=value) 

958 res = cplx.real 

959 return impl_ret_untracked(context, builder, typ, res) 

960 

961@lower_getattr(types.Complex, "imag") 

962def complex_imag_impl(context, builder, typ, value): 

963 cplx = context.make_complex(builder, typ, value=value) 

964 res = cplx.imag 

965 return impl_ret_untracked(context, builder, typ, res) 

966 

967@lower_builtin("complex.conjugate", types.Complex) 

968def complex_conjugate_impl(context, builder, sig, args): 

969 from numba.cpython import mathimpl 

970 z = context.make_complex(builder, sig.args[0], args[0]) 

971 z.imag = mathimpl.negate_real(builder, z.imag) 

972 res = z._getvalue() 

973 return impl_ret_untracked(context, builder, sig.return_type, res) 

974 

975def real_real_impl(context, builder, typ, value): 

976 return impl_ret_untracked(context, builder, typ, value) 

977 

978def real_imag_impl(context, builder, typ, value): 

979 res = cgutils.get_null_value(value.type) 

980 return impl_ret_untracked(context, builder, typ, res) 

981 

982def real_conjugate_impl(context, builder, sig, args): 

983 return impl_ret_untracked(context, builder, sig.return_type, args[0]) 

984 

985for cls in (types.Float, types.Integer): 

986 lower_getattr(cls, "real")(real_real_impl) 

987 lower_getattr(cls, "imag")(real_imag_impl) 

988 lower_builtin("complex.conjugate", cls)(real_conjugate_impl) 

989 

990 

991@lower_builtin(operator.pow, types.Complex, types.Complex) 

992@lower_builtin(operator.ipow, types.Complex, types.Complex) 

993@lower_builtin(pow, types.Complex, types.Complex) 

994def complex_power_impl(context, builder, sig, args): 

995 [ca, cb] = args 

996 ty = sig.args[0] 

997 fty = ty.underlying_float 

998 a = context.make_helper(builder, ty, value=ca) 

999 b = context.make_helper(builder, ty, value=cb) 

1000 c = context.make_helper(builder, ty) 

1001 module = builder.module 

1002 pa = a._getpointer() 

1003 pb = b._getpointer() 

1004 pc = c._getpointer() 

1005 

1006 # Optimize for square because cpow loses a lot of precision 

1007 TWO = context.get_constant(fty, 2) 

1008 ZERO = context.get_constant(fty, 0) 

1009 

1010 b_real_is_two = builder.fcmp_ordered('==', b.real, TWO) 

1011 b_imag_is_zero = builder.fcmp_ordered('==', b.imag, ZERO) 

1012 b_is_two = builder.and_(b_real_is_two, b_imag_is_zero) 

1013 

1014 with builder.if_else(b_is_two) as (then, otherwise): 

1015 with then: 

1016 # Lower as multiplication 

1017 res = complex_mul_impl(context, builder, sig, (ca, ca)) 

1018 cres = context.make_helper(builder, ty, value=res) 

1019 c.real = cres.real 

1020 c.imag = cres.imag 

1021 

1022 with otherwise: 

1023 # Lower with call to external function 

1024 func_name = { 

1025 types.complex64: "numba_cpowf", 

1026 types.complex128: "numba_cpow", 

1027 }[ty] 

1028 fnty = ir.FunctionType(ir.VoidType(), [pa.type] * 3) 

1029 cpow = cgutils.get_or_insert_function(module, fnty, func_name) 

1030 builder.call(cpow, (pa, pb, pc)) 

1031 

1032 res = builder.load(pc) 

1033 return impl_ret_untracked(context, builder, sig.return_type, res) 

1034 

1035def complex_add_impl(context, builder, sig, args): 

1036 [cx, cy] = args 

1037 ty = sig.args[0] 

1038 x = context.make_complex(builder, ty, value=cx) 

1039 y = context.make_complex(builder, ty, value=cy) 

1040 z = context.make_complex(builder, ty) 

1041 a = x.real 

1042 b = x.imag 

1043 c = y.real 

1044 d = y.imag 

1045 z.real = builder.fadd(a, c) 

1046 z.imag = builder.fadd(b, d) 

1047 res = z._getvalue() 

1048 return impl_ret_untracked(context, builder, sig.return_type, res) 

1049 

1050 

1051def complex_sub_impl(context, builder, sig, args): 

1052 [cx, cy] = args 

1053 ty = sig.args[0] 

1054 x = context.make_complex(builder, ty, value=cx) 

1055 y = context.make_complex(builder, ty, value=cy) 

1056 z = context.make_complex(builder, ty) 

1057 a = x.real 

1058 b = x.imag 

1059 c = y.real 

1060 d = y.imag 

1061 z.real = builder.fsub(a, c) 

1062 z.imag = builder.fsub(b, d) 

1063 res = z._getvalue() 

1064 return impl_ret_untracked(context, builder, sig.return_type, res) 

1065 

1066 

1067def complex_mul_impl(context, builder, sig, args): 

1068 """ 

1069 (a+bi)(c+di)=(ac-bd)+i(ad+bc) 

1070 """ 

1071 [cx, cy] = args 

1072 ty = sig.args[0] 

1073 x = context.make_complex(builder, ty, value=cx) 

1074 y = context.make_complex(builder, ty, value=cy) 

1075 z = context.make_complex(builder, ty) 

1076 a = x.real 

1077 b = x.imag 

1078 c = y.real 

1079 d = y.imag 

1080 ac = builder.fmul(a, c) 

1081 bd = builder.fmul(b, d) 

1082 ad = builder.fmul(a, d) 

1083 bc = builder.fmul(b, c) 

1084 z.real = builder.fsub(ac, bd) 

1085 z.imag = builder.fadd(ad, bc) 

1086 res = z._getvalue() 

1087 return impl_ret_untracked(context, builder, sig.return_type, res) 

1088 

1089 

1090NAN = float('nan') 

1091 

1092def complex_div_impl(context, builder, sig, args): 

1093 def complex_div(a, b): 

1094 # This is CPython's algorithm (in _Py_c_quot()). 

1095 areal = a.real 

1096 aimag = a.imag 

1097 breal = b.real 

1098 bimag = b.imag 

1099 if not breal and not bimag: 

1100 raise ZeroDivisionError("complex division by zero") 

1101 if abs(breal) >= abs(bimag): 

1102 # Divide tops and bottom by b.real 

1103 if not breal: 

1104 return complex(NAN, NAN) 

1105 ratio = bimag / breal 

1106 denom = breal + bimag * ratio 

1107 return complex( 

1108 (areal + aimag * ratio) / denom, 

1109 (aimag - areal * ratio) / denom) 

1110 else: 

1111 # Divide tops and bottom by b.imag 

1112 if not bimag: 

1113 return complex(NAN, NAN) 

1114 ratio = breal / bimag 

1115 denom = breal * ratio + bimag 

1116 return complex( 

1117 (a.real * ratio + a.imag) / denom, 

1118 (a.imag * ratio - a.real) / denom) 

1119 

1120 res = context.compile_internal(builder, complex_div, sig, args) 

1121 return impl_ret_untracked(context, builder, sig.return_type, res) 

1122 

1123 

1124def complex_negate_impl(context, builder, sig, args): 

1125 from numba.cpython import mathimpl 

1126 [typ] = sig.args 

1127 [val] = args 

1128 cmplx = context.make_complex(builder, typ, value=val) 

1129 res = context.make_complex(builder, typ) 

1130 res.real = mathimpl.negate_real(builder, cmplx.real) 

1131 res.imag = mathimpl.negate_real(builder, cmplx.imag) 

1132 res = res._getvalue() 

1133 return impl_ret_untracked(context, builder, sig.return_type, res) 

1134 

1135 

1136def complex_positive_impl(context, builder, sig, args): 

1137 [val] = args 

1138 return impl_ret_untracked(context, builder, sig.return_type, val) 

1139 

1140 

1141def complex_eq_impl(context, builder, sig, args): 

1142 [cx, cy] = args 

1143 typ = sig.args[0] 

1144 x = context.make_complex(builder, typ, value=cx) 

1145 y = context.make_complex(builder, typ, value=cy) 

1146 

1147 reals_are_eq = builder.fcmp_ordered('==', x.real, y.real) 

1148 imags_are_eq = builder.fcmp_ordered('==', x.imag, y.imag) 

1149 res = builder.and_(reals_are_eq, imags_are_eq) 

1150 return impl_ret_untracked(context, builder, sig.return_type, res) 

1151 

1152 

1153def complex_ne_impl(context, builder, sig, args): 

1154 [cx, cy] = args 

1155 typ = sig.args[0] 

1156 x = context.make_complex(builder, typ, value=cx) 

1157 y = context.make_complex(builder, typ, value=cy) 

1158 

1159 reals_are_ne = builder.fcmp_unordered('!=', x.real, y.real) 

1160 imags_are_ne = builder.fcmp_unordered('!=', x.imag, y.imag) 

1161 res = builder.or_(reals_are_ne, imags_are_ne) 

1162 return impl_ret_untracked(context, builder, sig.return_type, res) 

1163 

1164 

1165def complex_abs_impl(context, builder, sig, args): 

1166 """ 

1167 abs(z) := hypot(z.real, z.imag) 

1168 """ 

1169 def complex_abs(z): 

1170 return math.hypot(z.real, z.imag) 

1171 

1172 res = context.compile_internal(builder, complex_abs, sig, args) 

1173 return impl_ret_untracked(context, builder, sig.return_type, res) 

1174 

1175 

1176ty = types.Complex 

1177 

1178lower_builtin(operator.add, ty, ty)(complex_add_impl) 

1179lower_builtin(operator.iadd, ty, ty)(complex_add_impl) 

1180lower_builtin(operator.sub, ty, ty)(complex_sub_impl) 

1181lower_builtin(operator.isub, ty, ty)(complex_sub_impl) 

1182lower_builtin(operator.mul, ty, ty)(complex_mul_impl) 

1183lower_builtin(operator.imul, ty, ty)(complex_mul_impl) 

1184lower_builtin(operator.truediv, ty, ty)(complex_div_impl) 

1185lower_builtin(operator.itruediv, ty, ty)(complex_div_impl) 

1186lower_builtin(operator.neg, ty)(complex_negate_impl) 

1187lower_builtin(operator.pos, ty)(complex_positive_impl) 

1188# Complex modulo is deprecated in python3 

1189 

1190lower_builtin(operator.eq, ty, ty)(complex_eq_impl) 

1191lower_builtin(operator.ne, ty, ty)(complex_ne_impl) 

1192 

1193lower_builtin(abs, ty)(complex_abs_impl) 

1194 

1195del ty 

1196 

1197 

1198@lower_builtin("number.item", types.Boolean) 

1199@lower_builtin("number.item", types.Number) 

1200def number_item_impl(context, builder, sig, args): 

1201 """ 

1202 The no-op .item() method on booleans and numbers. 

1203 """ 

1204 return args[0] 

1205 

1206 

1207#------------------------------------------------------------------------------ 

1208 

1209 

1210def number_not_impl(context, builder, sig, args): 

1211 [typ] = sig.args 

1212 [val] = args 

1213 istrue = context.cast(builder, val, typ, sig.return_type) 

1214 res = builder.not_(istrue) 

1215 return impl_ret_untracked(context, builder, sig.return_type, res) 

1216 

1217@lower_builtin(bool, types.Boolean) 

1218def bool_as_bool(context, builder, sig, args): 

1219 [val] = args 

1220 return val 

1221 

1222@lower_builtin(bool, types.Integer) 

1223def int_as_bool(context, builder, sig, args): 

1224 [val] = args 

1225 return builder.icmp_unsigned('!=', val, Constant(val.type, 0)) 

1226 

1227@lower_builtin(bool, types.Float) 

1228def float_as_bool(context, builder, sig, args): 

1229 [val] = args 

1230 return builder.fcmp_unordered('!=', val, Constant(val.type, 0.0)) 

1231 

1232@lower_builtin(bool, types.Complex) 

1233def complex_as_bool(context, builder, sig, args): 

1234 [typ] = sig.args 

1235 [val] = args 

1236 cmplx = context.make_complex(builder, typ, val) 

1237 real, imag = cmplx.real, cmplx.imag 

1238 zero = Constant(real.type, 0.0) 

1239 real_istrue = builder.fcmp_unordered('!=', real, zero) 

1240 imag_istrue = builder.fcmp_unordered('!=', imag, zero) 

1241 return builder.or_(real_istrue, imag_istrue) 

1242 

1243 

1244for ty in (types.Integer, types.Float, types.Complex): 

1245 lower_builtin(operator.not_, ty)(number_not_impl) 

1246 

1247lower_builtin(operator.not_, types.boolean)(number_not_impl) 

1248 

1249 

1250#------------------------------------------------------------------------------ 

1251# Hashing numbers, see hashing.py 

1252 

1253#------------------------------------------------------------------------------- 

1254# Implicit casts between numerics 

1255 

1256@lower_cast(types.IntegerLiteral, types.Integer) 

1257@lower_cast(types.IntegerLiteral, types.Float) 

1258@lower_cast(types.IntegerLiteral, types.Complex) 

1259def literal_int_to_number(context, builder, fromty, toty, val): 

1260 lit = context.get_constant_generic( 

1261 builder, 

1262 fromty.literal_type, 

1263 fromty.literal_value, 

1264 ) 

1265 return context.cast(builder, lit, fromty.literal_type, toty) 

1266 

1267 

1268@lower_cast(types.Integer, types.Integer) 

1269def integer_to_integer(context, builder, fromty, toty, val): 

1270 if toty.bitwidth == fromty.bitwidth: 

1271 # Just a change of signedness 

1272 return val 

1273 elif toty.bitwidth < fromty.bitwidth: 

1274 # Downcast 

1275 return builder.trunc(val, context.get_value_type(toty)) 

1276 elif fromty.signed: 

1277 # Signed upcast 

1278 return builder.sext(val, context.get_value_type(toty)) 

1279 else: 

1280 # Unsigned upcast 

1281 return builder.zext(val, context.get_value_type(toty)) 

1282 

1283@lower_cast(types.Integer, types.voidptr) 

1284def integer_to_voidptr(context, builder, fromty, toty, val): 

1285 return builder.inttoptr(val, context.get_value_type(toty)) 

1286 

1287@lower_cast(types.Float, types.Float) 

1288def float_to_float(context, builder, fromty, toty, val): 

1289 lty = context.get_value_type(toty) 

1290 if fromty.bitwidth < toty.bitwidth: 

1291 return builder.fpext(val, lty) 

1292 else: 

1293 return builder.fptrunc(val, lty) 

1294 

1295@lower_cast(types.Integer, types.Float) 

1296def integer_to_float(context, builder, fromty, toty, val): 

1297 lty = context.get_value_type(toty) 

1298 if fromty.signed: 

1299 return builder.sitofp(val, lty) 

1300 else: 

1301 return builder.uitofp(val, lty) 

1302 

1303@lower_cast(types.Float, types.Integer) 

1304def float_to_integer(context, builder, fromty, toty, val): 

1305 lty = context.get_value_type(toty) 

1306 if toty.signed: 

1307 return builder.fptosi(val, lty) 

1308 else: 

1309 return builder.fptoui(val, lty) 

1310 

1311@lower_cast(types.Float, types.Complex) 

1312@lower_cast(types.Integer, types.Complex) 

1313def non_complex_to_complex(context, builder, fromty, toty, val): 

1314 real = context.cast(builder, val, fromty, toty.underlying_float) 

1315 imag = context.get_constant(toty.underlying_float, 0) 

1316 

1317 cmplx = context.make_complex(builder, toty) 

1318 cmplx.real = real 

1319 cmplx.imag = imag 

1320 return cmplx._getvalue() 

1321 

1322@lower_cast(types.Complex, types.Complex) 

1323def complex_to_complex(context, builder, fromty, toty, val): 

1324 srcty = fromty.underlying_float 

1325 dstty = toty.underlying_float 

1326 

1327 src = context.make_complex(builder, fromty, value=val) 

1328 dst = context.make_complex(builder, toty) 

1329 dst.real = context.cast(builder, src.real, srcty, dstty) 

1330 dst.imag = context.cast(builder, src.imag, srcty, dstty) 

1331 return dst._getvalue() 

1332 

1333@lower_cast(types.Any, types.Boolean) 

1334def any_to_boolean(context, builder, fromty, toty, val): 

1335 return context.is_true(builder, fromty, val) 

1336 

1337@lower_cast(types.Boolean, types.Number) 

1338def boolean_to_any(context, builder, fromty, toty, val): 

1339 # Casting from boolean to anything first casts to int32 

1340 asint = builder.zext(val, ir.IntType(32)) 

1341 return context.cast(builder, asint, types.int32, toty) 

1342 

1343@lower_cast(types.IntegerLiteral, types.Boolean) 

1344@lower_cast(types.BooleanLiteral, types.Boolean) 

1345def literal_int_to_boolean(context, builder, fromty, toty, val): 

1346 lit = context.get_constant_generic( 

1347 builder, 

1348 fromty.literal_type, 

1349 fromty.literal_value, 

1350 ) 

1351 return context.is_true(builder, fromty.literal_type, lit) 

1352 

1353#------------------------------------------------------------------------------- 

1354# Constants 

1355 

1356@lower_constant(types.Complex) 

1357def constant_complex(context, builder, ty, pyval): 

1358 fty = ty.underlying_float 

1359 real = context.get_constant_generic(builder, fty, pyval.real) 

1360 imag = context.get_constant_generic(builder, fty, pyval.imag) 

1361 return Constant.literal_struct((real, imag)) 

1362 

1363@lower_constant(types.Integer) 

1364@lower_constant(types.Float) 

1365@lower_constant(types.Boolean) 

1366def constant_integer(context, builder, ty, pyval): 

1367 # See https://github.com/numba/numba/issues/6979 

1368 # llvmlite ir.IntType specialises the formatting of the constant for a 

1369 # cpython bool. A NumPy np.bool_ is not a cpython bool so force it to be one 

1370 # so that the constant renders correctly! 

1371 if isinstance(pyval, np.bool_): 

1372 pyval = bool(pyval) 

1373 lty = context.get_value_type(ty) 

1374 return lty(pyval) 

1375 

1376 

1377#------------------------------------------------------------------------------- 

1378# View 

1379 

1380def scalar_view(scalar, viewty): 

1381 """ Typing for the np scalar 'view' method. """ 

1382 if (isinstance(scalar, (types.Float, types.Integer)) 

1383 and isinstance(viewty, types.abstract.DTypeSpec)): 

1384 if scalar.bitwidth != viewty.dtype.bitwidth: 

1385 raise errors.TypingError( 

1386 "Changing the dtype of a 0d array is only supported if the " 

1387 "itemsize is unchanged") 

1388 

1389 def impl(scalar, viewty): 

1390 return viewer(scalar, viewty) 

1391 return impl 

1392 

1393 

1394overload_method(types.Float, 'view')(scalar_view) 

1395overload_method(types.Integer, 'view')(scalar_view)