bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.44k stars 1.3k forks source link

Does rotl support the vector floating point number? #9645

Closed abc767234318 closed 4 days ago

abc767234318 commented 4 days ago

I found the rotl instruction is defined as follows:

    /// Rotate left.
    ///
    /// Rotate the bits in ``x`` by ``y`` places.
    ///
    /// Inputs:
    ///
    /// - x: Scalar or vector value to shift
    /// - y: Number of bits to shift
    ///
    /// Outputs:
    ///
    /// - a: A scalar or vector integer type
    #[allow(non_snake_case)]
    fn rotl(self, x: ir::Value, y: ir::Value) -> Value {
        let ctrl_typevar = self.data_flow_graph().value_type(x);
        let (inst, dfg) = self.Binary(Opcode::Rotl, ctrl_typevar, x, y);
        dfg.first_result(inst)
    }

It seems that it can accept any vector type as its argument x. But I get the following error:

 ERROR cranelift_filetests::concurrent > FAIL: failed to parse file_tests/multi_func.clif
FAIL file_tests/multi_func.clif: failed to parse file_tests/multi_func.clif

Caused by:
    54: f32x4 is not a valid typevar for rotl
1 tests
Error: 1 failure
cfallin commented 4 days ago

f32x4 is not a valid typevar for rotl

This is the canonical answer -- the validator and all of the other infrastructure related to the CLIF instruction definitions comes from a single DSL where we define which types each instruction accepts, and there we have defined that rotl takes only integer types -- and so it is.

We certainly could choose to implement rotates for floats as well, but we'd probably do so in the backends by bitcasting to ints and reusing existing implementations, so it wouldn't really be any more efficient than what you can do in CLIF today. So I'd recommend building this out of two bitcasts and an integer rotl instead.

abc767234318 commented 4 days ago

f32x4 is not a valid typevar for rotl

This is the canonical answer -- the validator and all of the other infrastructure related to the CLIF instruction definitions comes from a single DSL where we define which types each instruction accepts, and there we have defined that rotl takes only integer types -- and so it is.

We certainly could choose to implement rotates for floats as well, but we'd probably do so in the backends by bitcasting to ints and reusing existing implementations, so it wouldn't really be any more efficient than what you can do in CLIF today. So I'd recommend building this out of two bitcasts and an integer rotl instead.

Would you consider modifying the description of the document? Because in the description of my other instructions, if vector defines a certain type, it will be declared. Such as:

/// Signed integer minimum.
    ///
    /// Inputs:
    ///
    /// - x: A scalar or vector integer type
    /// - y: A scalar or vector integer type
    ///
    /// Outputs:
    ///
    /// - a: A scalar or vector integer type
    #[allow(non_snake_case)]
    fn smin(self, x: ir::Value, y: ir::Value) -> Value {
        let ctrl_typevar = self.data_flow_graph().value_type(x);
        let (inst, dfg) = self.Binary(Opcode::Smin, ctrl_typevar, x, y);
        dfg.first_result(inst)
    }

/// Floating point addition.
    ///
    /// Inputs:
    ///
    /// - x: A scalar or vector floating point number
    /// - y: A scalar or vector floating point number
    ///
    /// Outputs:
    ///
    /// - a: Result of applying operator to each lane
    #[allow(non_snake_case)]
    fn fadd(self, x: ir::Value, y: ir::Value) -> Value {
        let ctrl_typevar = self.data_flow_graph().value_type(x);
        let (inst, dfg) = self.Binary(Opcode::Fadd, ctrl_typevar, x, y);
        dfg.first_result(inst)
    }
cfallin commented 4 days ago

Sure, happy to review a PR!