Skip to content

Commit

Permalink
Generialize float intrinsics
Browse files Browse the repository at this point in the history
Add support for FLoat16
  • Loading branch information
Keno committed Jun 29, 2013
1 parent d5459b0 commit ca1c1df
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 136 deletions.
4 changes: 2 additions & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ export
#fptrunc32, le_float, lefsi64, lefui64, lesif64,
#leuif64, lshr_int, lt_float, ltfsi64, ltfui64, ltsif64, ltuif64, mul_float,
#mul_int, ne_float, ne_int, neg_float, neg_int, not_int, or_int, rem_float,
#sdiv_int, shl_int, sitofp32, sitofp64, sle_int, slt_int, smod_int,
#srem_int, sub_float, sub_int, trunc_int, udiv_int, uitofp32, uitofp64,
#sdiv_int, shl_int, sitofp, sle_int, slt_int, smod_int,
#srem_int, sub_float, sub_int, trunc_int, udiv_int, uitofp,
#ule_int, ult_int, unbox, urem_int, xor_int, sext_int, zext_int


Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ export
fld,
flipsign,
float,
float16,
float32,
float64,
floor,
Expand Down
83 changes: 24 additions & 59 deletions base/float.jl
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
bitstype 16 Float16 <: FloatingPoint
## conversions to floating-point ##

convert(::Type{Float32}, x::Bool) = box(Float32,uitofp32(unbox(Bool,x)))
convert(::Type{Float32}, x::Char) = box(Float32,uitofp32(unbox(Float32,x)))
convert(::Type{Float32}, x::Int8) = box(Float32,sitofp32(unbox(Int8,x)))
convert(::Type{Float32}, x::Int16) = box(Float32,sitofp32(unbox(Int16,x)))
convert(::Type{Float32}, x::Int32) = box(Float32,sitofp32(unbox(Int32,x)))
convert(::Type{Float32}, x::Int64) = box(Float32,sitofp32(unbox(Int64,x)))
convert(::Type{Float32}, x::Int128) = float32(uint128(abs(x)))*(1-2(x<0))
convert(::Type{Float32}, x::Uint8) = box(Float32,uitofp32(unbox(Uint8,x)))
convert(::Type{Float32}, x::Uint16) = box(Float32,uitofp32(unbox(Uint16,x)))
convert(::Type{Float32}, x::Uint32) = box(Float32,uitofp32(unbox(Uint32,x)))
convert(::Type{Float32}, x::Uint64) = box(Float32,uitofp32(unbox(Uint64,x)))
convert(::Type{Float32}, x::Uint128) = float32(uint64(x)) + ldexp(float32(uint64(x>>>64)),64)
convert(::Type{Float32}, x::Float64) = box(Float32,fptrunc32(unbox(Float64,x)))

convert(::Type{Float64}, x::Bool) = box(Float64,uitofp64(unbox(Bool,x)))
convert(::Type{Float64}, x::Char) = box(Float64,uitofp64(unbox(Char,x)))
convert(::Type{Float64}, x::Int8) = box(Float64,sitofp64(unbox(Int8,x)))
convert(::Type{Float64}, x::Int16) = box(Float64,sitofp64(unbox(Int16,x)))
convert(::Type{Float64}, x::Int32) = box(Float64,sitofp64(unbox(Int32,x)))
convert(::Type{Float64}, x::Int64) = box(Float64,sitofp64(unbox(Int64,x)))
convert(::Type{Float64}, x::Int128) = float64(uint128(abs(x)))*(1-2(x<0))
convert(::Type{Float64}, x::Uint8) = box(Float64,uitofp64(unbox(Uint8,x)))
convert(::Type{Float64}, x::Uint16) = box(Float64,uitofp64(unbox(Uint16,x)))
convert(::Type{Float64}, x::Uint32) = box(Float64,uitofp64(unbox(Uint32,x)))
convert(::Type{Float64}, x::Uint64) = box(Float64,uitofp64(unbox(Uint64,x)))
convert(::Type{Float64}, x::Uint128) = float64(uint64(x)) + ldexp(float64(uint64(x>>>64)),64)

This comment has been minimized.

Copy link
@JeffBezanson

JeffBezanson Jun 29, 2013

Member

Do direct conversions from Uint128 to Float via CreateUIToFP really work in llvm?

This comment has been minimized.

Copy link
@Keno

Keno Jun 29, 2013

Author Member

Seems to work just fine:

julia> function foo(x)
              float64(uint128(x)<<64)
              end
# methods for generic function foo
foo(x) at none:2

julia> foo(12345)
2.277250555899444e23

julia> disassemble(foo,(Int64,))

define double @julia_foo626(i64) {
top:
  %1 = zext i64 %0 to i128, !dbg !3410
  %2 = shl nuw i128 %1, 64, !dbg !3410
  %3 = uitofp i128 %2 to double, !dbg !3410
  ret double %3, !dbg !3410
}
convert(::Type{Float64}, x::Float32) = box(Float64,fpext64(unbox(Float32,x)))
for t1 in (Float16,Float32,Float64)
for st in (Int8,Int16,Int32,Int64,Int128)
@eval begin
convert(::Type{$t1},x::($st)) = box($t1,sitofp(unbox($st,x),$t1))

This comment has been minimized.

Copy link
@JeffBezanson

JeffBezanson Jun 29, 2013

Member

The other intrinsics of this form use the other argument order, e.g. trunc_int(Type, val)

This comment has been minimized.

Copy link
@Keno

Keno Jun 29, 2013

Author Member

Yes, I realized. Will change.

promote_rule(::Type{$t1}, ::Type{$st} ) = $t1
end
end
for ut in (Bool,Char,Uint8,Uint16,Uint32,Uint64,Uint128)
@eval begin
convert(::Type{$t1},x::($ut)) = box($t1,uitofp(unbox($ut,x),$t1))
promote_rule(::Type{$t1}, ::Type{$ut} ) = $t1
end
end
end
convert(::Type{Float16}, x::Union(Float32,Float64)) = box(Float16,fptrunc(x,Float16))
convert(::Type{Float32}, x::Float16) = box(Float32,fpext(x,Float32))
convert(::Type{Float32}, x::Float64) = box(Float32,fptrunc(x,Float32))
convert(::Type{Float64}, x::Union(Float32,Float16)) = box(Float64,fpext(x,Float64))

convert(::Type{FloatingPoint}, x::Bool) = convert(Float32, x)
convert(::Type{FloatingPoint}, x::Char) = convert(Float32, x)
Expand All @@ -41,6 +33,7 @@ convert(::Type{FloatingPoint}, x::Uint32) = convert(Float64, x)
convert(::Type{FloatingPoint}, x::Uint64) = convert(Float64, x) # LOSSY
convert(::Type{FloatingPoint}, x::Uint128) = convert(Float64, x) # LOSSY

float16(x) = convert(Float16, x)
float32(x) = convert(Float32, x)
float64(x) = convert(Float64, x)
float(x) = convert(FloatingPoint, x)
Expand Down Expand Up @@ -83,9 +76,9 @@ iround(::Type{Int32}, x::Float32) = box(Int32,fpsiround(unbox(Float32,x)))
iround(::Type{Int32}, x::Float64) = box(Int32,trunc_int(Int32,fpsiround(unbox(Float64,x))))
iround(::Type{Uint32}, x::Float32) = box(Uint32,fpuiround(unbox(Float32,x)))
iround(::Type{Uint32}, x::Float64) = box(Uint32,trunc_int(Uint32,fpuiround(unbox(Float64,x))))
iround(::Type{Int64}, x::Float32) = box(Int64,fpsiround(fpext64(unbox(Float32,x))))
iround(::Type{Int64}, x::Float32) = box(Int64,fpsiround(float64(x)))
iround(::Type{Int64}, x::Float64) = box(Int64,fpsiround(unbox(Float64,x)))
iround(::Type{Uint64}, x::Float32) = box(Uint64,fpuiround(fpext64(unbox(Float32,x))))
iround(::Type{Uint64}, x::Float32) = box(Uint64,fpuiround(float64(x)))
iround(::Type{Uint64}, x::Float64) = box(Uint64,fpuiround(unbox(Float64,x)))

iround(::Type{Int128}, x::Float32) = convert(Int128,round(x))
Expand All @@ -99,35 +92,10 @@ floor(x::Float64) = ccall((:floor, Base.libm_name), Float64, (Float64,), x)

## floating point promotions ##

promote_rule(::Type{Float32}, ::Type{Float16}) = Float32
promote_rule(::Type{Float64}, ::Type{Float32}) = Float64

promote_rule(::Type{Float32}, ::Type{Int8} ) = Float32
promote_rule(::Type{Float32}, ::Type{Int16} ) = Float32
promote_rule(::Type{Float32}, ::Type{Int32} ) = Float32
promote_rule(::Type{Float32}, ::Type{Int64} ) = Float32
promote_rule(::Type{Float32}, ::Type{Int128}) = Float32

promote_rule(::Type{Float64}, ::Type{Int8} ) = Float64
promote_rule(::Type{Float64}, ::Type{Int16} ) = Float64
promote_rule(::Type{Float64}, ::Type{Int32} ) = Float64
promote_rule(::Type{Float64}, ::Type{Int64} ) = Float64
promote_rule(::Type{Float64}, ::Type{Int128}) = Float64

promote_rule(::Type{Float32}, ::Type{Uint8} ) = Float32
promote_rule(::Type{Float32}, ::Type{Uint16} ) = Float32
promote_rule(::Type{Float32}, ::Type{Uint32} ) = Float32
promote_rule(::Type{Float32}, ::Type{Uint64} ) = Float32
promote_rule(::Type{Float32}, ::Type{Uint128}) = Float32

promote_rule(::Type{Float64}, ::Type{Uint8} ) = Float64
promote_rule(::Type{Float64}, ::Type{Uint16} ) = Float64
promote_rule(::Type{Float64}, ::Type{Uint32} ) = Float64
promote_rule(::Type{Float64}, ::Type{Uint64} ) = Float64
promote_rule(::Type{Float64}, ::Type{Uint128}) = Float64

promote_rule(::Type{Float32}, ::Type{Char}) = Float32
promote_rule(::Type{Float64}, ::Type{Char}) = Float64

morebits(::Type{Float16}) = Float32
morebits(::Type{Float32}) = Float64

## floating point arithmetic ##
Expand Down Expand Up @@ -260,9 +228,6 @@ const NaN = box(Float64,unbox(Uint64,0x7ff8000000000000))
eps() = eps(Float64)
end

sizeof(::Type{Float32}) = 4

This comment has been minimized.

Copy link
@JeffBezanson

JeffBezanson Jun 29, 2013

Member

These are probably still necessary for performance at the moment.

sizeof(::Type{Float64}) = 8

## byte order swaps for arbitrary-endianness serialization/deserialization ##
bswap(x::Float32) = box(Float32,bswap_int(unbox(Float32,x)))
bswap(x::Float64) = box(Float64,bswap_int(unbox(Float64,x)))
5 changes: 3 additions & 2 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ else
end

write(s::IO, x::Bool) = write(s, uint8(x))
write(s::IO, x::Float32) = write(s, box(Int32,unbox(Float32,x)))
write(s::IO, x::Float64) = write(s, box(Int64,unbox(Float64,x)))
write(s::IO, x::Float16) = write(s, reinterpret(Int16,x))
write(s::IO, x::Float32) = write(s, reinterpret(Int32,x))
write(s::IO, x::Float64) = write(s, reinterpret(Int64,x))

function write(s::IO, a::AbstractArray)
nb = 0
Expand Down
25 changes: 12 additions & 13 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ static Type *julia_struct_to_llvm(jl_value_t *jt);
static Type *julia_type_to_llvm(jl_value_t *jt)
{
if (jt == (jl_value_t*)jl_bool_type) return T_int1;
if (jt == (jl_value_t*)jl_float32_type) return T_float32;
if (jt == (jl_value_t*)jl_float64_type) return T_float64;
if (jt == (jl_value_t*)jl_bottom_type) return T_void;
if (!jl_is_leaf_type(jt))
return jl_pvalue_llvmt;
Expand All @@ -79,12 +77,18 @@ static Type *julia_type_to_llvm(jl_value_t *jt)
return PointerType::get(lt, 0);
}
if (jl_is_bitstype(jt)) {
int nb = jl_datatype_size(jt)*8;
if (nb == 8) return T_int8;
if (nb == 16) return T_int16;
if (nb == 32) return T_int32;
if (nb == 64) return T_int64;
else return Type::getIntNTy(getGlobalContext(), nb);
int nb = jl_datatype_size(jt);
if(jl_is_floattype(jt)) {
if(nb == 2)
return Type::getHalfTy(jl_LLVMContext);
else if(nb == 4)
return Type::getFloatTy(jl_LLVMContext);
else if(nb == 8)
return Type::getDoubleTy(jl_LLVMContext);
else if(nb == 16)
return Type::getFP128Ty(jl_LLVMContext);
}
return Type::getIntNTy(jl_LLVMContext, nb*8);
}
if (jl_isbits(jt)) {
if (((jl_datatype_t*)jt)->size == 0) {
Expand Down Expand Up @@ -245,11 +249,6 @@ static Value *mark_julia_type(Value *v, jl_value_t *jt)
return v;
}

static Value *mark_julia_type(Value *v, jl_datatype_t *jt)
{
return mark_julia_type(v, (jl_value_t*)jt);
}

// --- generating various error checks ---

static jl_value_t *llvm_type_to_julia(Type *t, bool err=true);
Expand Down
15 changes: 9 additions & 6 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static Value *V_null;
static GlobalVariable *jltrue_var;
static GlobalVariable *jlfalse_var;
static GlobalVariable *jlnull_var;
static GlobalVariable *jlfloat32temp_var;
static GlobalVariable *jlfloattemp_var;
#ifdef JL_GC_MARKSWEEP
static GlobalVariable *jlpgcstack_var;
#endif
Expand Down Expand Up @@ -247,7 +247,7 @@ static Function *to_function(jl_lambda_info_t *li, bool cstyle)
assert(f != NULL);
nested_compile = last_n_c;
//f->dump();
//verifyFunction(*f);
verifyFunction(*f);
FPM->run(*f);
//n_compile++;
// print out the function's LLVM code
Expand Down Expand Up @@ -2953,10 +2953,13 @@ static void init_julia_llvm_env(Module *m)
(void*)&jl_inexact_exception);
jlboundserr_var = global_to_llvm("jl_bounds_exception",
(void*)&jl_bounds_exception);
jlfloat32temp_var =
new GlobalVariable(*jl_Module, T_float32,
false, GlobalVariable::PrivateLinkage,
ConstantFP::get(T_float32,0.0), "jl_float32_temp");

// Has to be big enough for the biggest LLVM-supported float type
jlfloattemp_var =
new GlobalVariable(*jl_Module, IntegerType::get(jl_LLVMContext,128),
false, GlobalVariable::PrivateLinkage,
ConstantInt::get(IntegerType::get(jl_LLVMContext,128),0),
"jl_float_temp");

std::vector<Type*> args1(0);
args1.push_back(T_pint8);
Expand Down
1 change: 1 addition & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ void jl_get_builtin_hooks(void)

jl_float32_type = (jl_datatype_t*)core("Float32");
jl_float64_type = (jl_datatype_t*)core("Float64");
jl_floatingpoint_type = (jl_datatype_t*)core("FloatingPoint");

jl_stackovf_exception =
jl_apply((jl_function_t*)core("StackOverflowError"), NULL, 0);
Expand Down
Loading

0 comments on commit ca1c1df

Please sign in to comment.