Skip to content

Commit

Permalink
pulley: Run many existing *.clif runtests
Browse files Browse the repository at this point in the history
This commit adds the pulley targets to many of the preexisting `*.clif`
runtests throughout the tree. This covers most of the MVP functionality
of wasm for example and additionally exercises 8 and 16-bit lowerings
for many instructions. A few minor pulley instructions were added and
otherwise new 8/16-bit lowerings use existing instructions. It's
expected that the 8/16-bit lowerings won't be used all that often so
they're not particularly optimal at this time.

Some CLIF tests were omitted such as:

* Most SIMD-using CLIF tests
* Float/int conversion tests using 8 and 16-bit integers
* Tests with `call` instructions as relocations don't work with the JIT
  crate on Pulley
* Tests using 128-bit integers

Support for some of these tests may be enabled in the future, but for
example 8/16-bit integers may not get used much.
  • Loading branch information
alexcrichton committed Dec 14, 2024
1 parent 128decd commit 6a1b4ac
Show file tree
Hide file tree
Showing 79 changed files with 732 additions and 161 deletions.
6 changes: 4 additions & 2 deletions cranelift/codegen/src/isa/pulley_shared/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,10 @@ where
Inst::gen_load(into_reg, mem, ty, MemFlags::trusted()).into()
}

fn gen_store_base_offset(_base: Reg, _offset: i32, _from_reg: Reg, _ty: Type) -> Self::I {
todo!()
fn gen_store_base_offset(base: Reg, offset: i32, from_reg: Reg, ty: Type) -> Self::I {
let base = XReg::try_from(base).unwrap();
let mem = Amode::RegOffset { base, offset };
Inst::gen_store(mem, from_reg, ty, MemFlags::trusted()).into()
}

fn gen_sp_reg_adjust(amount: i32) -> SmallInstVec<Self::I> {
Expand Down
30 changes: 30 additions & 0 deletions cranelift/codegen/src/isa/pulley_shared/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -435,3 +435,33 @@

(decl gen_call_indirect (SigRef Value ValueSlice) InstOutput)
(extern constructor gen_call_indirect gen_call_indirect)

;;;; Helpers for Sign extension ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Sign extend a `Value` to at least 32-bit
(decl zext32 (Value) XReg)
(rule (zext32 val @ (value_type $I8)) (pulley_zext8 val))
(rule (zext32 val @ (value_type $I16)) (pulley_zext16 val))
(rule (zext32 val @ (value_type $I32)) val)
(rule (zext32 val @ (value_type $I64)) val)

;; Same as `zext32` but for sign-extension
(decl sext32 (Value) XReg)
(rule (sext32 val @ (value_type $I8)) (pulley_sext8 val))
(rule (sext32 val @ (value_type $I16)) (pulley_sext16 val))
(rule (sext32 val @ (value_type $I32)) val)
(rule (sext32 val @ (value_type $I64)) val)

;; Sign extend a `Value` to at least 64-bit
(decl zext64 (Value) XReg)
(rule (zext64 val @ (value_type $I8)) (pulley_zext8 val))
(rule (zext64 val @ (value_type $I16)) (pulley_zext16 val))
(rule (zext64 val @ (value_type $I32)) (pulley_zext32 val))
(rule (zext64 val @ (value_type $I64)) val)

;; Same as `zext64` but for sign-extension
(decl sext64 (Value) XReg)
(rule (sext64 val @ (value_type $I8)) (pulley_sext8 val))
(rule (sext64 val @ (value_type $I16)) (pulley_sext16 val))
(rule (sext64 val @ (value_type $I32)) (pulley_sext32 val))
(rule (sext64 val @ (value_type $I64)) val)
157 changes: 102 additions & 55 deletions cranelift/codegen/src/isa/pulley_shared/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@
;; comparison must be made. Additionally if `Value` is smaller than 32-bits
;; then it must be sign-extended up to at least 32 bits.
(decl lower_cond (Value) Cond)
(rule (lower_cond val @ (value_type $I64))
(rule 0 (lower_cond val @ (value_type (fits_in_32 _))) (Cond.If32 (zext32 val)))
(rule 1 (lower_cond val @ (value_type $I64))
(Cond.IfXneq64 val (pulley_xconst8 0)))
(rule (lower_cond val @ (value_type $I32)) (Cond.If32 val))
(rule (lower_cond val @ (value_type $I16)) (Cond.If32 (pulley_zext16 val)))
(rule (lower_cond val @ (value_type $I8)) (Cond.If32 (pulley_zext8 val)))

;; Peel away explicit `uextend` values to take a look at the inner value.
(rule 1 (lower_cond (uextend val)) (lower_cond val))
(rule 2 (lower_cond (uextend val)) (lower_cond val))
;; Conditional branches on `icmp`s.
(rule 1 (lower_cond (icmp cc a b @ (value_type $I32))) (lower_cond_icmp32 cc a b))
(rule 1 (lower_cond (icmp cc a b @ (value_type $I64))) (lower_cond_icmp64 cc a b))
(rule 2 (lower_cond (icmp cc a b @ (value_type $I32))) (lower_cond_icmp32 cc a b))
(rule 2 (lower_cond (icmp cc a b @ (value_type $I64))) (lower_cond_icmp64 cc a b))

(decl lower_cond_icmp32 (IntCC Value Value) Cond)
(rule (lower_cond_icmp32 (IntCC.Equal) a b) (Cond.IfXeq32 a b))
Expand Down Expand Up @@ -171,26 +169,36 @@

;;;; Rules for `sdiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (sdiv a b))) (pulley_xdiv32_s a b))
(rule (lower (has_type $I64 (sdiv a b))) (pulley_xdiv64_s a b))
(rule 0 (lower (has_type (fits_in_32 _) (sdiv a b)))
(pulley_xdiv32_s (sext32 a) (sext32 b)))
(rule 1 (lower (has_type $I64 (sdiv a b))) (pulley_xdiv64_s a b))

;;;; Rules for `srem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (srem a b))) (pulley_xrem32_s a b))
(rule (lower (has_type $I64 (srem a b))) (pulley_xrem64_s a b))
(rule 0 (lower (has_type (fits_in_32 _) (srem a b)))
(pulley_xrem32_s (sext32 a) (sext32 b)))
(rule 1 (lower (has_type $I64 (srem a b))) (pulley_xrem64_s a b))

;;;; Rules for `udiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (udiv a b))) (pulley_xdiv32_u a b))
(rule (lower (has_type $I64 (udiv a b))) (pulley_xdiv64_u a b))
(rule 0 (lower (has_type (ty_int (fits_in_32 _)) (udiv a b)))
(pulley_xdiv32_u (zext32 a) (zext32 b)))
(rule 1 (lower (has_type $I64 (udiv a b))) (pulley_xdiv64_u a b))

;;;; Rules for `urem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (urem a b))) (pulley_xrem32_u a b))
(rule (lower (has_type $I64 (urem a b))) (pulley_xrem64_u a b))
(rule 0 (lower (has_type (ty_int (fits_in_32 _)) (urem a b)))
(pulley_xrem32_u (zext32 a) (zext32 b)))
(rule 1 (lower (has_type $I64 (urem a b))) (pulley_xrem64_u a b))

;;;; Rules for `ishl` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I8 (ishl a b)))
(pulley_xshl32 a (pulley_xband32 b (pulley_xconst8 7))))

(rule (lower (has_type $I16 (ishl a b)))
(pulley_xshl32 a (pulley_xband32 b (pulley_xconst8 15))))

(rule (lower (has_type $I32 (ishl a b)))
(pulley_xshl32 a b))

Expand All @@ -204,6 +212,12 @@

;;;; Rules for `ushr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I8 (ushr a b)))
(pulley_xshr32_u (zext32 a) (pulley_xband32 b (pulley_xconst8 7))))

(rule (lower (has_type $I16 (ushr a b)))
(pulley_xshr32_u (zext32 a) (pulley_xband32 b (pulley_xconst8 15))))

(rule (lower (has_type $I32 (ushr a b)))
(pulley_xshr32_u a b))

Expand All @@ -217,6 +231,12 @@

;;;; Rules for `sshr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I8 (sshr a b)))
(pulley_xshr32_u (sext32 a) (pulley_xband32 b (pulley_xconst8 7))))

(rule (lower (has_type $I16 (sshr a b)))
(pulley_xshr32_u (sext32 a) (pulley_xband32 b (pulley_xconst8 15))))

(rule (lower (has_type $I32 (sshr a b)))
(pulley_xshr32_s a b))

Expand Down Expand Up @@ -262,38 +282,50 @@

;;;; Rules for `umin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (umin a b))) (pulley_xmin32_u a b))
(rule (lower (has_type $I64 (umin a b))) (pulley_xmin64_u a b))
(rule 0 (lower (has_type (fits_in_32 _) (umin a b)))
(pulley_xmin32_u (zext32 a) (zext32 b)))
(rule 1 (lower (has_type $I64 (umin a b))) (pulley_xmin64_u a b))

;;;; Rules for `smin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (smin a b))) (pulley_xmin32_s a b))
(rule (lower (has_type $I64 (smin a b))) (pulley_xmin64_s a b))
(rule 0 (lower (has_type (fits_in_32 _) (smin a b)))
(pulley_xmin32_s (sext32 a) (sext32 b)))
(rule 1 (lower (has_type $I64 (smin a b))) (pulley_xmin64_s a b))

;;;; Rules for `umax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (umax a b))) (pulley_xmax32_u a b))
(rule (lower (has_type $I64 (umax a b))) (pulley_xmax64_u a b))
(rule 0 (lower (has_type (fits_in_32 _) (umax a b)))
(pulley_xmax32_u (zext32 a) (zext32 b)))
(rule 1 (lower (has_type $I64 (umax a b))) (pulley_xmax64_u a b))

;;;; Rules for `smax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (smax a b))) (pulley_xmax32_s a b))
(rule (lower (has_type $I64 (smax a b))) (pulley_xmax64_s a b))
(rule 0 (lower (has_type (fits_in_32 _) (smax a b)))
(pulley_xmax32_s (sext32 a) (sext32 b)))
(rule 1 (lower (has_type $I64 (smax a b))) (pulley_xmax64_s a b))

;;;; Rules for `ctz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I8 (ctz a)))
(pulley_xctz32 (pulley_xbor32 a (pulley_xconst16 0x100))))
(rule (lower (has_type $I16 (ctz a)))
(pulley_xctz32 (pulley_xbor32 a (pulley_xconst32 0x10000))))
(rule (lower (has_type $I32 (ctz a))) (pulley_xctz32 a))
(rule (lower (has_type $I64 (ctz a))) (pulley_xctz64 a))

;;;; Rules for `clz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I8 (clz a)))
(pulley_xsub32 (pulley_xclz32 (zext32 a)) (pulley_xconst8 24)))
(rule (lower (has_type $I16 (clz a)))
(pulley_xsub32 (pulley_xclz32 (zext32 a)) (pulley_xconst8 16)))
(rule (lower (has_type $I32 (clz a))) (pulley_xclz32 a))
(rule (lower (has_type $I64 (clz a))) (pulley_xclz64 a))

;;;; Rules for `popcnt` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (popcnt a))) (pulley_xpopcnt32 a))
(rule (lower (has_type $I64 (popcnt a))) (pulley_xpopcnt64 a))
(rule 0 (lower (has_type (fits_in_32 _) (popcnt a))) (pulley_xpopcnt32 (zext32 a)))
(rule 1 (lower (has_type $I64 (popcnt a))) (pulley_xpopcnt64 a))

;;;; Rules for `rotl` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand All @@ -309,8 +341,8 @@

(rule 1 (lower (icmp cc a b @ (value_type $I64)))
(lower_icmp $I64 cc a b))
(rule (lower (icmp cc a b @ (value_type (fits_in_32 _))))
(lower_icmp $I32 cc a b))
(rule (lower (icmp cc a b @ (value_type (ty_int (fits_in_32 ty)))))
(lower_icmp ty cc a b))

(decl lower_icmp (Type IntCC Value Value) XReg)

Expand All @@ -332,23 +364,23 @@
(rule (lower_icmp $I64 (IntCC.UnsignedLessThanOrEqual) a b)
(pulley_xulteq64 a b))

(rule (lower_icmp $I32 (IntCC.Equal) a b)
(pulley_xeq32 a b))
(rule 1 (lower_icmp (fits_in_32 _) (IntCC.Equal) a b)
(pulley_xeq32 (zext32 a) (zext32 b)))

(rule (lower_icmp $I32 (IntCC.NotEqual) a b)
(pulley_xneq32 a b))
(rule 1 (lower_icmp (fits_in_32 _) (IntCC.NotEqual) a b)
(pulley_xneq32 (zext32 a) (zext32 b)))

(rule (lower_icmp $I32 (IntCC.SignedLessThan) a b)
(pulley_xslt32 a b))
(rule 1 (lower_icmp (fits_in_32 _) (IntCC.SignedLessThan) a b)
(pulley_xslt32 (sext32 a) (sext32 b)))

(rule (lower_icmp $I32 (IntCC.SignedLessThanOrEqual) a b)
(pulley_xslteq32 a b))
(rule 1 (lower_icmp (fits_in_32 _) (IntCC.SignedLessThanOrEqual) a b)
(pulley_xslteq32 (sext32 a) (sext32 b)))

(rule (lower_icmp $I32 (IntCC.UnsignedLessThan) a b)
(pulley_xult32 a b))
(rule 1 (lower_icmp (fits_in_32 _) (IntCC.UnsignedLessThan) a b)
(pulley_xult32 (zext32 a) (zext32 b)))

(rule (lower_icmp $I32 (IntCC.UnsignedLessThanOrEqual) a b)
(pulley_xulteq32 a b))
(rule 1 (lower_icmp (fits_in_32 _) (IntCC.UnsignedLessThanOrEqual) a b)
(pulley_xulteq32 (zext32 a) (zext32 b)))

;; Pulley doesn't have instructions for `>` and `>=`, so we have to reverse the
;; operation.
Expand Down Expand Up @@ -470,25 +502,19 @@

;;;; Rules for `uextend` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type (fits_in_64 _) (uextend val @ (value_type $I32))))
(pulley_zext32 val))
(rule 0 (lower (has_type (fits_in_32 _) (uextend val)))
(zext32 val))

(rule (lower (has_type (fits_in_64 _) (uextend val @ (value_type $I16))))
(pulley_zext16 val))

(rule (lower (has_type (fits_in_64 _) (uextend val @ (value_type $I8))))
(pulley_zext8 val))
(rule 1 (lower (has_type $I64 (uextend val)))
(zext64 val))

;;;; Rules for `sextend` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type (fits_in_64 _) (sextend val @ (value_type $I8))))
(pulley_sext8 val))

(rule (lower (has_type (fits_in_64 _) (sextend val @ (value_type $I16))))
(pulley_sext16 val))
(rule 0 (lower (has_type (fits_in_32 _) (sextend val)))
(sext32 val))

(rule (lower (has_type (fits_in_64 _) (sextend val @ (value_type $I32))))
(pulley_sext32 val))
(rule 1 (lower (has_type $I64 (sextend val)))
(sext64 val))

;;;; Rules for `ireduce` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down Expand Up @@ -551,6 +577,8 @@
(rule 1 (lower (has_type (ty_vec128 _) (bitcast _flags val @ (value_type (ty_vec128 _)))))
val)

(rule 2 (lower (has_type ty (bitcast _flags a @ (value_type ty)))) a)

;;;; Rules for `fcvt_to_{u,s}int` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (fcvt_to_uint val @ (value_type $F32))))
Expand Down Expand Up @@ -711,8 +739,8 @@

;;;; Rules for `ineg` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I32 (ineg a))) (pulley_xneg32 a))
(rule (lower (has_type $I64 (ineg a))) (pulley_xneg64 a))
(rule 0 (lower (has_type (fits_in_32 _) (ineg a))) (pulley_xneg32 (sext32 a)))
(rule 1 (lower (has_type $I64 (ineg a))) (pulley_xneg64 a))

;;;; Rules for `fabs` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand All @@ -722,3 +750,22 @@
;;;; Rules for `vconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type (ty_vec128 _) (vconst (u128_from_constant a)))) (pulley_vconst128 a))

;;;; Rules for `bmask` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule 0 (lower (has_type (ty_int (fits_in_32 _)) (bmask a)))
(pulley_xbmask32 (zext32 a)))
(rule 1 (lower (has_type $I64 (bmask a)))
(pulley_xbmask64 (zext64 a)))

;;;; Rules for `bswap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type $I16 (bswap a)))
(pulley_xshr32_u (pulley_bswap32 a) (pulley_xconst8 16)))
(rule (lower (has_type $I32 (bswap a))) (pulley_bswap32 a))
(rule (lower (has_type $I64 (bswap a))) (pulley_bswap64 a))

;;;; Rules for `iabs` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule 0 (lower (has_type (fits_in_32 _) (iabs a))) (pulley_xabs32 (sext32 a)))
(rule 1 (lower (has_type $I64 (iabs a))) (pulley_xabs64 a))
32 changes: 20 additions & 12 deletions cranelift/filetests/filetests/isa/pulley32/brif.clif
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,11 @@ block2:

; VCode:
; block0:
; xeq32 x6, x0, x1
; zext8 x6, x6
; br_if32 x6, label2; jump label1
; zext8 x6, x0
; zext8 x8, x1
; xeq32 x10, x6, x8
; zext8 x8, x10
; br_if32 x8, label2; jump label1
; block1:
; xconst8 x0, 0
; ret
Expand All @@ -154,9 +156,11 @@ block2:
; ret
;
; Disassembled:
; xeq32 x6, x0, x1
; zext8 x6, x6
; br_if32 x6, 0xa // target = 0x10
; zext8 x6, x0
; zext8 x8, x1
; xeq32 x10, x6, x8
; zext8 x8, x10
; br_if32 x8, 0xa // target = 0x16
; xconst8 x0, 0
; ret
; xconst8 x0, 1
Expand All @@ -178,9 +182,11 @@ block2:

; VCode:
; block0:
; xneq32 x6, x0, x1
; zext8 x6, x6
; br_if32 x6, label2; jump label1
; zext16 x6, x0
; zext16 x8, x1
; xneq32 x10, x6, x8
; zext8 x8, x10
; br_if32 x8, label2; jump label1
; block1:
; xconst8 x0, 0
; ret
Expand All @@ -189,9 +195,11 @@ block2:
; ret
;
; Disassembled:
; xneq32 x6, x0, x1
; zext8 x6, x6
; br_if32 x6, 0xa // target = 0x10
; zext16 x6, x0
; zext16 x8, x1
; xneq32 x10, x6, x8
; zext8 x8, x10
; br_if32 x8, 0xa // target = 0x16
; xconst8 x0, 0
; ret
; xconst8 x0, 1
Expand Down
Loading

0 comments on commit 6a1b4ac

Please sign in to comment.