Merge pull request #5348 from basile-henry/basile/num-is-nan

Implement builtins for Num.isNan, Num.isInfinite, and Num.isFinite
This commit is contained in:
Richard Feldman 2023-05-05 06:15:18 -04:00 committed by GitHub
commit df0ab01128
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
80 changed files with 697 additions and 258 deletions

View file

@ -126,6 +126,8 @@ comptime {
num.exportSubWithOverflow(T, ROC_BUILTINS ++ "." ++ NUM ++ ".sub_with_overflow.");
num.exportMulWithOverflow(T, T, ROC_BUILTINS ++ "." ++ NUM ++ ".mul_with_overflow.");
num.exportIsNan(T, ROC_BUILTINS ++ "." ++ NUM ++ ".is_nan.");
num.exportIsInfinite(T, ROC_BUILTINS ++ "." ++ NUM ++ ".is_infinite.");
num.exportIsFinite(T, ROC_BUILTINS ++ "." ++ NUM ++ ".is_finite.");
}
}

View file

@ -95,6 +95,24 @@ pub fn exportPow(comptime T: type, comptime name: []const u8) void {
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportIsNan(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(input: T) callconv(.C) bool {
return std.math.isNan(input);
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportIsInfinite(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(input: T) callconv(.C) bool {
return std.math.isInf(input);
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportIsFinite(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(input: T) callconv(.C) bool {

View file

@ -55,6 +55,9 @@ interface Num
toFrac,
isPositive,
isNegative,
isNaN,
isInfinite,
isFinite,
rem,
remChecked,
div,
@ -621,6 +624,29 @@ isNegative = \x -> x < 0
toFrac : Num * -> Frac *
## Returns `Bool.true` if the [Frac] is not a number as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
##
## ```
## Num.isNaN (0 / 0)
## ```
isNaN : Frac * -> Bool
## Returns `Bool.true` if the [Frac] is positive or negative infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
##
## ```
## Num.isInfinite (1 / 0)
##
## Num.isInfinite (-1 / 0)
## ```
isInfinite : Frac * -> Bool
## Returns `Bool.true` if the [Frac] is not an infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
##
## ```
## Num.isFinite 42
## ```
isFinite : Frac * -> Bool
## Return the absolute value of the number.
##
## * For a positive number, returns the same number.

View file

@ -262,6 +262,8 @@ pub const NUM_COS: IntrinsicName = float_intrinsic!("roc_builtins.num.cos");
pub const NUM_ASIN: IntrinsicName = float_intrinsic!("roc_builtins.num.asin");
pub const NUM_ACOS: IntrinsicName = float_intrinsic!("roc_builtins.num.acos");
pub const NUM_ATAN: IntrinsicName = float_intrinsic!("roc_builtins.num.atan");
pub const NUM_IS_NAN: IntrinsicName = float_intrinsic!("roc_builtins.num.is_nan");
pub const NUM_IS_INFINITE: IntrinsicName = float_intrinsic!("roc_builtins.num.is_infinite");
pub const NUM_IS_FINITE: IntrinsicName = float_intrinsic!("roc_builtins.num.is_finite");
pub const NUM_LOG: IntrinsicName = float_intrinsic!("roc_builtins.num.log");
pub const NUM_POW: IntrinsicName = float_intrinsic!("roc_builtins.num.pow");

View file

@ -184,6 +184,9 @@ map_symbol_to_lowlevel_and_arity! {
NumLogUnchecked; NUM_LOG; 1,
NumRound; NUM_ROUND; 1,
NumToFrac; NUM_TO_FRAC; 1,
NumIsNan; NUM_IS_NAN; 1,
NumIsInfinite; NUM_IS_INFINITE; 1,
NumIsFinite; NUM_IS_FINITE; 1,
NumPow; NUM_POW; 2,
NumCeiling; NUM_CEILING; 1,
NumPowInt; NUM_POW_INT; 2,

View file

@ -750,6 +750,16 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64FloatReg) {
fmov_freg_freg(buf, FloatWidth::F64, dst, src);
}
#[inline(always)]
fn mov_reg32_freg32(_buf: &mut Vec<'_, u8>, _dst: AArch64GeneralReg, _src: AArch64FloatReg) {
unimplemented!();
}
#[inline(always)]
fn mov_reg64_freg64(_buf: &mut Vec<'_, u8>, _dst: AArch64GeneralReg, _src: AArch64FloatReg) {
unimplemented!();
}
#[inline(always)]
fn mov_reg_reg(
buf: &mut Vec<'_, u8>,
@ -1086,6 +1096,17 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
cset_reg64_cond(buf, dst, cond);
}
#[inline(always)]
fn is_nan_freg_reg64(
buf: &mut Vec<'_, u8>,
dst: AArch64GeneralReg,
src: AArch64FloatReg,
width: FloatWidth,
) {
fcmp_freg_freg(buf, width, src, src);
cset_reg64_cond(buf, dst, ConditionCode::NE);
}
#[inline(always)]
fn to_float_freg64_reg64(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, src: AArch64GeneralReg) {
scvtf_freg_reg64(buf, FloatWidth::F64, dst, src);

View file

@ -269,6 +269,9 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
fn mov_reg64_imm64(buf: &mut Vec<'_, u8>, dst: GeneralReg, imm: i64);
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: FloatReg);
fn mov_reg32_freg32(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: FloatReg);
fn mov_reg64_freg64(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: FloatReg);
fn mov_reg_reg(
buf: &mut Vec<'_, u8>,
register_width: RegisterWidth,
@ -535,6 +538,8 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
operation: CompareOperation,
);
fn is_nan_freg_reg64(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: FloatReg, width: FloatWidth);
fn to_float_freg32_reg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: GeneralReg);
fn to_float_freg64_reg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: GeneralReg);
@ -1585,6 +1590,89 @@ impl<
}
}
fn build_num_is_nan(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
let float_width = match *arg_layout {
Layout::F32 => FloatWidth::F32,
Layout::F64 => FloatWidth::F64,
_ => unreachable!(),
};
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::is_nan_freg_reg64(&mut self.buf, dst_reg, src_reg, float_width);
}
fn build_num_is_infinite(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
self.storage_manager.with_tmp_general_reg(
&mut self.buf,
|_storage_manager, buf, mask_reg| {
match *arg_layout {
Layout::F32 => {
ASM::mov_reg64_imm64(buf, mask_reg, 0x7fff_ffff);
ASM::xor_reg64_reg64_reg64(buf, dst_reg, dst_reg, dst_reg); // zero out dst reg
ASM::mov_reg32_freg32(buf, dst_reg, src_reg);
ASM::and_reg64_reg64_reg64(buf, dst_reg, dst_reg, mask_reg);
ASM::mov_reg64_imm64(buf, mask_reg, 0x7f80_0000);
ASM::eq_reg_reg_reg(buf, RegisterWidth::W32, dst_reg, dst_reg, mask_reg);
}
Layout::F64 => {
ASM::mov_reg64_imm64(buf, mask_reg, 0x7fff_ffff_ffff_ffff);
ASM::mov_reg64_freg64(buf, dst_reg, src_reg);
ASM::and_reg64_reg64_reg64(buf, dst_reg, dst_reg, mask_reg);
ASM::mov_reg64_imm64(buf, mask_reg, 0x7ff0_0000_0000_0000);
ASM::eq_reg_reg_reg(buf, RegisterWidth::W64, dst_reg, dst_reg, mask_reg);
}
_ => unreachable!(),
}
},
);
}
fn build_num_is_finite(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
self.storage_manager.with_tmp_general_reg(
&mut self.buf,
|_storage_manager, buf, mask_reg| {
match *arg_layout {
Layout::F32 => {
ASM::mov_reg64_imm64(buf, mask_reg, 0x7f80_0000);
ASM::xor_reg64_reg64_reg64(buf, dst_reg, dst_reg, dst_reg); // zero out dst reg
ASM::mov_reg32_freg32(buf, dst_reg, src_reg);
ASM::and_reg64_reg64_reg64(buf, dst_reg, dst_reg, mask_reg);
ASM::neq_reg64_reg64_reg64(
buf,
RegisterWidth::W32,
dst_reg,
dst_reg,
mask_reg,
);
}
Layout::F64 => {
ASM::mov_reg64_imm64(buf, mask_reg, 0x7ff0_0000_0000_0000);
ASM::mov_reg64_freg64(buf, dst_reg, src_reg);
ASM::and_reg64_reg64_reg64(buf, dst_reg, dst_reg, mask_reg);
ASM::neq_reg64_reg64_reg64(
buf,
RegisterWidth::W64,
dst_reg,
dst_reg,
mask_reg,
);
}
_ => unreachable!(),
}
},
);
}
fn build_num_lt(
&mut self,
dst: &Symbol,

View file

@ -1483,6 +1483,16 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) {
movsd_freg64_freg64(buf, dst, src);
}
#[inline(always)]
fn mov_reg32_freg32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
movd_reg32_freg32(buf, dst, src);
}
#[inline(always)]
fn mov_reg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
movq_reg64_freg64(buf, dst, src);
}
#[inline(always)]
fn mov_reg_reg(
buf: &mut Vec<'_, u8>,
@ -1795,6 +1805,21 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
};
}
#[inline(always)]
fn is_nan_freg_reg64(
buf: &mut Vec<'_, u8>,
dst: X86_64GeneralReg,
src: X86_64FloatReg,
width: FloatWidth,
) {
match width {
FloatWidth::F32 => cmp_freg32_freg32(buf, src, src),
FloatWidth::F64 => cmp_freg64_freg64(buf, src, src),
}
setp_reg64(buf, dst)
}
#[inline(always)]
fn to_float_freg32_reg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64GeneralReg) {
cvtsi2ss_freg64_reg64(buf, dst, src);
@ -2901,6 +2926,33 @@ fn movzx_reg64_base16_offset32(
movzx_reg64_base_offset32(buf, dst, base, offset, 0xB7)
}
#[inline(always)]
fn movd_reg32_freg32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
let dst_high = dst as u8 > 7;
let dst_mod = dst as u8 % 8;
let src_high = src as u8 > 7;
let src_mod = src as u8 % 8;
if dst_high || src_high {
let rex = add_rm_extension(dst, REX);
let rex = add_reg_extension(src, rex);
buf.extend([0x66, rex, 0x0F, 0x7E, 0xC0 | (src_mod << 3) | (dst_mod)])
} else {
buf.extend([0x66, 0x0F, 0x7E, 0xC0 | (src_mod << 3) | (dst_mod)])
}
}
#[inline(always)]
fn movq_reg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64FloatReg) {
let dst_mod = dst as u8 % 8;
let src_mod = src as u8 % 8;
let rex = add_rm_extension(dst, REX_W);
let rex = add_reg_extension(src, rex);
buf.extend([0x66, rex, 0x0F, 0x7E, 0xC0 | (src_mod << 3) | (dst_mod)]);
}
/// `MOVSD xmm1,xmm2` -> Move scalar double-precision floating-point value from xmm2 to xmm1 register.
/// This will not generate anything if dst and src are the same.
#[inline(always)]
@ -3191,12 +3243,18 @@ fn setge_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
set_reg64_help(0x9d, buf, reg);
}
/// `SETO r/m64` -> Set byte if oveflow flag is set.
/// `SETO r/m64` -> Set byte if overflow flag is set.
#[inline(always)]
fn seto_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
set_reg64_help(0x90, buf, reg);
}
/// `SETP r/m64` -> Set byte if parity (PF=1).
#[inline(always)]
fn setp_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
set_reg64_help(0x9A, buf, reg);
}
/// `RET` -> Near return to calling procedure.
#[inline(always)]
fn ret(buf: &mut Vec<'_, u8>) {
@ -3905,6 +3963,26 @@ mod tests {
);
}
#[test]
fn test_movd_reg32_freg32() {
disassembler_test!(
movd_reg32_freg32,
|dst: X86_64GeneralReg, src| format!("movd {}, {}", dst.low_32bits_string(), src),
ALL_GENERAL_REGS,
ALL_FLOAT_REGS
);
}
#[test]
fn test_movq_reg64_freg64() {
disassembler_test!(
movq_reg64_freg64,
|dst, src| format!("movq {}, {}", dst, src),
ALL_GENERAL_REGS,
ALL_FLOAT_REGS
);
}
#[test]
fn test_movsd_freg64_freg64() {
disassembler_test!(

View file

@ -830,6 +830,48 @@ trait Backend<'a> {
);
self.build_num_to_frac(sym, &args[0], &arg_layouts[0], ret_layout)
}
LowLevel::NumIsNan => {
debug_assert_eq!(
1,
args.len(),
"NumIsNan: expected to have exactly one argument"
);
debug_assert_eq!(
Layout::BOOL,
*ret_layout,
"NumIsNan: expected to have return layout of type Bool"
);
self.build_num_is_nan(sym, &args[0], &arg_layouts[0])
}
LowLevel::NumIsInfinite => {
debug_assert_eq!(
1,
args.len(),
"NumIsInfinite: expected to have exactly one argument"
);
debug_assert_eq!(
Layout::BOOL,
*ret_layout,
"NumIsInfinite: expected to have return layout of type Bool"
);
self.build_num_is_infinite(sym, &args[0], &arg_layouts[0])
}
LowLevel::NumIsFinite => {
debug_assert_eq!(
1,
args.len(),
"NumIsFinite: expected to have exactly one argument"
);
debug_assert_eq!(
Layout::BOOL,
*ret_layout,
"NumIsFinite: expected to have return layout of type Bool"
);
self.build_num_is_finite(sym, &args[0], &arg_layouts[0])
}
LowLevel::NumLte => {
debug_assert_eq!(
2,
@ -1477,6 +1519,15 @@ trait Backend<'a> {
ret_layout: &InLayout<'a>,
);
/// build_num_is_nan check is a Frac is NaN
fn build_num_is_nan(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>);
/// build_num_is_infinite check is a Frac is infinite
fn build_num_is_infinite(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>);
/// build_num_is_finite check is a Frac is finite
fn build_num_is_finite(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>);
/// build_num_lte stores the result of `src1 <= src2` into dst.
fn build_num_lte(
&mut self,

View file

@ -885,6 +885,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
| NumCeiling
| NumFloor
| NumToFrac
| NumIsNan
| NumIsInfinite
| NumIsFinite
| NumAtan
| NumAcos
@ -2351,6 +2353,10 @@ fn build_float_unary_op<'a, 'ctx>(
"num_round",
)
}
NumIsNan => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_IS_NAN[float_width]),
NumIsInfinite => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_IS_INFINITE[float_width])
}
NumIsFinite => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_IS_FINITE[float_width]),
// trigonometry

View file

@ -1613,6 +1613,8 @@ impl<'a> LowLevelCall<'a> {
self.load_args_and_call_zig(backend, &bitcode::NUM_POW_INT[width])
}
NumIsNan => num_is_nan(backend, self.arguments[0]),
NumIsInfinite => num_is_infinite(backend, self.arguments[0]),
NumIsFinite => num_is_finite(backend, self.arguments[0]),
NumAtan => match self.ret_layout_raw {
@ -2167,6 +2169,112 @@ impl<'a> LowLevelCall<'a> {
}
}
/// Helper for NumIsNan op
fn num_is_nan(backend: &mut WasmBackend<'_, '_>, argument: Symbol) {
use StoredValue::*;
let stored = backend.storage.get(&argument).to_owned();
match stored {
VirtualMachineStack { value_type, .. } | Local { value_type, .. } => {
backend
.storage
.load_symbols(&mut backend.code_builder, &[argument]);
match value_type {
// Integers are never NaN. Just return False.
ValueType::I32 | ValueType::I64 => backend.code_builder.i32_const(0),
ValueType::F32 => {
backend.code_builder.i32_reinterpret_f32();
backend.code_builder.i32_const(0x7f80_0000);
backend.code_builder.i32_and();
backend.code_builder.i32_const(0x7f80_0000);
backend.code_builder.i32_eq(); // Exponents are all ones
backend
.storage
.load_symbols(&mut backend.code_builder, &[argument]);
backend.code_builder.i32_reinterpret_f32();
backend.code_builder.i32_const(0x007f_ffff);
backend.code_builder.i32_and();
backend.code_builder.i32_const(0);
backend.code_builder.i32_ne(); // Mantissa is non-zero
backend.code_builder.i32_and();
}
ValueType::F64 => {
backend.code_builder.i64_reinterpret_f64();
backend.code_builder.i64_const(0x7ff0_0000_0000_0000);
backend.code_builder.i64_and();
backend.code_builder.i64_const(0x7ff0_0000_0000_0000);
backend.code_builder.i64_eq(); // Exponents are all ones
backend
.storage
.load_symbols(&mut backend.code_builder, &[argument]);
backend.code_builder.i64_reinterpret_f64();
backend.code_builder.i64_const(0x000f_ffff_ffff_ffff);
backend.code_builder.i64_and();
backend.code_builder.i64_const(0);
backend.code_builder.i64_ne(); // Mantissa is non-zero
backend.code_builder.i32_and();
}
}
}
StackMemory { format, .. } => {
match format {
// Integers and fixed-point numbers are NaN. Just return False.
StackMemoryFormat::Int128 | StackMemoryFormat::Decimal => {
backend.code_builder.i32_const(0)
}
StackMemoryFormat::DataStructure => {
internal_error!("Tried to perform NumIsInfinite on a data structure")
}
}
}
}
}
/// Helper for NumIsInfinite op
fn num_is_infinite(backend: &mut WasmBackend<'_, '_>, argument: Symbol) {
use StoredValue::*;
let stored = backend.storage.get(&argument).to_owned();
match stored {
VirtualMachineStack { value_type, .. } | Local { value_type, .. } => {
backend
.storage
.load_symbols(&mut backend.code_builder, &[argument]);
match value_type {
// Integers are never infinite. Just return False.
ValueType::I32 | ValueType::I64 => backend.code_builder.i32_const(0),
ValueType::F32 => {
backend.code_builder.i32_reinterpret_f32();
backend.code_builder.i32_const(0x7fff_ffff);
backend.code_builder.i32_and();
backend.code_builder.i32_const(0x7f80_0000);
backend.code_builder.i32_eq();
}
ValueType::F64 => {
backend.code_builder.i64_reinterpret_f64();
backend.code_builder.i64_const(0x7fff_ffff_ffff_ffff);
backend.code_builder.i64_and();
backend.code_builder.i64_const(0x7ff0_0000_0000_0000);
backend.code_builder.i64_eq();
}
}
}
StackMemory { format, .. } => {
match format {
// Integers and fixed-point numbers are never infinite. Just return False.
StackMemoryFormat::Int128 | StackMemoryFormat::Decimal => {
backend.code_builder.i32_const(0)
}
StackMemoryFormat::DataStructure => {
internal_error!("Tried to perform NumIsInfinite on a data structure")
}
}
}
}
}
/// Helper for NumIsFinite op, and also part of Eq/NotEq
fn num_is_finite(backend: &mut WasmBackend<'_, '_>, argument: Symbol) {
use StoredValue::*;

View file

@ -86,6 +86,8 @@ pub enum LowLevel {
NumCeiling,
NumPowInt,
NumFloor,
NumIsNan,
NumIsInfinite,
NumIsFinite,
NumAtan,
NumAcos,
@ -234,7 +236,6 @@ macro_rules! map_symbol_to_lowlevel {
// these are not implemented, not sure why
LowLevel::StrFromInt => unimplemented!(),
LowLevel::StrFromFloat => unimplemented!(),
LowLevel::NumIsFinite => unimplemented!(),
}
}
};
@ -314,6 +315,9 @@ map_symbol_to_lowlevel! {
NumLogUnchecked <= NUM_LOG,
NumRound <= NUM_ROUND,
NumToFrac <= NUM_TO_FRAC,
NumIsNan <= NUM_IS_NAN,
NumIsInfinite <= NUM_IS_INFINITE,
NumIsFinite <= NUM_IS_FINITE,
NumPow <= NUM_POW,
NumCeiling <= NUM_CEILING,
NumPowInt <= NUM_POW_INT,

View file

@ -1259,6 +1259,9 @@ define_builtins! {
153 NUM_COUNT_TRAILING_ZERO_BITS: "countTrailingZeroBits"
154 NUM_COUNT_ONE_BITS: "countOneBits"
155 NUM_ABS_DIFF: "absDiff"
156 NUM_IS_NAN: "isNaN"
157 NUM_IS_INFINITE: "isInfinite"
158 NUM_IS_FINITE: "isFinite"
}
4 BOOL: "Bool" => {
0 BOOL_BOOL: "Bool" exposed_type=true // the Bool.Bool type alias

View file

@ -1002,6 +1002,8 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] {
| NumFloor
| NumToFrac
| Not
| NumIsNan
| NumIsInfinite
| NumIsFinite
| NumAtan
| NumAcos

View file

@ -109,6 +109,8 @@ enum FirstOrder {
NumCeiling,
NumPowInt,
NumFloor,
NumIsNan,
NumIsInfinite,
NumIsFinite,
NumAtan,
NumAcos,

View file

@ -1705,6 +1705,31 @@ fn float_to_float() {
assert_evals_to!("Num.toFrac 0.5", 0.5, f64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn frac_is_nan() {
assert_evals_to!("Num.isNaN (0 / 0)", true, bool);
assert_evals_to!("Num.isNaN (1 / 0)", false, bool);
assert_evals_to!("Num.isNaN 42", false, bool);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn frac_is_infinite() {
assert_evals_to!("Num.isInfinite (1 / 0)", true, bool);
assert_evals_to!("Num.isInfinite (-1 / 0)", true, bool);
assert_evals_to!("Num.isInfinite (0 / 0)", false, bool);
assert_evals_to!("Num.isInfinite 42", false, bool);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn frac_is_finite() {
assert_evals_to!("Num.isFinite 42", true, bool);
assert_evals_to!("Num.isFinite (1 / 0)", false, bool);
assert_evals_to!("Num.isFinite (0 / 0)", false, bool);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn int_compare() {

View file

@ -86,16 +86,16 @@ procedure List.92 (List.430, List.431, List.432):
ret List.515;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.280 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.283;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.284;
procedure Num.77 (#Attr.2, #Attr.3):
let Num.279 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.282;
procedure Test.1 (Test.2):
let Test.13 : U64 = 0i64;

View file

@ -47,8 +47,8 @@ procedure List.9 (List.287):
ret List.496;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Result.5 (Result.12, Result.13):
let Result.39 : U8 = 1i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.279 : I128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : I128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.282;
procedure Test.0 ():
let Test.6 : I128 = 18446744073709551616i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.2 : U128 = 170141183460469231731687303715884105728u128;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.2 : U64 = 9999999999999999999i64;

View file

@ -40,12 +40,12 @@ procedure List.92 (List.430, List.431, List.432):
ret List.497;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.279 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.282;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.300 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -79,12 +79,12 @@ procedure List.82 (List.526, List.527, List.528):
jump List.508 List.526 List.527 List.528;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.279 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.282;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.281 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.281;
let Num.284 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.284;
procedure Test.0 ():
let Test.3 : {} = Struct {};

View file

@ -25,8 +25,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.499;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Test.2 (Test.5):
dec Test.5;

View file

@ -287,24 +287,24 @@ procedure List.92 (List.430, List.431, List.432):
ret List.592;
procedure Num.127 (#Attr.2):
let Num.304 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.304;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.307 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
let Num.307 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.307;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.305 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.305;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.310 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.310;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.308 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.308 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.308;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.311 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.311;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.306 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.306;
let Num.309 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.309;
procedure Str.12 (#Attr.2):
let Str.315 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -170,24 +170,24 @@ procedure List.92 (List.430, List.431, List.432):
ret List.525;
procedure Num.127 (#Attr.2):
let Num.285 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.285;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.288 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
let Num.288 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.288;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.286 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.286;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.291 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.291;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.289 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.289 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.289;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.292 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.292;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.287 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.287;
let Num.290 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.290;
procedure Str.12 (#Attr.2):
let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -177,24 +177,24 @@ procedure List.92 (List.430, List.431, List.432):
ret List.525;
procedure Num.127 (#Attr.2):
let Num.285 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.285;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.288 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
let Num.288 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.288;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.286 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.286;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.291 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.291;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.289 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.289 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.289;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.292 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.292;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.287 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.287;
let Num.290 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.290;
procedure Str.12 (#Attr.2):
let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -53,8 +53,8 @@ procedure List.8 (#Attr.2, #Attr.3):
ret List.504;
procedure Num.127 (#Attr.2):
let Num.279 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.279;
let Num.282 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.282;
procedure Str.12 (#Attr.2):
let Str.312 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -179,24 +179,24 @@ procedure List.92 (List.430, List.431, List.432):
ret List.531;
procedure Num.127 (#Attr.2):
let Num.287 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.287;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.290 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
let Num.290 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.290;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.288 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.288;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.293 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.293;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.291 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.291 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.291;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.294 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.294;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.289 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.289;
let Num.292 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.292;
procedure Str.12 (#Attr.2):
let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -182,24 +182,24 @@ procedure List.92 (List.430, List.431, List.432):
ret List.531;
procedure Num.127 (#Attr.2):
let Num.287 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.287;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.290 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
let Num.290 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.290;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.288 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.288;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.293 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.293;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.291 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.291 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.291;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.294 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.294;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.289 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.289;
let Num.292 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.292;
procedure Str.12 (#Attr.2):
let Str.313 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -1,10 +1,10 @@
procedure Num.20 (#Attr.2, #Attr.3):
let Num.279 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.282;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.15, Test.16):
joinpoint Test.7 Test.2 Test.3:

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.8):
let Test.3 : I64 = 10i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.279 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.282;
procedure Test.1 (Test.9):
let Test.4 : U8 = 10i64;

View file

@ -3,8 +3,8 @@ procedure Bool.1 ():
ret Bool.23;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.3 (Test.4):
ret Test.4;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.280 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.283;
procedure Test.2 (Test.3):
switch Test.3:

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.279 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.282;
procedure Test.2 (Test.3, Test.1):
let Test.17 : Int1 = false;

View file

@ -3,8 +3,8 @@ procedure List.6 (#Attr.2):
ret List.494;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.280 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.283;
procedure Test.0 ():
let Test.1 : List I64 = Array [1i64, 2i64];

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.2 : I64 = 1i64;

View file

@ -1,6 +1,6 @@
procedure Num.45 (#Attr.2):
let Num.278 : I64 = lowlevel NumRound #Attr.2;
ret Num.278;
let Num.281 : I64 = lowlevel NumRound #Attr.2;
ret Num.281;
procedure Test.0 ():
let Test.2 : Float64 = 3.6f64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.1 : I64 = 3i64;

View file

@ -1,22 +1,22 @@
procedure Num.30 (#Attr.2):
let Num.285 : I64 = 0i64;
let Num.284 : Int1 = lowlevel Eq #Attr.2 Num.285;
ret Num.284;
let Num.288 : I64 = 0i64;
let Num.287 : Int1 = lowlevel Eq #Attr.2 Num.288;
ret Num.287;
procedure Num.39 (#Attr.2, #Attr.3):
let Num.280 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3;
ret Num.283;
procedure Num.40 (Num.250, Num.251):
let Num.281 : Int1 = CallByName Num.30 Num.251;
if Num.281 then
let Num.283 : {} = Struct {};
let Num.282 : [C {}, C I64] = TagId(0) Num.283;
ret Num.282;
procedure Num.40 (Num.253, Num.254):
let Num.284 : Int1 = CallByName Num.30 Num.254;
if Num.284 then
let Num.286 : {} = Struct {};
let Num.285 : [C {}, C I64] = TagId(0) Num.286;
ret Num.285;
else
let Num.279 : I64 = CallByName Num.39 Num.250 Num.251;
let Num.278 : [C {}, C I64] = TagId(1) Num.279;
ret Num.278;
let Num.282 : I64 = CallByName Num.39 Num.253 Num.254;
let Num.281 : [C {}, C I64] = TagId(1) Num.282;
ret Num.281;
procedure Test.0 ():
let Test.8 : I64 = 1000i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.10 : I64 = 41i64;

View file

@ -44,8 +44,8 @@ procedure List.9 (List.287):
ret List.496;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Str.27 (Str.99):
let Str.298 : [C Int1, C I64] = CallByName Str.72 Str.99;

View file

@ -320,16 +320,16 @@ procedure List.72 (#Attr.2, #Attr.3, #Attr.4):
ret List.505;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.279 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.282;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.281 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.281;
let Num.284 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.284;
procedure Num.77 (#Attr.2, #Attr.3):
let Num.283 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.283;
let Num.286 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.286;
procedure Str.48 (#Attr.2, #Attr.3, #Attr.4):
let Str.307 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;

View file

@ -82,17 +82,17 @@ procedure List.92 (List.430, List.431, List.432):
ret List.507;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.280 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.280;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.283;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.284;
procedure Test.1 (Test.77):
joinpoint Test.26 Test.6:
let Test.65 : [<r>C I64, C List *self] = StructAtIndex 1 Test.6;

View file

@ -291,16 +291,16 @@ procedure List.72 (#Attr.2, #Attr.3, #Attr.4):
ret List.499;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.279 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.282;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.281 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.281;
let Num.284 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.284;
procedure Num.77 (#Attr.2, #Attr.3):
let Num.283 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.283;
let Num.286 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.286;
procedure Str.12 (#Attr.2):
let Str.307 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -1,10 +1,10 @@
procedure Num.96 (#Attr.2):
let Num.278 : Str = lowlevel NumToStr #Attr.2;
ret Num.278;
let Num.281 : Str = lowlevel NumToStr #Attr.2;
ret Num.281;
procedure Num.96 (#Attr.2):
let Num.279 : Str = lowlevel NumToStr #Attr.2;
ret Num.279;
let Num.282 : Str = lowlevel NumToStr #Attr.2;
ret Num.282;
procedure Test.1 (Test.4):
let Test.13 : [C U8, C U64] = TagId(1) Test.4;

View file

@ -7,12 +7,12 @@ procedure Bool.2 ():
ret Bool.24;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.279 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.282;
procedure Test.0 (Test.8):
let Test.20 : Int1 = CallByName Bool.2;

View file

@ -37,12 +37,12 @@ procedure List.92 (List.430, List.431, List.432):
ret List.497;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.279 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.282;
procedure Test.7 (Test.11, Test.12):
let Test.17 : {[<rnu>C *self, <null>], [<rnu><null>, C {[<rnu>C *self, <null>], *self}]} = Struct {Test.12, Test.11};

View file

@ -22,12 +22,12 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
ret List.501;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.279 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.282;
procedure Test.1 ():
let Test.8 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -21,8 +21,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.499;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.2):
let Test.6 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -7,8 +7,8 @@ procedure List.6 (#Attr.2):
ret List.495;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.1 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -27,8 +27,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.499;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Str.16 (#Attr.2, #Attr.3):
let Str.298 : Str = lowlevel StrRepeat #Attr.2 #Attr.3;

View file

@ -27,8 +27,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.499;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.299 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -21,8 +21,8 @@ procedure List.5 (#Attr.2, #Attr.3):
procedure Num.19 (#Attr.2, #Attr.3):
let Num.280 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.283;
procedure Test.4 (Test.5, #Attr.12):
let Test.1 : U8 = UnionAtIndex (Id 0) (Index 0) #Attr.12;

View file

@ -22,8 +22,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
ret List.499;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.278 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
procedure Test.2 (Test.3):
let Test.6 : U64 = 0i64;

View file

@ -8,8 +8,8 @@ procedure List.59 (List.282):
ret List.494;
procedure Num.46 (#Attr.2, #Attr.3):
let Num.278 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.2 : List I64 = Array [4i64, 3i64, 2i64, 1i64];

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.19 : I64 = 41i64;

View file

@ -1,6 +1,6 @@
procedure Num.37 (#Attr.2, #Attr.3):
let Num.278 : Float64 = lowlevel NumDivFrac #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : Float64 = lowlevel NumDivFrac #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.2 : Float64 = 1f64;

View file

@ -1,6 +1,6 @@
procedure Num.21 (#Attr.2, #Attr.3):
let Num.280 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.283;
procedure Test.1 (Test.6):
let Test.21 : Int1 = false;

View file

@ -1,14 +1,14 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.279 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.282;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.280 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.283;
procedure Test.1 (Test.24, Test.25, Test.26):
joinpoint Test.12 Test.2 Test.3 Test.4:

View file

@ -40,8 +40,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
ret List.499;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.280 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.283;
procedure Test.1 (Test.2):
let Test.28 : U64 = 0i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.4):
let Test.2 : I64 = StructAtIndex 0 Test.4;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.4):
let Test.2 : I64 = 10i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.2):
let Test.3 : I64 = StructAtIndex 0 Test.2;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.2):
let Test.3 : I64 = 10i64;

View file

@ -3,8 +3,8 @@ procedure Bool.2 ():
ret Bool.23;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.2):
let Test.8 : U32 = 0i64;

View file

@ -3,12 +3,12 @@ procedure Bool.11 (#Attr.2, #Attr.3):
ret Bool.23;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.279 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.282;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.278 : U8 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U8 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.26, Test.27):
joinpoint Test.11 Test.2 Test.3:

View file

@ -1,6 +1,6 @@
procedure Num.20 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.281;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.300 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -40,8 +40,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
ret List.499;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.280 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.283;
procedure Test.1 (Test.2, Test.3, Test.4):
inc Test.4;

View file

@ -3,12 +3,12 @@ procedure Bool.2 ():
ret Bool.24;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.279 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.282;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.2, Test.3):
let Test.15 : U8 = GetTagId Test.2;

View file

@ -3,12 +3,12 @@ procedure Bool.2 ():
ret Bool.23;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.279 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.282;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.281;
procedure Test.6 (Test.8, #Attr.12):
let Test.4 : I64 = UnionAtIndex (Id 0) (Index 0) #Attr.12;

View file

@ -1,10 +1,10 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.279 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.282;
procedure Test.1 (Test.15, Test.16):
joinpoint Test.7 Test.2 Test.3:

View file

@ -164,24 +164,24 @@ procedure List.92 (List.430, List.431, List.432):
ret List.529;
procedure Num.127 (#Attr.2):
let Num.287 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.287;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.290 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
let Num.290 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.290;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.288 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.288;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.293 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.293;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.291 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.291 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.291;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.294 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.294;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.289 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.289;
let Num.292 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.292;
procedure Str.12 (#Attr.2):
let Str.299 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -296,24 +296,24 @@ procedure List.92 (List.430, List.431, List.432):
ret List.596;
procedure Num.127 (#Attr.2):
let Num.306 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.306;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.309 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
let Num.309 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.309;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.307 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.307;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.312 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.312;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.310 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.310 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.310;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.313 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.313;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.308 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.308;
let Num.311 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.311;
procedure Str.12 (#Attr.2):
let Str.300 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -86,16 +86,16 @@ procedure List.92 (List.430, List.431, List.432):
ret List.515;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.280 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.280;
let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.283;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.281;
let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.284;
procedure Num.77 (#Attr.2, #Attr.3):
let Num.279 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.279;
let Num.282 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.282;
procedure Test.3 (Test.4, Test.12):
let Test.13 : [C U64, C U64] = TagId(0) Test.4;

View file

@ -3,8 +3,8 @@ procedure Bool.2 ():
ret Bool.25;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.1 (Test.2):
joinpoint Test.12:

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.19 : I64 = 41i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.5 : I64 = 2i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.278 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.278;
let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.281;
procedure Test.0 ():
let Test.15 : I64 = 3i64;