Stream: git-wasmtime

Topic: wasmtime / Issue #2883 Cranelift: `unreachable` in `crane...


view this post on Zulip Wasmtime GitHub notifications bot (May 07 2021 at 13:54):

mental32 labeled Issue #2883:

.clif Test Case

function u0:0() -> i64 system_v {
    block0:
        v0 = iconst.i64 1
        v1 = iconst.i64 1
        v2 = ssub_sat v0, v1
        return v2
}

Steps to Reproduce

Use ssub_sat with two I64 values and (at least for my case) use cranelift-object with a triple that looks like:

target_lexicon::Triple::host() = Triple {
    architecture: X86_64,
    vendor: Unknown,
    operating_system: Linux,
    environment: Gnu,
    binary_format: Elf,
}

Expected Results

The code should compile correctly and the function should return 0

Actual Results

thread 'main' panicked at 'internal error: entered unreachable code: SsubSat', /home/mental/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-codegen-0.73.0/src/isa/x64/lower.rs:1800:26

(note that the unreachable message is actually empty in the code, I have modified it locally to emit the unsupported opcode)

an unreachable case is hit instead.

Versions and Environment

Cranelift version or commit: 0.73.0

Operating system: Linux felix 5.11.15-arch1-2 #1 SMP PREEMPT Sat, 17 Apr 2021 00:22:30 +0000 x86_64 GNU/Linux

Architecture: x86_64

Extra Info

<details>
<summary>minimal, complete and verifiable example (mcve)</summary>

use cranelift_codegen::{binemit, ir::InstBuilder, Context};
use cranelift_codegen::{
    ir::{self, Signature},
    isa, settings, verify_function,
};
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use cranelift_module::{Linkage, Module};
use cranelift_object::{ObjectBuilder, ObjectModule};
use settings::FlagsOrIsa;

fn main() {
    let target_isa = isa::lookup(dbg!(target_lexicon::Triple::host()))
        .unwrap()
        .finish(settings::Flags::new(settings::builder()));

    let object_builder = ObjectBuilder::new(
        target_isa,
        "<empty>".to_string(),
        cranelift_module::default_libcall_names(),
    )
    .unwrap();

    let target_isa = isa::lookup(target_lexicon::Triple::host())
        .unwrap()
        .finish(settings::Flags::new(settings::builder()));

    let mut object_module = ObjectModule::new(object_builder);

    let mut sig = Signature::new(cranelift_codegen::isa::CallConv::SystemV);

    sig.returns.push(ir::AbiParam::new(ir::types::I64));

    let mut func = ir::Function::with_name_signature(
        ir::ExternalName::User {
            namespace: 0,
            index: 0,
        },
        sig,
    );

    let mut builder_ctx = FunctionBuilderContext::new();
    let mut builder = FunctionBuilder::new(&mut func, &mut builder_ctx);

    let b0 = builder.create_block();

    builder.switch_to_block(b0);

    let v1 = builder.ins().iconst(ir::types::I64, 1);
    let v2 = builder.ins().iconst(ir::types::I64, 1);

    let v3 = builder.ins().ssub_sat(v1, v2);

    builder.ins().return_(&[v3]);

    let fisa = FlagsOrIsa::from(&*target_isa);

    verify_function(&builder.func, fisa).unwrap();

    let fid = object_module
        .declare_function(&"main", Linkage::Export, &func.signature.clone())
        .unwrap();

    let mut ctx = Context::for_function(func);

    object_module
        .define_function(
            fid,
            &mut ctx,
            &mut binemit::NullTrapSink {},
            &mut binemit::NullStackMapSink {},
        )
        .unwrap();
}
[package]
name = "clif-usub"
version = "0.1.0"
edition = "2018"

[dependencies]
cranelift-codegen = "0.73.0"
cranelift-frontend = "0.73.0"
cranelift-object = "0.73.0"
cranelift-module = "0.73.0"
target-lexicon = "0.12.0"

</details>

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2021 at 13:54):

mental32 labeled Issue #2883:

.clif Test Case

function u0:0() -> i64 system_v {
    block0:
        v0 = iconst.i64 1
        v1 = iconst.i64 1
        v2 = ssub_sat v0, v1
        return v2
}

Steps to Reproduce

Use ssub_sat with two I64 values and (at least for my case) use cranelift-object with a triple that looks like:

target_lexicon::Triple::host() = Triple {
    architecture: X86_64,
    vendor: Unknown,
    operating_system: Linux,
    environment: Gnu,
    binary_format: Elf,
}

Expected Results

The code should compile correctly and the function should return 0

Actual Results

thread 'main' panicked at 'internal error: entered unreachable code: SsubSat', /home/mental/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-codegen-0.73.0/src/isa/x64/lower.rs:1800:26

(note that the unreachable message is actually empty in the code, I have modified it locally to emit the unsupported opcode)

an unreachable case is hit instead.

Versions and Environment

Cranelift version or commit: 0.73.0

Operating system: Linux felix 5.11.15-arch1-2 #1 SMP PREEMPT Sat, 17 Apr 2021 00:22:30 +0000 x86_64 GNU/Linux

Architecture: x86_64

Extra Info

<details>
<summary>minimal, complete and verifiable example (mcve)</summary>

use cranelift_codegen::{binemit, ir::InstBuilder, Context};
use cranelift_codegen::{
    ir::{self, Signature},
    isa, settings, verify_function,
};
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use cranelift_module::{Linkage, Module};
use cranelift_object::{ObjectBuilder, ObjectModule};
use settings::FlagsOrIsa;

fn main() {
    let target_isa = isa::lookup(dbg!(target_lexicon::Triple::host()))
        .unwrap()
        .finish(settings::Flags::new(settings::builder()));

    let object_builder = ObjectBuilder::new(
        target_isa,
        "<empty>".to_string(),
        cranelift_module::default_libcall_names(),
    )
    .unwrap();

    let target_isa = isa::lookup(target_lexicon::Triple::host())
        .unwrap()
        .finish(settings::Flags::new(settings::builder()));

    let mut object_module = ObjectModule::new(object_builder);

    let mut sig = Signature::new(cranelift_codegen::isa::CallConv::SystemV);

    sig.returns.push(ir::AbiParam::new(ir::types::I64));

    let mut func = ir::Function::with_name_signature(
        ir::ExternalName::User {
            namespace: 0,
            index: 0,
        },
        sig,
    );

    let mut builder_ctx = FunctionBuilderContext::new();
    let mut builder = FunctionBuilder::new(&mut func, &mut builder_ctx);

    let b0 = builder.create_block();

    builder.switch_to_block(b0);

    let v1 = builder.ins().iconst(ir::types::I64, 1);
    let v2 = builder.ins().iconst(ir::types::I64, 1);

    let v3 = builder.ins().ssub_sat(v1, v2);

    builder.ins().return_(&[v3]);

    let fisa = FlagsOrIsa::from(&*target_isa);

    verify_function(&builder.func, fisa).unwrap();

    let fid = object_module
        .declare_function(&"main", Linkage::Export, &func.signature.clone())
        .unwrap();

    let mut ctx = Context::for_function(func);

    object_module
        .define_function(
            fid,
            &mut ctx,
            &mut binemit::NullTrapSink {},
            &mut binemit::NullStackMapSink {},
        )
        .unwrap();
}
[package]
name = "clif-usub"
version = "0.1.0"
edition = "2018"

[dependencies]
cranelift-codegen = "0.73.0"
cranelift-frontend = "0.73.0"
cranelift-object = "0.73.0"
cranelift-module = "0.73.0"
target-lexicon = "0.12.0"

</details>

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2021 at 13:54):

mental32 opened Issue #2883:

.clif Test Case

function u0:0() -> i64 system_v {
    block0:
        v0 = iconst.i64 1
        v1 = iconst.i64 1
        v2 = ssub_sat v0, v1
        return v2
}

Steps to Reproduce

Use ssub_sat with two I64 values and (at least for my case) use cranelift-object with a triple that looks like:

target_lexicon::Triple::host() = Triple {
    architecture: X86_64,
    vendor: Unknown,
    operating_system: Linux,
    environment: Gnu,
    binary_format: Elf,
}

Expected Results

The code should compile correctly and the function should return 0

Actual Results

thread 'main' panicked at 'internal error: entered unreachable code: SsubSat', /home/mental/.cargo/registry/src/github.com-1ecc6299db9ec823/cranelift-codegen-0.73.0/src/isa/x64/lower.rs:1800:26

(note that the unreachable message is actually empty in the code, I have modified it locally to emit the unsupported opcode)

an unreachable case is hit instead.

Versions and Environment

Cranelift version or commit: 0.73.0

Operating system: Linux felix 5.11.15-arch1-2 #1 SMP PREEMPT Sat, 17 Apr 2021 00:22:30 +0000 x86_64 GNU/Linux

Architecture: x86_64

Extra Info

<details>
<summary>minimal, complete and verifiable example (mcve)</summary>

use cranelift_codegen::{binemit, ir::InstBuilder, Context};
use cranelift_codegen::{
    ir::{self, Signature},
    isa, settings, verify_function,
};
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use cranelift_module::{Linkage, Module};
use cranelift_object::{ObjectBuilder, ObjectModule};
use settings::FlagsOrIsa;

fn main() {
    let target_isa = isa::lookup(dbg!(target_lexicon::Triple::host()))
        .unwrap()
        .finish(settings::Flags::new(settings::builder()));

    let object_builder = ObjectBuilder::new(
        target_isa,
        "<empty>".to_string(),
        cranelift_module::default_libcall_names(),
    )
    .unwrap();

    let target_isa = isa::lookup(target_lexicon::Triple::host())
        .unwrap()
        .finish(settings::Flags::new(settings::builder()));

    let mut object_module = ObjectModule::new(object_builder);

    let mut sig = Signature::new(cranelift_codegen::isa::CallConv::SystemV);

    sig.returns.push(ir::AbiParam::new(ir::types::I64));

    let mut func = ir::Function::with_name_signature(
        ir::ExternalName::User {
            namespace: 0,
            index: 0,
        },
        sig,
    );

    let mut builder_ctx = FunctionBuilderContext::new();
    let mut builder = FunctionBuilder::new(&mut func, &mut builder_ctx);

    let b0 = builder.create_block();

    builder.switch_to_block(b0);

    let v1 = builder.ins().iconst(ir::types::I64, 1);
    let v2 = builder.ins().iconst(ir::types::I64, 1);

    let v3 = builder.ins().ssub_sat(v1, v2);

    builder.ins().return_(&[v3]);

    let fisa = FlagsOrIsa::from(&*target_isa);

    verify_function(&builder.func, fisa).unwrap();

    let fid = object_module
        .declare_function(&"main", Linkage::Export, &func.signature.clone())
        .unwrap();

    let mut ctx = Context::for_function(func);

    object_module
        .define_function(
            fid,
            &mut ctx,
            &mut binemit::NullTrapSink {},
            &mut binemit::NullStackMapSink {},
        )
        .unwrap();
}
[package]
name = "clif-usub"
version = "0.1.0"
edition = "2018"

[dependencies]
cranelift-codegen = "0.73.0"
cranelift-frontend = "0.73.0"
cranelift-object = "0.73.0"
cranelift-module = "0.73.0"
target-lexicon = "0.12.0"

</details>

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2021 at 15:43):

abrown commented on Issue #2883:

If I remember correctly, ssub_sat was created solely to support Wasm SIMD's saturating instructions. I'm not sure why we allowed scalar values at the time, but the scalar lowering could be added, I suppose. @mental32, is a scalar ssub_sat an instruction you need? What for?

The alternative would be to limit what types are allowed to be used for ssub_sat--i.e., only allow vector types.

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2021 at 16:06):

mental32 commented on Issue #2883:

a scalar ssub_sat an instruction you need? What for?

Well... I wanted a signed integer subtraction that would saturate instead of wrapping on underflow but I was being lazy and thought to use Cranelift to do it for me instead of implementing it manually :smile:

I don't mind not being able to use it but in that case the docs for it are incorrect:
![image](https://user-images.githubusercontent.com/27660514/117477517-c1548980-af66-11eb-89b7-0936414b49c3.png)

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2021 at 16:08):

mental32 edited a comment on Issue #2883:

a scalar ssub_sat an instruction you need? What for?

Well... I wanted a signed integer subtraction that would saturate instead of wrapping on underflow but I was being lazy and thought to use Cranelift to do it for me instead of implementing it manually :smile:

I don't mind not being able to use it but in that case the docs for it are incorrect and misleading:
![image](https://user-images.githubusercontent.com/27660514/117477517-c1548980-af66-11eb-89b7-0936414b49c3.png)

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2021 at 16:44):

abrown commented on Issue #2883:

Yup, that should be fixed. I can pretty easily restrict the types of ssub_sat to just vectors which should fix the documentation and this issue but that doesn't really help you :grinning:. I haven't looked into it too much, but it looks like there are lowerings (e.g. here and here) that might work--if you're interested in implementing I'll be happy to review. Otherwise I'll probably default to restricting the types.


Last updated: Dec 23 2024 at 12:05 UTC