Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 34 additions & 38 deletions cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -329,111 +329,107 @@
(if-let imm12_neg (imm12_from_negated_value y))
(alu_rr_imm12 (select_addi ty) x imm12_neg))

(rule 4 (lower (has_type (ty_int_ref_scalar_64 ty) (isub x y)))
(if-let imm12_neg (imm12_from_negated_value x))
(alu_rr_imm12 (select_addi ty) y imm12_neg))

;; SIMD Vectors
(rule 5 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
(rule 4 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
(rv_vsub_vv x y (unmasked) ty))

(rule 6 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat y))))
(rule 5 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat y))))
(rv_vsub_vx x y (unmasked) ty))

(rule 7 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (sextend y @ (value_type sext_ty))))))
(rule 6 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (sextend y @ (value_type sext_ty))))))
(if-let half_ty (ty_half_width ty))
(if-let $true (ty_equal (lane_type half_ty) sext_ty))
(rv_vwsub_wx x y (unmasked) (vstate_mf2 half_ty)))

(rule 7 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (uextend y @ (value_type uext_ty))))))
(rule 6 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (uextend y @ (value_type uext_ty))))))
(if-let half_ty (ty_half_width ty))
(if-let $true (ty_equal (lane_type half_ty) uext_ty))
(rv_vwsubu_wx x y (unmasked) (vstate_mf2 half_ty)))

(rule 8 (lower (has_type (ty_vec_fits_in_register ty) (isub (splat x) y)))
(rule 7 (lower (has_type (ty_vec_fits_in_register ty) (isub (splat x) y)))
(rv_vrsub_vx y x (unmasked) ty))

(rule 9 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
(rule 8 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
(if-let x_imm (replicated_imm5 x))
(rv_vrsub_vi y x_imm (unmasked) ty))


;; Signed Widening Low Subtractions

(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_low y @ (value_type in_ty)))))
(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_low y @ (value_type in_ty)))))
(rv_vwsub_wv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
(swiden_low y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
(swiden_low y))))
(rv_vwsub_vv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
(splat (sextend y @ (value_type sext_ty))))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
(splat (sextend y @ (value_type sext_ty))))))
(if-let $true (ty_equal (lane_type in_ty) sext_ty))
(rv_vwsub_vx x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

;; Signed Widening High Subtractions
;; These are the same as the low widenings, but we first slide down the inputs.

(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_high y @ (value_type in_ty)))))
(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_high y @ (value_type in_ty)))))
(rv_vwsub_wv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
(swiden_high y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
(swiden_high y))))
(rv_vwsub_vv (gen_slidedown_half in_ty x) (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
(splat (sextend y @ (value_type sext_ty))))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
(splat (sextend y @ (value_type sext_ty))))))
(if-let $true (ty_equal (lane_type in_ty) sext_ty))
(rv_vwsub_vx (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

;; Unsigned Widening Low Subtractions

(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_low y @ (value_type in_ty)))))
(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_low y @ (value_type in_ty)))))
(rv_vwsubu_wv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
(uwiden_low y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
(uwiden_low y))))
(rv_vwsubu_vv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
(splat (uextend y @ (value_type uext_ty))))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
(splat (uextend y @ (value_type uext_ty))))))
(if-let $true (ty_equal (lane_type in_ty) uext_ty))
(rv_vwsubu_vx x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

;; Unsigned Widening High Subtractions
;; These are the same as the low widenings, but we first slide down the inputs.

(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_high y @ (value_type in_ty)))))
(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_high y @ (value_type in_ty)))))
(rv_vwsubu_wv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
(uwiden_high y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
(uwiden_high y))))
(rv_vwsubu_vv (gen_slidedown_half in_ty x) (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
(splat (uextend y @ (value_type uext_ty))))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
(splat (uextend y @ (value_type uext_ty))))))
(if-let $true (ty_equal (lane_type in_ty) uext_ty))
(rv_vwsubu_vx (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

;; Signed Widening Mixed High/Low Subtractions

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
(swiden_high y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
(swiden_high y))))
(rv_vwsub_vv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
(swiden_low y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
(swiden_low y))))
(rv_vwsub_vv (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

;; Unsigned Widening Mixed High/Low Subtractions

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
(uwiden_high y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
(uwiden_high y))))
(rv_vwsubu_vv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
(uwiden_low y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
(uwiden_low y))))
(rv_vwsubu_vv (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))


Expand Down
8 changes: 8 additions & 0 deletions cranelift/filetests/filetests/runtests/arithmetic.clif
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ block0(v0: i8,v1: i8):
; run: %sub_i8(0xAB, 0x0B) == 0xA0
; run: %sub_i8(0xC0, 0xDE) == 0xE2

function %isub_const_lhs(i8, i32) -> i32 {
block0(v0: i8, v1: i32):
v376 = iconst.i32 0xffff_fffd
v1161 = isub v376, v1
return v1161
}

; run: %isub_const_lhs(68, 4474) == -4477

function %mul_i64(i64, i64) -> i64 {
block0(v0: i64,v1: i64):
Expand Down
17 changes: 16 additions & 1 deletion crates/test-programs/src/bin/api_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,22 @@ use bindings::wasi::http::types::{IncomingRequest, ResponseOutparam};
struct T;

impl bindings::exports::wasi::http::incoming_handler::Guest for T {
fn handle(_request: IncomingRequest, outparam: ResponseOutparam) {
fn handle(request: IncomingRequest, outparam: ResponseOutparam) {
let header = String::from("custom-forbidden-header");
let req_hdrs = request.headers();

assert!(
!req_hdrs.get(&header).is_empty(),
"missing `custom-forbidden-header` from request"
);

assert!(req_hdrs.delete(&header).is_err());

assert!(
!req_hdrs.get(&header).is_empty(),
"delete of forbidden header succeeded"
);

let hdrs = bindings::wasi::http::types::Headers::new();
let resp = bindings::wasi::http::types::OutgoingResponse::new(hdrs);
let body = resp.body().expect("outgoing response");
Expand Down
14 changes: 11 additions & 3 deletions crates/wasi-http/src/types_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,23 @@ impl<T: WasiHttpView> crate::bindings::http::types::HostFields for T {
Ok(Ok(()))
}

fn delete(&mut self, fields: Resource<HostFields>, name: String) -> wasmtime::Result<()> {
fn delete(
&mut self,
fields: Resource<HostFields>,
name: String,
) -> wasmtime::Result<Result<(), types::HeaderError>> {
let header = match hyper::header::HeaderName::from_bytes(name.as_bytes()) {
Ok(header) => header,
Err(_) => return Ok(()),
Err(_) => return Ok(Err(types::HeaderError::InvalidSyntax)),
};

if is_forbidden_header(self, &header) {
return Ok(Err(types::HeaderError::Forbidden));
}

let m = get_fields_mut(self.table(), &fields)?;
m.remove(header);
Ok(())
Ok(Ok(()))
}

fn append(
Expand Down
15 changes: 11 additions & 4 deletions crates/wasi-http/tests/all/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,18 @@ async fn run_wasi_http(

#[test_log::test(tokio::test)]
async fn wasi_http_proxy_tests() -> anyhow::Result<()> {
let req = hyper::Request::builder()
.method(http::Method::GET)
.body(body::empty())?;
let mut req = hyper::Request::builder().method(http::Method::GET);

let resp = run_wasi_http(test_programs_artifacts::API_PROXY_COMPONENT, req, None).await?;
req.headers_mut()
.unwrap()
.append("custom-forbidden-header", "yes".parse().unwrap());

let resp = run_wasi_http(
test_programs_artifacts::API_PROXY_COMPONENT,
req.body(body::empty())?,
None,
)
.await?;

match resp {
Ok(resp) => println!("response: {resp:?}"),
Expand Down
6 changes: 3 additions & 3 deletions crates/wasi-http/wit/deps/http/types.wit
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ interface types {
set: func(name: field-key, value: list<field-value>) -> result<_, header-error>;

/// Delete all values for a key. Does nothing if no values for the key
/// exist.
delete: func(name: field-key);
/// exist. Returns and error if the `field-key` is syntactically invalid, or
/// if the `field-key` is forbidden.
delete: func(name: field-key) -> result<_, header-error>;

/// Append a value for a key. Does not change or delete any existing
/// values for that key.
Expand All @@ -98,7 +99,6 @@ interface types {
/// the name is forbidden.
append: func(name: field-key, value: field-value) -> result<_, header-error>;


/// Retrieve the full set of keys and values in the Fields. Like the
/// constructor, the list represents each key-value pair.
///
Expand Down
6 changes: 3 additions & 3 deletions crates/wasi/wit/deps/http/types.wit
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ interface types {
set: func(name: field-key, value: list<field-value>) -> result<_, header-error>;

/// Delete all values for a key. Does nothing if no values for the key
/// exist.
delete: func(name: field-key);
/// exist. Returns and error if the `field-key` is syntactically invalid, or
/// if the `field-key` is forbidden.
delete: func(name: field-key) -> result<_, header-error>;

/// Append a value for a key. Does not change or delete any existing
/// values for that key.
Expand All @@ -98,7 +99,6 @@ interface types {
/// the name is forbidden.
append: func(name: field-key, value: field-value) -> result<_, header-error>;


/// Retrieve the full set of keys and values in the Fields. Like the
/// constructor, the list represents each key-value pair.
///
Expand Down