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
39 changes: 10 additions & 29 deletions cranelift/codegen/src/isa/aarch64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1200,35 +1200,16 @@

;;; Rules for integer min/max: umin, smin, umax, smax ;;;;;;;;;;;;;;;;;;;;;;;;;

;; `i64` and smaller.

;; cmp $x, $y
;; csel .., $x, $y, $cc
(attr cmp_and_choose (veri chain))
(decl cmp_and_choose (Type Cond bool Value Value) ValueRegs)
(rule (cmp_and_choose (fits_in_64 ty) cc _ x y)
(let ((x Reg (put_in_reg x))
(y Reg (put_in_reg y)))
(with_flags_reg (cmp (operand_size ty) x y)
(csel cc x y))))

;; `i16` and `i8` min/max require sign extension as
;; the comparison operates on (at least) 32 bits.
(attr rule cmp_and_choose_8_16 (veri priority))
(rule cmp_and_choose_8_16 1 (cmp_and_choose (fits_in_16 ty) cc signed x y)
(let ((x Reg (extend (put_in_reg x) signed (ty_bits ty) 32))
(y Reg (extend (put_in_reg y) signed (ty_bits ty) 32)))
(with_flags_reg (cmp (operand_size ty) x y)
(csel cc x y))))

(rule umin 2 (lower (umin (and (fits_in_64 ty) (ty_int _)) x y))
(cmp_and_choose ty (Cond.Lo) false x y))
(rule smin 2 (lower (smin (and (fits_in_64 ty) (ty_int _)) x y))
(cmp_and_choose ty (Cond.Lt) true x y))
(rule umax 2 (lower (umax (and (fits_in_64 ty) (ty_int _)) x y))
(cmp_and_choose ty (Cond.Hi) false x y))
(rule smax 2 (lower (smax (and (fits_in_64 ty) (ty_int _)) x y))
(cmp_and_choose ty (Cond.Gt) true x y))
;; Scalar integers.

(rule umin 2 (lower (umin (ty_int ty) x y))
(lower_select ty (emit_icmp (IntCC.UnsignedLessThan) x y) x y))
(rule smin 2 (lower (smin (ty_int ty) x y))
(lower_select ty (emit_icmp (IntCC.SignedLessThan) x y) x y))
(rule umax 2 (lower (umax (ty_int ty) x y))
(lower_select ty (emit_icmp (IntCC.UnsignedGreaterThan) x y) x y))
(rule smax 2 (lower (smax (ty_int ty) x y))
(lower_select ty (emit_icmp (IntCC.SignedGreaterThan) x y) x y))

;; Vector types.

Expand Down
8 changes: 4 additions & 4 deletions cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -2448,7 +2448,7 @@
;; TODO: could this perhaps be more optimal through inspection of the `fcsr`?
;; Unsure whether that needs to be preserved across function calls and/or would
;; cause other problems. Also unsure whether it's actually more performant.
(rule (lower (fcvt_to_uint ity v @ (value_type fty)))
(rule (lower (fcvt_to_uint (fits_in_64 ity) v @ (value_type fty)))
(let ((_ InstOutput (gen_trapif (cmp_eqz (rv_feq fty v v)) (TrapCode.BAD_CONVERSION_TO_INTEGER)))
(min FReg (imm fty (fcvt_umin_bound fty false)))
(_ InstOutput (gen_trapif (cmp_nez (rv_fle fty v min)) (TrapCode.INTEGER_OVERFLOW)))
Expand All @@ -2465,7 +2465,7 @@
;;;;; Rules for `fcvt_to_sint`;;;;;;;;;

;; NB: see above with `fcvt_to_uint` as this is similar
(rule (lower (fcvt_to_sint ity v @ (value_type fty)))
(rule (lower (fcvt_to_sint (fits_in_64 ity) v @ (value_type fty)))
(let ((_ InstOutput (gen_trapif (cmp_eqz (rv_feq fty v v)) (TrapCode.BAD_CONVERSION_TO_INTEGER)))
(min FReg (imm fty (fcvt_smin_bound fty ity false)))
(_ InstOutput (gen_trapif (cmp_nez (rv_fle fty v min)) (TrapCode.INTEGER_OVERFLOW)))
Expand All @@ -2481,7 +2481,7 @@

;;;;; Rules for `fcvt_to_sint_sat`;;;;;;;;;

(rule 0 (lower (fcvt_to_sint_sat to v @ (value_type (ty_supported_float_full from))))
(rule 0 (lower (fcvt_to_sint_sat (fits_in_64 to) v @ (value_type (ty_supported_float_full from))))
(handle_fcvt_to_int_nan from v (lower_fcvt_to_sint_sat from to v)))

;; Lowers to a `rv_fcvt*` instruction but handles 8/16-bit cases where the
Expand Down Expand Up @@ -2524,7 +2524,7 @@

;;;;; Rules for `fcvt_to_uint_sat`;;;;;;;;;

(rule 0 (lower (fcvt_to_uint_sat to v @ (value_type (ty_supported_float_full from))))
(rule 0 (lower (fcvt_to_uint_sat (fits_in_64 to) v @ (value_type (ty_supported_float_full from))))
(handle_fcvt_to_int_nan from v (lower_fcvt_to_uint_sat from to v)))

;; Lowers to a `rv_fcvt*` instruction but handles 8/16-bit cases where the
Expand Down
8 changes: 4 additions & 4 deletions cranelift/codegen/src/isa/x64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -3805,16 +3805,16 @@

;; Rules for `fcvt_to_uint` and `fcvt_to_sint` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (fcvt_to_uint out_ty val @ (value_type (ty_scalar_float _))))
(rule (lower (fcvt_to_uint (fits_in_64 out_ty) val @ (value_type (ty_scalar_float _))))
(cvt_float_to_uint_seq out_ty val false))

(rule (lower (fcvt_to_uint_sat out_ty val @ (value_type (ty_scalar_float _))))
(rule (lower (fcvt_to_uint_sat (fits_in_64 out_ty) val @ (value_type (ty_scalar_float _))))
(cvt_float_to_uint_seq out_ty val true))

(rule (lower (fcvt_to_sint out_ty val @ (value_type (ty_scalar_float _))))
(rule (lower (fcvt_to_sint (fits_in_64 out_ty) val @ (value_type (ty_scalar_float _))))
(cvt_float_to_sint_seq out_ty val false))

(rule (lower (fcvt_to_sint_sat out_ty val @ (value_type (ty_scalar_float _))))
(rule (lower (fcvt_to_sint_sat (fits_in_64 out_ty) val @ (value_type (ty_scalar_float _))))
(cvt_float_to_sint_seq out_ty val true))

;; The x64 backend currently only supports these two type combinations.
Expand Down
89 changes: 89 additions & 0 deletions cranelift/filetests/filetests/isa/aarch64/i128.clif
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,92 @@ block0(v0: i64, v1: i64):
; umulh x0, x0, x1
; ret


function %umin_i128(i128, i128) -> i128 {
block0(v0: i128, v1: i128):
v2 = umin v0, v1
return v2
}

; VCode:
; block0:
; subs xzr, x0, x2
; sbcs xzr, x1, x3
; csel x0, x0, x2, lo
; csel x1, x1, x3, lo
; ret
;
; Disassembled:
; block0: ; offset 0x0
; cmp x0, x2
; sbcs xzr, x1, x3
; csel x0, x0, x2, lo
; csel x1, x1, x3, lo
; ret

function %umax_i128(i128, i128) -> i128 {
block0(v0: i128, v1: i128):
v2 = umax v0, v1
return v2
}

; VCode:
; block0:
; subs xzr, x2, x0
; sbcs xzr, x3, x1
; csel x0, x0, x2, lo
; csel x1, x1, x3, lo
; ret
;
; Disassembled:
; block0: ; offset 0x0
; cmp x2, x0
; sbcs xzr, x3, x1
; csel x0, x0, x2, lo
; csel x1, x1, x3, lo
; ret

function %smin_i128(i128, i128) -> i128 {
block0(v0: i128, v1: i128):
v2 = smin v0, v1
return v2
}

; VCode:
; block0:
; subs xzr, x0, x2
; sbcs xzr, x1, x3
; csel x0, x0, x2, lt
; csel x1, x1, x3, lt
; ret
;
; Disassembled:
; block0: ; offset 0x0
; cmp x0, x2
; sbcs xzr, x1, x3
; csel x0, x0, x2, lt
; csel x1, x1, x3, lt
; ret

function %smax_i128(i128, i128) -> i128 {
block0(v0: i128, v1: i128):
v2 = smax v0, v1
return v2
}

; VCode:
; block0:
; subs xzr, x2, x0
; sbcs xzr, x3, x1
; csel x0, x0, x2, lt
; csel x1, x1, x3, lt
; ret
;
; Disassembled:
; block0: ; offset 0x0
; cmp x2, x0
; sbcs xzr, x3, x1
; csel x0, x0, x2, lt
; csel x1, x1, x3, lt
; ret

164 changes: 164 additions & 0 deletions cranelift/filetests/filetests/isa/aarch64/minmax.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
test compile precise-output
set opt_level=speed
target aarch64

function %umin_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = umin v0, v1
return v2
}

; VCode:
; block0:
; uxtb w3, w0
; subs wzr, w3, w1, UXTB
; csel x0, x0, x1, lo
; ret
;
; Disassembled:
; block0: ; offset 0x0
; uxtb w3, w0
; cmp w3, w1, uxtb
; csel x0, x0, x1, lo
; ret

function %smin_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = smin v0, v1
return v2
}

; VCode:
; block0:
; sxtb w3, w0
; subs wzr, w3, w1, SXTB
; csel x0, x0, x1, lt
; ret
;
; Disassembled:
; block0: ; offset 0x0
; sxtb w3, w0
; cmp w3, w1, sxtb
; csel x0, x0, x1, lt
; ret

function %umax_i16(i16, i16) -> i16 {
block0(v0: i16, v1: i16):
v2 = umax v0, v1
return v2
}

; VCode:
; block0:
; uxth w3, w0
; subs wzr, w3, w1, UXTH
; csel x0, x0, x1, hi
; ret
;
; Disassembled:
; block0: ; offset 0x0
; uxth w3, w0
; cmp w3, w1, uxth
; csel x0, x0, x1, hi
; ret

function %smax_i16(i16, i16) -> i16 {
block0(v0: i16, v1: i16):
v2 = smax v0, v1
return v2
}

; VCode:
; block0:
; sxth w3, w0
; subs wzr, w3, w1, SXTH
; csel x0, x0, x1, gt
; ret
;
; Disassembled:
; block0: ; offset 0x0
; sxth w3, w0
; cmp w3, w1, sxth
; csel x0, x0, x1, gt
; ret

function %umin_i8_imm(i8) -> i8 {
block0(v0: i8):
v1 = iconst.i8 100
v2 = umin v0, v1
return v2
}

; VCode:
; block0:
; movz w4, #100
; uxtb w3, w0
; subs wzr, w3, #100
; csel x0, x0, x4, lo
; ret
;
; Disassembled:
; block0: ; offset 0x0
; mov w4, #0x64
; uxtb w3, w0
; cmp w3, #0x64
; csel x0, x0, x4, lo
; ret

function %umin_i32(i32, i32) -> i32 {
block0(v0: i32, v1: i32):
v2 = umin v0, v1
return v2
}

; VCode:
; block0:
; subs wzr, w0, w1
; csel x0, x0, x1, lo
; ret
;
; Disassembled:
; block0: ; offset 0x0
; cmp w0, w1
; csel x0, x0, x1, lo
; ret

function %smax_i64(i64, i64) -> i64 {
block0(v0: i64, v1: i64):
v2 = smax v0, v1
return v2
}

; VCode:
; block0:
; subs xzr, x0, x1
; csel x0, x0, x1, gt
; ret
;
; Disassembled:
; block0: ; offset 0x0
; cmp x0, x1
; csel x0, x0, x1, gt
; ret

function %smax_i64_imm(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 5
v2 = smax v0, v1
return v2
}

; VCode:
; block0:
; movz x3, #5
; subs xzr, x0, #5
; csel x0, x0, x3, gt
; ret
;
; Disassembled:
; block0: ; offset 0x0
; mov x3, #5
; cmp x0, #5
; csel x0, x0, x3, gt
; ret

1 change: 1 addition & 0 deletions cranelift/filetests/filetests/runtests/i128-min-max.clif
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
test interpret
test run
target aarch64
target riscv64
target riscv64 has_c has_zcb
set enable_multi_ret_implicit_sret
Expand Down
Loading