Skip to content

Commit 0c9a858

Browse files
authored
Merge pull request #22202 from JuliaLang/teh/purge_intrinsics
Replace several intrinsics with Julia equivalents
2 parents 5851a26 + d5ec1c6 commit 0c9a858

13 files changed

+36
-104
lines changed

base/fastmath.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module FastMath
2424

2525
export @fastmath
2626

27-
import Core.Intrinsics: sqrt_llvm_fast, neg_float_fast,
27+
import Core.Intrinsics: sqrt_llvm, neg_float_fast,
2828
add_float_fast, sub_float_fast, mul_float_fast, div_float_fast, rem_float_fast,
2929
eq_float_fast, ne_float_fast, lt_float_fast, le_float_fast
3030

@@ -264,9 +264,7 @@ end
264264
pow_fast(x::Float32, y::Integer) = ccall("llvm.powi.f32", llvmcall, Float32, (Float32, Int32), x, y)
265265
pow_fast(x::Float64, y::Integer) = ccall("llvm.powi.f64", llvmcall, Float64, (Float64, Int32), x, y)
266266

267-
# TODO: Change sqrt_llvm intrinsic to avoid nan checking; add nan
268-
# checking to sqrt in math.jl; remove sqrt_llvm_fast intrinsic
269-
sqrt_fast(x::FloatTypes) = sqrt_llvm_fast(x)
267+
sqrt_fast(x::FloatTypes) = sqrt_llvm(x)
270268

271269
# libm
272270

base/inference.jl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -449,10 +449,6 @@ add_tfunc(uitofp, 2, 2, bitcast_tfunc, 1)
449449
add_tfunc(sitofp, 2, 2, bitcast_tfunc, 1)
450450
add_tfunc(fptrunc, 2, 2, bitcast_tfunc, 1)
451451
add_tfunc(fpext, 2, 2, bitcast_tfunc, 1)
452-
## checked conversion ##
453-
add_tfunc(checked_trunc_sint, 2, 2, bitcast_tfunc, 3)
454-
add_tfunc(checked_trunc_uint, 2, 2, bitcast_tfunc, 3)
455-
add_tfunc(check_top_bit, 1, 1, math_tfunc, 2)
456452
## arithmetic ##
457453
add_tfunc(neg_int, 1, 1, math_tfunc, 1)
458454
add_tfunc(add_int, 2, 2, math_tfunc, 1)
@@ -502,7 +498,6 @@ add_tfunc(floor_llvm, 1, 1, math_tfunc, 10)
502498
add_tfunc(trunc_llvm, 1, 1, math_tfunc, 10)
503499
add_tfunc(rint_llvm, 1, 1, math_tfunc, 10)
504500
add_tfunc(sqrt_llvm, 1, 1, math_tfunc, 20)
505-
add_tfunc(sqrt_llvm_fast, 1, 1, math_tfunc, 20)
506501
## same-type comparisons ##
507502
cmp_tfunc(x::ANY, y::ANY) = Bool
508503
add_tfunc(eq_int, 2, 2, cmp_tfunc, 1)
@@ -3747,13 +3742,10 @@ function is_pure_intrinsic(f::IntrinsicFunction)
37473742
return !(f === Intrinsics.pointerref || # this one is volatile
37483743
f === Intrinsics.pointerset || # this one is never effect-free
37493744
f === Intrinsics.llvmcall || # this one is never effect-free
3750-
f === Intrinsics.checked_trunc_sint ||
3751-
f === Intrinsics.checked_trunc_uint ||
37523745
f === Intrinsics.checked_sdiv_int ||
37533746
f === Intrinsics.checked_udiv_int ||
37543747
f === Intrinsics.checked_srem_int ||
37553748
f === Intrinsics.checked_urem_int ||
3756-
f === Intrinsics.check_top_bit ||
37573749
f === Intrinsics.sqrt_llvm ||
37583750
f === Intrinsics.cglobal) # cglobal throws an error for symbol-not-found
37593751
end

base/int.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,34 @@ trailing_ones(x::Integer) = trailing_zeros(~x)
395395
>>>(x::BitInteger, y::Int) =
396396
select_value(0 <= y, x >>> unsigned(y), x << unsigned(-y))
397397

398+
function is_top_bit_set(x::BitInteger)
399+
@_inline_meta
400+
lshr_int(x, (sizeof(x) << 0x03) - 1) == rem(0x01, typeof(x))
401+
end
402+
function check_top_bit(x::BitInteger)
403+
@_inline_meta
404+
is_top_bit_set(x) && throw(InexactError())
405+
x
406+
end
407+
398408
## integer conversions ##
399409

410+
function checked_trunc_sint{To,From}(::Type{To}, x::From)
411+
@_inline_meta
412+
y = trunc_int(To, x)
413+
back = sext_int(From, y)
414+
x == back || throw(InexactError())
415+
y
416+
end
417+
418+
function checked_trunc_uint{To,From}(::Type{To}, x::From)
419+
@_inline_meta
420+
y = trunc_int(To, x)
421+
back = zext_int(From, y)
422+
x == back || throw(InexactError())
423+
y
424+
end
425+
400426
for to in BitInteger_types, from in (BitInteger_types..., Bool)
401427
if !(to === from)
402428
if to.size < from.size

base/math.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,10 @@ Compute sine and cosine of `x`, where `x` is in radians.
431431
return res
432432
end
433433

434-
sqrt(x::Float64) = sqrt_llvm(x)
435-
sqrt(x::Float32) = sqrt_llvm(x)
434+
@inline function sqrt(x::Union{Float32,Float64})
435+
x < zero(x) && throw(DomainError())
436+
sqrt_llvm(x)
437+
end
436438

437439
"""
438440
sqrt(x)

src/cgutils.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -913,13 +913,6 @@ static void raise_exception_unless(jl_codectx_t &ctx, Value *cond, Value *exc)
913913
raise_exception(ctx, exc, passBB);
914914
}
915915

916-
// DO NOT PASS IN A CONST CONDITION!
917-
static void raise_exception_if(jl_codectx_t &ctx, Value *cond, Value *exc)
918-
{
919-
raise_exception_unless(ctx, ctx.builder.CreateXor(cond, ConstantInt::get(T_int1,-1)),
920-
exc);
921-
}
922-
923916
static size_t dereferenceable_size(jl_value_t *jt) {
924917
size_t size = 0;
925918
if (jl_is_array_type(jt)) {

src/codegen.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6234,9 +6234,7 @@ static void init_julia_llvm_env(Module *m)
62346234
global_jlvalue_to_llvm("jl_emptytuple", &jl_emptytuple, m);
62356235
global_jlvalue_to_llvm("jl_diverror_exception", &jl_diverror_exception, m);
62366236
global_jlvalue_to_llvm("jl_undefref_exception", &jl_undefref_exception, m);
6237-
global_jlvalue_to_llvm("jl_domain_exception", &jl_domain_exception, m);
62386237
global_jlvalue_to_llvm("jl_overflow_exception", &jl_overflow_exception, m);
6239-
global_jlvalue_to_llvm("jl_inexact_exception", &jl_inexact_exception, m);
62406238

62416239
jlRTLD_DEFAULT_var =
62426240
new GlobalVariable(*m, T_pint8,

src/init.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,7 @@ void jl_get_builtin_hooks(void)
785785
jl_errorexception_type = (jl_datatype_t*)core("ErrorException");
786786
jl_stackovf_exception = jl_new_struct_uninit((jl_datatype_t*)core("StackOverflowError"));
787787
jl_diverror_exception = jl_new_struct_uninit((jl_datatype_t*)core("DivideError"));
788-
jl_domain_exception = jl_new_struct_uninit((jl_datatype_t*)core("DomainError"));
789788
jl_overflow_exception = jl_new_struct_uninit((jl_datatype_t*)core("OverflowError"));
790-
jl_inexact_exception = jl_new_struct_uninit((jl_datatype_t*)core("InexactError"));
791789
jl_undefref_exception = jl_new_struct_uninit((jl_datatype_t*)core("UndefRefError"));
792790
jl_undefvarerror_type = (jl_datatype_t*)core("UndefVarError");
793791
jl_interrupt_exception = jl_new_struct_uninit((jl_datatype_t*)core("InterruptException"));

src/intrinsics.cpp

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ static void jl_init_intrinsic_functions_codegen(Module *m)
7070
float_func[trunc_llvm] = true;
7171
float_func[rint_llvm] = true;
7272
float_func[sqrt_llvm] = true;
73-
float_func[sqrt_llvm_fast] = true;
7473
}
7574

7675
extern "C"
@@ -499,24 +498,6 @@ static Value *generic_trunc(jl_codectx_t &ctx, Type *to, Value *x)
499498
return ctx.builder.CreateTrunc(x, to);
500499
}
501500

502-
static Value *generic_trunc_uchecked(jl_codectx_t &ctx, Type *to, Value *x)
503-
{
504-
Value *ans = ctx.builder.CreateTrunc(x, to);
505-
Value *back = ctx.builder.CreateZExt(ans, x->getType());
506-
raise_exception_unless(ctx, ctx.builder.CreateICmpEQ(back, x),
507-
literal_pointer_val(ctx, jl_inexact_exception));
508-
return ans;
509-
}
510-
511-
static Value *generic_trunc_schecked(jl_codectx_t &ctx, Type *to, Value *x)
512-
{
513-
Value *ans = ctx.builder.CreateTrunc(x, to);
514-
Value *back = ctx.builder.CreateSExt(ans, x->getType());
515-
raise_exception_unless(ctx, ctx.builder.CreateICmpEQ(back, x),
516-
literal_pointer_val(ctx, jl_inexact_exception));
517-
return ans;
518-
}
519-
520501
static Value *generic_sext(jl_codectx_t &ctx, Type *to, Value *x)
521502
{
522503
return ctx.builder.CreateSExt(x, to);
@@ -778,10 +759,6 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
778759
return generic_bitcast(ctx, argv);
779760
case trunc_int:
780761
return generic_cast(ctx, f, generic_trunc, argv, true, true);
781-
case checked_trunc_uint:
782-
return generic_cast(ctx, f, generic_trunc_uchecked, argv, true, true);
783-
case checked_trunc_sint:
784-
return generic_cast(ctx, f, generic_trunc_schecked, argv, true, true);
785762
case sext_int:
786763
return generic_cast(ctx, f, generic_sext, argv, true, true);
787764
case zext_int:
@@ -1007,15 +984,6 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg
1007984
literal_pointer_val(ctx, jl_diverror_exception));
1008985
return ctx.builder.CreateURem(x, y);
1009986

1010-
case check_top_bit:
1011-
// raise InexactError if argument's top bit is set
1012-
raise_exception_if(ctx,
1013-
ctx.builder.CreateTrunc(
1014-
ctx.builder.CreateLShr(x, ConstantInt::get(t, t->getPrimitiveSizeInBits() - 1)),
1015-
T_int1),
1016-
literal_pointer_val(ctx, jl_inexact_exception));
1017-
return x;
1018-
1019987
case eq_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpEQ(x, y);
1020988
case ne_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpNE(x, y);
1021989
case slt_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpSLT(x, y);
@@ -1150,12 +1118,7 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg
11501118
Value *rintintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::rint, makeArrayRef(t));
11511119
return ctx.builder.CreateCall(rintintr, x);
11521120
}
1153-
case sqrt_llvm:
1154-
raise_exception_unless(ctx,
1155-
ctx.builder.CreateFCmpUGE(x, ConstantFP::get(t, 0.0)),
1156-
literal_pointer_val(ctx, jl_domain_exception));
1157-
// fall-through
1158-
case sqrt_llvm_fast: {
1121+
case sqrt_llvm: {
11591122
Value *sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
11601123
return ctx.builder.CreateCall(sqrtintr, x);
11611124
}

src/intrinsics.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@
6666
ADD_I(sitofp, 2) \
6767
ADD_I(fptrunc, 2) \
6868
ADD_I(fpext, 2) \
69-
/* checked conversion */ \
70-
ADD_I(checked_trunc_sint, 2) \
71-
ADD_I(checked_trunc_uint, 2) \
72-
ADD_I(check_top_bit, 1) \
7369
/* checked arithmetic */ \
7470
ADD_I(checked_sadd_int, 2) \
7571
ADD_I(checked_uadd_int, 2) \
@@ -91,7 +87,6 @@
9187
ADD_I(trunc_llvm, 1) \
9288
ADD_I(rint_llvm, 1) \
9389
ADD_I(sqrt_llvm, 1) \
94-
ALIAS(sqrt_llvm_fast, sqrt_llvm) \
9590
/* pointer access */ \
9691
ADD_I(pointerref, 3) \
9792
ADD_I(pointerset, 4) \

src/jltypes.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ jl_value_t *jl_segv_exception;
121121
JL_DLLEXPORT jl_value_t *jl_diverror_exception;
122122
JL_DLLEXPORT jl_value_t *jl_domain_exception;
123123
JL_DLLEXPORT jl_value_t *jl_overflow_exception;
124-
JL_DLLEXPORT jl_value_t *jl_inexact_exception;
125124
JL_DLLEXPORT jl_value_t *jl_undefref_exception;
126125
jl_value_t *jl_interrupt_exception;
127126
jl_datatype_t *jl_boundserror_type;

src/julia.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,7 @@ extern JL_DLLEXPORT jl_value_t *jl_stackovf_exception;
529529
extern JL_DLLEXPORT jl_value_t *jl_memory_exception;
530530
extern JL_DLLEXPORT jl_value_t *jl_readonlymemory_exception;
531531
extern JL_DLLEXPORT jl_value_t *jl_diverror_exception;
532-
extern JL_DLLEXPORT jl_value_t *jl_domain_exception;
533532
extern JL_DLLEXPORT jl_value_t *jl_overflow_exception;
534-
extern JL_DLLEXPORT jl_value_t *jl_inexact_exception;
535533
extern JL_DLLEXPORT jl_value_t *jl_undefref_exception;
536534
extern JL_DLLEXPORT jl_value_t *jl_interrupt_exception;
537535
extern JL_DLLEXPORT jl_datatype_t *jl_boundserror_type;

src/julia_internal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -807,10 +807,6 @@ JL_DLLEXPORT jl_value_t *jl_fptosi(jl_value_t *ty, jl_value_t *a);
807807
JL_DLLEXPORT jl_value_t *jl_fptrunc(jl_value_t *ty, jl_value_t *a);
808808
JL_DLLEXPORT jl_value_t *jl_fpext(jl_value_t *ty, jl_value_t *a);
809809

810-
JL_DLLEXPORT jl_value_t *jl_checked_trunc_sint(jl_value_t *ty, jl_value_t *a);
811-
JL_DLLEXPORT jl_value_t *jl_checked_trunc_uint(jl_value_t *ty, jl_value_t *a);
812-
813-
JL_DLLEXPORT jl_value_t *jl_check_top_bit(jl_value_t *a);
814810
JL_DLLEXPORT jl_value_t *jl_checked_sadd_int(jl_value_t *a, jl_value_t *b);
815811
JL_DLLEXPORT jl_value_t *jl_checked_uadd_int(jl_value_t *a, jl_value_t *b);
816812
JL_DLLEXPORT jl_value_t *jl_checked_ssub_int(jl_value_t *a, jl_value_t *b);

src/runtime_intrinsics.c

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -378,15 +378,13 @@ static inline jl_value_t *jl_intrinsiclambda_u1(jl_value_t *ty, void *pa, unsign
378378

379379
typedef void (*intrinsic_cvt_t)(unsigned, void*, unsigned, void*);
380380
typedef unsigned (*intrinsic_cvt_check_t)(unsigned, unsigned, void*);
381-
#define cvt_iintrinsic_checked(LLVMOP, check_op, name) \
381+
#define cvt_iintrinsic(LLVMOP, name) \
382382
JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *ty, jl_value_t *a) \
383383
{ \
384-
return jl_intrinsic_cvt(ty, a, #name, LLVMOP, check_op); \
384+
return jl_intrinsic_cvt(ty, a, #name, LLVMOP); \
385385
}
386-
#define cvt_iintrinsic(LLVMOP, name) \
387-
cvt_iintrinsic_checked(LLVMOP, NULL, name) \
388386

389-
static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const char *name, intrinsic_cvt_t op, intrinsic_cvt_check_t check_op)
387+
static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const char *name, intrinsic_cvt_t op)
390388
{
391389
jl_ptls_t ptls = jl_get_ptls_states();
392390
jl_value_t *aty = jl_typeof(a);
@@ -397,8 +395,6 @@ static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const
397395
void *pa = jl_data_ptr(a);
398396
unsigned isize = jl_datatype_size(aty);
399397
unsigned osize = jl_datatype_size(ty);
400-
if (check_op && check_op(isize, osize, pa))
401-
jl_throw(jl_inexact_exception);
402398
jl_value_t *newv = jl_gc_alloc(ptls, jl_datatype_size(ty), ty);
403399
op(aty == (jl_value_t*)jl_bool_type ? 1 : isize * host_char_bit, pa,
404400
osize * host_char_bit, jl_data_ptr(newv));
@@ -856,26 +852,6 @@ static inline int all_eq(char *p, char n, char v)
856852
return 0;
857853
return 1;
858854
}
859-
static unsigned check_trunc_sint(unsigned isize, unsigned osize, void *pa)
860-
{
861-
return !all_eq((char*)pa + osize, isize - osize, signbitbyte(pa, isize)); // TODO: assumes little-endian
862-
}
863-
cvt_iintrinsic_checked(LLVMTrunc, check_trunc_sint, checked_trunc_sint)
864-
static unsigned check_trunc_uint(unsigned isize, unsigned osize, void *pa)
865-
{
866-
return !all_eq((char*)pa + osize, isize - osize, 0); // TODO: assumes little-endian
867-
}
868-
cvt_iintrinsic_checked(LLVMTrunc, check_trunc_uint, checked_trunc_uint)
869-
870-
JL_DLLEXPORT jl_value_t *jl_check_top_bit(jl_value_t *a)
871-
{
872-
jl_value_t *ty = jl_typeof(a);
873-
if (!jl_is_primitivetype(ty))
874-
jl_error("check_top_bit: value is not a primitive type");
875-
if (signbitbyte(jl_data_ptr(a), jl_datatype_size(ty)))
876-
jl_throw(jl_inexact_exception);
877-
return a;
878-
}
879855

880856
// checked arithmetic
881857
#define check_sadd_int(a,b) \
@@ -911,8 +887,6 @@ bi_iintrinsic_fast(jl_LLVMFlipSign, flipsign, flipsign_int, )
911887
#define trunc_float(pr, a) *pr = fp_select(a, trunc)
912888
#define rint_float(pr, a) *pr = fp_select(a, rint)
913889
#define sqrt_float(pr, a) \
914-
if (a < 0) \
915-
jl_throw(jl_domain_exception); \
916890
*pr = fp_select(a, sqrt)
917891
#define copysign_float(a, b) \
918892
fp_select2(a, b, copysign)

0 commit comments

Comments
 (0)