diff --git a/contrib/sb-simd/code/arm64-fake-vops.lisp b/contrib/sb-simd/code/arm64-fake-vops.lisp index c8a6f7605..cacdde336 100644 --- a/contrib/sb-simd/code/arm64-fake-vops.lisp +++ b/contrib/sb-simd/code/arm64-fake-vops.lisp @@ -109,6 +109,12 @@ (define-fake-vop u64.2-horizontal+ (a) (sb-simd::%two-arg-u64+ (%u64.2-lane-extract a 0) (%u64.2-lane-extract a 1))) +(define-fake-vop two-arg-u64.2-min (a b) + (%u64.2-bit-select (%two-arg-u64.2> b a) a b)) + +(define-fake-vop two-arg-u64.2-max (a b) + (%u64.2-bit-select (%two-arg-u64.2> a b) a b)) + (define-fake-vop s64.2-pair-min (a b) (%make-s64.2 (sb-simd::%two-arg-s64-min (%s64.2-lane-extract a 0) (%s64.2-lane-extract a 1)) (sb-simd::%two-arg-s64-min (%s64.2-lane-extract b 0) (%s64.2-lane-extract b 1)))) @@ -129,3 +135,9 @@ (define-fake-vop s64.2-horizontal+ (a) (sb-simd::%two-arg-s64+ (%s64.2-lane-extract a 0) (%s64.2-lane-extract a 1))) + +(define-fake-vop two-arg-s64.2-min (a b) + (%s64.2-bit-select (%two-arg-s64.2> b a) a b)) + +(define-fake-vop two-arg-s64.2-max (a b) + (%s64.2-bit-select (%two-arg-s64.2> a b) a b)) diff --git a/contrib/sb-simd/code/define-custom-vops.lisp b/contrib/sb-simd/code/define-custom-vops.lisp index af0456cc4..873f55176 100644 --- a/contrib/sb-simd/code/define-custom-vops.lisp +++ b/contrib/sb-simd/code/define-custom-vops.lisp @@ -313,7 +313,10 @@ (:info lane) (:results (dst :scs (,scalar-reg))) (:generator - (inst umov dst src lane ,element))) + (inst ,(if (and (eql sign :s) (not (eql width 64))) + 'smov + 'umov) + dst src lane ,element))) (define-custom-vop ,(name "~a~d.~d-LANE-INSERT" sign width count) (:args (src1 :scs (int-neon-reg) :target dst) (src2 :scs (,scalar-reg) :to :save)) diff --git a/contrib/sb-simd/code/instruction-sets/neon.lisp b/contrib/sb-simd/code/instruction-sets/neon.lisp index 52d2f9c3d..096d583a5 100644 --- a/contrib/sb-simd/code/instruction-sets/neon.lisp +++ b/contrib/sb-simd/code/instruction-sets/neon.lisp @@ -85,6 +85,8 @@ (f32.4-andc2 #:bic (f32.4) (f32.4 f32.4) :cost 1 :suffix '(:16b)) (f32.4-not #:not (f32.4) (f32.4) :cost 1 :suffix '(:16b)) (f32.4-sqrt #:fsqrt (f32.4) (f32.4) :cost 15 :suffix '(:4s)) + (f32.4-abs #:fabs (f32.4) (f32.4) :cost 1 :suffix '(:4s)) + (f32.4-neg #:fneg (f32.4) (f32.4) :cost 1 :suffix '(:4s)) (f32.4-bit-select #:bsl (f32.4) (u32.4 f32.4 f32.4) :cost 1 :encoding :neon-rmw :suffix '(:16b)) (f32.4-lane-extract nil (f32) (f32.4 imm2) :cost 1 :encoding :custom) (f32.4-lane-insert nil (f32.4) (f32.4 f32 imm2) :cost 1 :encoding :custom) @@ -133,6 +135,8 @@ (f64.2-andc2 #:bic (f64.2) (f64.2 f64.2) :cost 1 :suffix '(:16b)) (f64.2-not #:not (f64.2) (f64.2) :cost 1 :suffix '(:16b)) (f64.2-sqrt #:fsqrt (f64.2) (f64.2) :cost 15 :suffix '(:2d)) + (f64.2-abs #:fabs (f64.2) (f64.2) :cost 1 :suffix '(:2d)) + (f64.2-neg #:fneg (f64.2) (f64.2) :cost 1 :suffix '(:2d)) (f64.2-bit-select #:bsl (f64.2) (u64.2 f64.2 f64.2) :cost 1 :encoding :neon-rmw :suffix '(:16b)) (f64.2-lane-extract nil (f64) (f64.2 imm1) :cost 1 :encoding :custom) (f64.2-lane-insert nil (f64.2) (f64.2 f64 imm1) :cost 1 :encoding :custom) @@ -266,10 +270,10 @@ (u32.4-from-f32.4 #:fcvtnu (u32.4) (f32.4) :cost 5 :suffix '(:4s)) (u32.4-from-u16.8 nil (u32.4) (u16.8) :cost 1 :encoding :custom) (u32.4-from-u16.8-hi nil (u32.4) (u16.8) :cost 1 :encoding :custom) - (u32.4-from-u64.2 #:xtn (u32.4) (u64.2) :cost 1 :suffix '(:4h)) - (u32.4-from-u64.2-hi #:xtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h)) - (u32.4-from-u64.2-saturating #:uqxtn (u32.4) (u64.2) :cost 1 :suffix '(:4h)) - (u32.4-from-u64.2-saturating-hi #:uqxtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h)) + (u32.4-from-u64.2 #:xtn (u32.4) (u64.2) :cost 1 :suffix '(:2s)) + (u32.4-from-u64.2-hi #:xtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s)) + (u32.4-from-u64.2-saturating #:uqxtn (u32.4) (u64.2) :cost 1 :suffix '(:2s)) + (u32.4-from-u64.2-saturating-hi #:uqxtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s)) (make-u32.4 nil (u32.4) (u32 u32 u32 u32) :cost 1 :encoding :fake-vop) (u32.4-values nil (u32 u32 u32 u32) (u32.4) :cost 1 :encoding :fake-vop) (u32.4-broadcast #:dup (u32.4) (u32) :cost 1 :suffix '(:4s)) @@ -329,8 +333,8 @@ (two-arg-u64.2-and #:and (u64.2) (u64.2 u64.2) :cost 1 :associative t :suffix '(:16b)) (two-arg-u64.2-or #:orr (u64.2) (u64.2 u64.2) :cost 1 :associative t :suffix '(:16b)) (two-arg-u64.2-xor #:eor (u64.2) (u64.2 u64.2) :cost 1 :associative t :suffix '(:16b)) - (two-arg-u64.2-max #:umax (u64.2) (u64.2 u64.2) :cost 3 :associative t :suffix '(:2d)) - (two-arg-u64.2-min #:umin (u64.2) (u64.2 u64.2) :cost 3 :associative t :suffix '(:2d)) + (two-arg-u64.2-max nil (u64.2) (u64.2 u64.2) :cost 3 :associative t :encoding :fake-vop) + (two-arg-u64.2-min nil (u64.2) (u64.2 u64.2) :cost 3 :associative t :encoding :fake-vop) (u64.2-andc1 nil (u64.2) (u64.2 u64.2) :cost 1 :encoding :fake-vop) (u64.2-andc2 #:bic (u64.2) (u64.2 u64.2) :cost 1 :suffix '(:16b)) (u64.2-not #:not (u64.2) (u64.2) :cost 1 :suffix '(:16b)) @@ -338,7 +342,6 @@ (two-arg-u64.2+-saturating #:uqadd (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d) :associative t) (two-arg-u64.2- #:sub (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d)) (two-arg-u64.2--saturating #:uqsub (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d)) - (two-arg-u64.2* #:mul (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d) :associative t) (two-arg-u64.2= #:cmeq (u64.2) (u64.2 u64.2) :cost 1 :suffix '(:2d)) (two-arg-u64.2/= nil (u64.2) (u64.2 u64.2) :cost 2 :associative t :encoding :fake-vop) (two-arg-u64.2> #:cmhi (u64.2) (u64.2 u64.2) :cost 1 :suffix '(:2d)) @@ -478,10 +481,10 @@ (s32.4-from-f32.4 #:fcvtns (s32.4) (f32.4) :cost 5 :suffix '(:4s)) (s32.4-from-s16.8 nil (s32.4) (s16.8) :cost 1 :encoding :custom) (s32.4-from-s16.8-hi nil (s32.4) (s16.8) :cost 1 :encoding :custom) - (s32.4-from-s64.2 #:xtn (s32.4) (s64.2) :cost 1 :suffix '(:4h)) - (s32.4-from-s64.2-hi #:xtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h)) - (s32.4-from-s64.2-saturating #:sqxtn (s32.4) (s64.2) :cost 1 :suffix '(:4h)) - (s32.4-from-s64.2-saturating-hi #:sqxtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h)) + (s32.4-from-s64.2 #:xtn (s32.4) (s64.2) :cost 1 :suffix '(:2s)) + (s32.4-from-s64.2-hi #:xtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s)) + (s32.4-from-s64.2-saturating #:sqxtn (s32.4) (s64.2) :cost 1 :suffix '(:2s)) + (s32.4-from-s64.2-saturating-hi #:sqxtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s)) (make-s32.4 nil (s32.4) (s32 s32 s32 s32) :cost 1 :encoding :fake-vop) (s32.4-values nil (s32 s32 s32 s32) (s32.4) :cost 1 :encoding :fake-vop) (s32.4-broadcast #:dup (s32.4) (s32) :cost 1 :suffix '(:4s)) @@ -539,8 +542,8 @@ (two-arg-s64.2-and #:and (s64.2) (s64.2 s64.2) :cost 1 :associative t :suffix '(:16b)) (two-arg-s64.2-or #:orr (s64.2) (s64.2 s64.2) :cost 1 :associative t :suffix '(:16b)) (two-arg-s64.2-xor #:eor (s64.2) (s64.2 s64.2) :cost 1 :associative t :suffix '(:16b)) - (two-arg-s64.2-max #:smax (s64.2) (s64.2 s64.2) :cost 3 :associative t :suffix '(:2d)) - (two-arg-s64.2-min #:smin (s64.2) (s64.2 s64.2) :cost 3 :associative t :suffix '(:2d)) + (two-arg-s64.2-max nil (s64.2) (s64.2 s64.2) :cost 3 :associative t :encoding :fake-vop) + (two-arg-s64.2-min nil (s64.2) (s64.2 s64.2) :cost 3 :associative t :encoding :fake-vop) (s64.2-andc1 nil (s64.2) (s64.2 s64.2) :cost 1 :encoding :fake-vop) (s64.2-andc2 #:bic (s64.2) (s64.2 s64.2) :cost 1 :suffix '(:16b)) (s64.2-not #:not (s64.2) (s64.2) :cost 1 :suffix '(:16b)) @@ -548,7 +551,6 @@ (two-arg-s64.2+-saturating #:sqadd (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d) :associative t) (two-arg-s64.2- #:sub (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d)) (two-arg-s64.2--saturating #:sqsub (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d)) - (two-arg-s64.2* #:mul (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d) :associative t) (two-arg-s64.2= #:cmeq (u64.2) (s64.2 s64.2) :cost 1 :suffix '(:2d)) (two-arg-s64.2/= nil (u64.2) (s64.2 s64.2) :cost 2 :associative t :encoding :fake-vop) (two-arg-s64.2> #:cmgt (u64.2) (s64.2 s64.2) :cost 1 :suffix '(:2d)) @@ -646,7 +648,6 @@ (u64.2-min two-arg-u64.2-min nil) (u64.2+ two-arg-u64.2+ 0) (u64.2+-saturating two-arg-u64.2+-saturating 0) - (u64.2* two-arg-u64.2* 1) (s8.16-and two-arg-s8.16-and +s8-true+) (s8.16-or two-arg-s8.16-or +s8-false+) (s8.16-xor two-arg-s8.16-xor +s8-false+) @@ -677,8 +678,7 @@ (s64.2-max two-arg-s64.2-max nil) (s64.2-min two-arg-s64.2-min nil) (s64.2+ two-arg-s64.2+ 0) - (s64.2+-saturating two-arg-s64.2+-saturating 0) - (s64.2* two-arg-s64.2* 1)) + (s64.2+-saturating two-arg-s64.2+-saturating 0)) (:comparisons (f32.4= two-arg-f32.4= u32.4-and +u32-true+) (f32.4< two-arg-f32.4< u32.4-and +u32-true+) diff --git a/contrib/sb-simd/code/packages.lisp b/contrib/sb-simd/code/packages.lisp index d28bdcc86..aca8836b3 100644 --- a/contrib/sb-simd/code/packages.lisp +++ b/contrib/sb-simd/code/packages.lisp @@ -2170,6 +2170,8 @@ #:f32.4-max #:f32.4-min #:f32.4-sqrt + #:f32.4-abs + #:f32.4-neg #:f32.4+ #:f32.4- #:f32.4* @@ -2220,6 +2222,8 @@ #:f64.2-max #:f64.2-min #:f64.2-sqrt + #:f64.2-abs + #:f64.2-neg #:f64.2+ #:f64.2- #:f64.2* @@ -2268,6 +2272,8 @@ #:u8.16-andc1 #:u8.16-andc2 #:u8.16-not + #:u8.16-min + #:u8.16-max #:u8.16+ #:u8.16+-saturating #:u8.16* @@ -2326,6 +2332,8 @@ #:u16.8-andc1 #:u16.8-andc2 #:u16.8-not + #:u16.8-min + #:u16.8-max #:u16.8+ #:u16.8+-saturating #:u16.8* @@ -2382,6 +2390,8 @@ #:u32.4-andc1 #:u32.4-andc2 #:u32.4-not + #:u32.4-min + #:u32.4-max #:u32.4+ #:u32.4+-saturating #:u32.4* @@ -2438,9 +2448,10 @@ #:u64.2-andc1 #:u64.2-andc2 #:u64.2-not + #:u64.2-min + #:u64.2-max #:u64.2+ #:u64.2+-saturating - #:u64.2* #:u64.2- #:u64.2--saturating #:u64.2= @@ -2487,6 +2498,8 @@ #:s8.16-andc1 #:s8.16-andc2 #:s8.16-not + #:s8.16-min + #:s8.16-max #:s8.16+ #:s8.16+-saturating #:s8.16* @@ -2540,6 +2553,8 @@ #:s16.8-andc1 #:s16.8-andc2 #:s16.8-not + #:s16.8-min + #:s16.8-max #:s16.8+ #:s16.8+-saturating #:s16.8* @@ -2594,6 +2609,8 @@ #:s32.4-andc1 #:s32.4-andc2 #:s32.4-not + #:s32.4-min + #:s32.4-max #:s32.4+ #:s32.4+-saturating #:s32.4* @@ -2644,9 +2661,10 @@ #:s64.2-andc1 #:s64.2-andc2 #:s64.2-not + #:s64.2-min + #:s64.2-max #:s64.2+ #:s64.2+-saturating - #:s64.2* #:s64.2- #:s64.2--saturating #:s64.2= diff --git a/contrib/sb-simd/test-suite/test-arm64-regressions.lisp b/contrib/sb-simd/test-suite/test-arm64-regressions.lisp new file mode 100644 index 000000000..f125a7730 --- /dev/null +++ b/contrib/sb-simd/test-suite/test-arm64-regressions.lisp @@ -0,0 +1,179 @@ +;;; Regression tests for AdvSIMD bugs found by auditing sb-simd against +;;; the A64 instruction set. Each test targets a bug that once produced +;;; wrong results or illegal instructions rather than a clean error. + +(in-package #:sb-simd-neon) + +;;; Values that sit on both sides of the signed/unsigned wrap-around +;;; point. Random sampling almost never generates pairs like +;;; (0, #xFFFFFFFFFFFFFFFF), so test them exhaustively. +(defparameter *u64-boundary-values* + (list 0 1 2 3 5 + #x7FFFFFFFFFFFFFFE #x7FFFFFFFFFFFFFFF + #x8000000000000000 #x8000000000000001 + #xFFFFFFFFFFFFFFFD #xFFFFFFFFFFFFFFFE #xFFFFFFFFFFFFFFFF)) + +(defparameter *s64-boundary-values* + (list -9223372036854775808 -9223372036854775807 -1 0 1 42 + 9223372036854775806 9223372036854775807)) + +;;; Issue: UMAX/UMIN/SMAX/SMIN have no .2d form; max/min are fake vops +;;; built from CMHI/CMGT plus BSL. +(sb-simd-test-suite:define-test u64.2-max-min-boundaries + (dolist (a *u64-boundary-values*) + (dolist (b *u64-boundary-values*) + (let ((pa (make-u64.2 a a)) + (pb (make-u64.2 b b))) + (sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-max pa pb) 0) (max a b))) + (sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-min pa pb) 0) (min a b))))))) + +(sb-simd-test-suite:define-test s64.2-max-min-boundaries + (dolist (a *s64-boundary-values*) + (dolist (b *s64-boundary-values*) + (let ((pa (make-s64.2 a a)) + (pb (make-s64.2 b b))) + (sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-max pa pb) 0) (max a b))) + (sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-min pa pb) 0) (min a b))))))) + +;;; Random cross-check of the same fake vops against the scalar +;;; reference implementation. +(sb-simd-test-suite:define-test u64.2-max-min-random + (flet ((to-signed (x) (if (logbitp 63 x) (- x (ash 1 64)) x))) + (dotimes (i 2000) + (let* ((bits (lambda () (logior (ash (random (ash 1 32)) 32) + (random (ash 1 32))))) + (a0 (funcall bits)) (a1 (funcall bits)) + (b0 (funcall bits)) (b1 (funcall bits)) + (ua (make-u64.2 a0 a1)) + (ub (make-u64.2 b0 b1)) + (sa (make-s64.2 (to-signed a0) (to-signed a1))) + (sb (make-s64.2 (to-signed b0) (to-signed b1)))) + (sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-max ua ub) 0) (max a0 b0))) + (sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-min ua ub) 1) (min a1 b1))) + (sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-max sa sb) 0) + (max (to-signed a0) (to-signed b0)))) + (sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-min sa sb) 1) + (min (to-signed a1) (to-signed b1)))))))) + +;;; Issue: the XTN-family narrowing records used .4h/.8h suffixes, +;;; silently computing a 32-to-16-bit narrowing on 64-bit lanes. +(sb-simd-test-suite:define-test u32.4-from-u64.2-narrowing + ;; Plain narrowing takes the low half of each lane and zeroes the rest. + (let ((r (u32.4-from-u64.2 (make-u64.2 #x1111111122222222 + #x3333333344444444)))) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 0) #x22222222)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 1) #x44444444)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 2) 0)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 3) 0))) + ;; Saturating narrowing clamps into the target range. + (let ((r (u32.4-from-u64.2-saturating (make-u64.2 #xFFFFFFFFFFFFFFFF 3)))) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 0) #xFFFFFFFF)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 1) 3))) + ;; The -hi variants append to the high half and preserve the low half. + (let ((r (u32.4-from-u64.2-hi (make-u32.4 10 20 30 40) + (make-u64.2 #x1111111122222222 + #x3333333344444444)))) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 0) 10)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 1) 20)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 2) #x22222222)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 3) #x44444444))) + (let ((r (u32.4-from-u64.2-saturating-hi + (make-u32.4 10 20 30 40) + (make-u64.2 #xFFFFFFFFFFFFFFFF #xFFFFFFFFFFFFFFFF)))) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 0) 10)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 1) 20)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 2) #xFFFFFFFF)) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 3) #xFFFFFFFF)))) + +(sb-simd-test-suite:define-test s32.4-from-s64.2-narrowing + (let ((r (s32.4-from-s64.2 (make-s64.2 -5 #x7000000011112222)))) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 0) -5)) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 1) #x11112222)) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 2) 0)) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 3) 0))) + ;; Saturation clamps in both directions. + (let ((r (s32.4-from-s64.2-saturating + (make-s64.2 #x7FFFFFFFFFFFFFFF -99999999999999)))) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 0) most-positive-s32)) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 1) most-negative-s32))) + (let ((r (s32.4-from-s64.2-hi (make-s32.4 10 20 30 40) + (make-s64.2 -5 #x7000000011112222)))) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 0) 10)) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 1) 20)) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 2) -5)) + (sb-simd-test-suite:is (= (s32.4-lane-extract r 3) #x11112222)))) + +;;; Issue: signed lane extraction returned zero-extended values because +;;; the custom vops emitted UMOV instead of SMOV. +(sb-simd-test-suite:define-test signed-lane-extraction-sign-extends + (let ((v (make-s8.16 -128 -1 127 42 0 -42 1 -127 2 -2 3 -3 4 -4 5 -5))) + (loop for expected in '(-128 -1 127 42 0 -42 1 -127 2 -2 3 -3 4 -4 5 -5) + for i from 0 + do (sb-simd-test-suite:is (= (s8.16-lane-extract v i) expected)))) + (let ((v (make-s16.8 -32768 -1 32767 12345 -5432 0 1 -1))) + (loop for expected in '(-32768 -1 32767 12345 -5432 0 1 -1) + for i from 0 + do (sb-simd-test-suite:is (= (s16.8-lane-extract v i) expected)))) + (let ((v (make-s32.4 -2147483648 -1 2147483647 42))) + (loop for expected in '(-2147483648 -1 2147483647 42) + for i from 0 + do (sb-simd-test-suite:is (= (s32.4-lane-extract v i) expected)))) + ;; Unsigned shapes must remain unaffected. + (let ((v (make-u8.16 255 254 253 252 0 1 2 3 4 5 6 7 8 9 10 11))) + (sb-simd-test-suite:is (= (u8.16-lane-extract v 0) 255)) + (sb-simd-test-suite:is (= (u8.16-lane-extract v 3) 252)))) + +;;; Issue: emit-movi-vector-imm passed replicated broadcast patterns to +;;; MOVI instead of lane immediates, aborting compilation with "bad +;;; immediate". Every constant below is materialized through that code +;;; path; several exercise the shifted-cmode forms. The tests are split +;;; into several functions because packing too many distinct vector +;;; constants into one function currently overflows the LDR spill +;;; offset range - see issue about large SIMD constant pools. +(sb-simd-test-suite:define-test integer-broadcast-constants-simple + ;; The original reproducer: 1 does not fit MOVI's simple .8h form. + (let ((r (u16.8-and (u16.8-broadcast 5) 1))) + (sb-simd-test-suite:is (= (u16.8-lane-extract r 0) 1)) + (sb-simd-test-suite:is (= (u16.8-lane-extract r 7) 1))) + ;; Shifted immediates (low byte zero). + (let ((r (u16.8-and (u16.8-broadcast #x0100) #x0100))) + (sb-simd-test-suite:is (= (u16.8-lane-extract r 3) #x0100))) + ;; Byte-replicated patterns. + (dolist (c (list 0 1 #x7F #x80 #xFF)) + (let ((r (u8.16-or (u8.16-broadcast c) (u8.16-broadcast c)))) + (sb-simd-test-suite:is (= (u8.16-lane-extract r 15) c))))) + +(sb-simd-test-suite:define-test integer-broadcast-constants-word + ;; 32-bit constants with shifted bytes. + (dolist (c (list 0 1 255 256 #xFFFF #x10000 #xFF0000 #xFF000000)) + (let ((r (u32.4-and (u32.4-broadcast c) (u32.4-broadcast c)))) + (sb-simd-test-suite:is (= (u32.4-lane-extract r 0) c))))) + +;;; Bit-replication patterns (.2d MOVI form): every byte is 0 or #xFF. +(sb-simd-test-suite:define-test integer-broadcast-constants-bit-replicated + (dolist (c (list #xFF00FF00FF00FF00 + #x8000000000000000 + #xFFFFFFFFFFFFFFFF + #x7F7F7F7F7F7F7F7F + #x00FF00FF00FF00FF)) + (let ((r (u64.2-and (u64.2-broadcast c) (u64.2-broadcast c)))) + (sb-simd-test-suite:is (= (u64.2-lane-extract r 0) c)) + (sb-simd-test-suite:is (= (u64.2-lane-extract r 1) c))))) + +;;; Patterns that fit no MOVI form fall back to register synthesis +;;; (MOVZ/DUP or logical-immediate ORR). +(sb-simd-test-suite:define-test integer-broadcast-constants-synthesized + (dolist (c (list #x0102030405060708 #xDEADBEEFCAFEBABE)) + (let ((r (u64.2-and (u64.2-broadcast c) (u64.2-broadcast c)))) + (sb-simd-test-suite:is (= (u64.2-lane-extract r 1) c))))) + +;;; Float constants take a different path (movi-immediate-p guarded); +;;; keep them covered too. +(sb-simd-test-suite:define-test float-broadcast-constants + (let ((r (f32.4-max (make-f32.4 0.5 -1.0 2.0 3.0) 1.0f0))) + (sb-simd-test-suite:is (= (f32.4-lane-extract r 0) 1.0f0)) + (sb-simd-test-suite:is (= (f32.4-lane-extract r 1) 1.0f0)) + (sb-simd-test-suite:is (= (f32.4-lane-extract r 2) 2.0f0))) + (let ((r (f64.2-min (make-f64.2 0.5d0 -5d0) -1d0))) + (sb-simd-test-suite:is (= (f64.2-lane-extract r 0) -1d0)) + (sb-simd-test-suite:is (= (f64.2-lane-extract r 1) -5d0)))) diff --git a/contrib/sb-simd/test-suite/test-simple-simd-functions-arm64.lisp b/contrib/sb-simd/test-suite/test-simple-simd-functions-arm64.lisp index 280d4184b..8ad454e4c 100644 --- a/contrib/sb-simd/test-suite/test-simple-simd-functions-arm64.lisp +++ b/contrib/sb-simd/test-suite/test-simple-simd-functions-arm64.lisp @@ -8,6 +8,8 @@ (sb-simd-test-suite:define-simple-simd-test f32.4-not (f32.4) (f32.4) f32-not) (sb-simd-test-suite:define-simple-simd-test f32.4-max (f32.4) (f32.4 &rest f32.4) f32-max) (sb-simd-test-suite:define-simple-simd-test f32.4-min (f32.4) (f32.4 &rest f32.4) f32-min) +(sb-simd-test-suite:define-simple-simd-test f32.4-abs (f32.4) (f32.4) abs) +(sb-simd-test-suite:define-simple-simd-test f32.4-neg (f32.4) (f32.4) -) (sb-simd-test-suite:define-simple-simd-test f32.4+ (f32.4) (&rest f32.4) f32+) (sb-simd-test-suite:define-simple-simd-test f32.4- (f32.4) (f32.4 &rest f32.4) f32-) (sb-simd-test-suite:define-simple-simd-test f32.4* (f32.4) (&rest f32.4) f32*) @@ -26,6 +28,8 @@ (sb-simd-test-suite:define-simple-simd-test f64.2-not (f64.2) (f64.2) f64-not) (sb-simd-test-suite:define-simple-simd-test f64.2-max (f64.2) (f64.2 &rest f64.2) f64-max) (sb-simd-test-suite:define-simple-simd-test f64.2-min (f64.2) (f64.2 &rest f64.2) f64-min) +(sb-simd-test-suite:define-simple-simd-test f64.2-abs (f64.2) (f64.2) abs) +(sb-simd-test-suite:define-simple-simd-test f64.2-neg (f64.2) (f64.2) -) (sb-simd-test-suite:define-simple-simd-test f64.2+ (f64.2) (&rest f64.2) f64+) (sb-simd-test-suite:define-simple-simd-test f64.2- (f64.2) (f64.2 &rest f64.2) f64-) (sb-simd-test-suite:define-simple-simd-test f64.2* (f64.2) (&rest f64.2) f64*) @@ -42,6 +46,8 @@ (sb-simd-test-suite:define-simple-simd-test u8.16-xor (u8.16) (&rest u8.16) u8-xor) (sb-simd-test-suite:define-simple-simd-test u8.16-andc1 (u8.16) (u8.16 u8.16) u8-andc1) (sb-simd-test-suite:define-simple-simd-test u8.16-not (u8.16) (u8.16) u8-not) +(sb-simd-test-suite:define-simple-simd-test u8.16-max (u8.16) (u8.16 &rest u8.16) u8-max) +(sb-simd-test-suite:define-simple-simd-test u8.16-min (u8.16) (u8.16 &rest u8.16) u8-min) (sb-simd-test-suite:define-simple-simd-test u8.16+ (u8.16) (&rest u8.16) u8+) (sb-simd-test-suite:define-simple-simd-test u8.16- (u8.16) (u8.16 &rest u8.16) u8-) (sb-simd-test-suite:define-simple-simd-test u8.16= (u8.16) (u8.16 &rest u8.16) u8=) @@ -56,6 +62,8 @@ (sb-simd-test-suite:define-simple-simd-test u16.8-xor (u16.8) (&rest u16.8) u16-xor) (sb-simd-test-suite:define-simple-simd-test u16.8-andc1 (u16.8) (u16.8 u16.8) u16-andc1) (sb-simd-test-suite:define-simple-simd-test u16.8-not (u16.8) (u16.8) u16-not) +(sb-simd-test-suite:define-simple-simd-test u16.8-max (u16.8) (u16.8 &rest u16.8) u16-max) +(sb-simd-test-suite:define-simple-simd-test u16.8-min (u16.8) (u16.8 &rest u16.8) u16-min) (sb-simd-test-suite:define-simple-simd-test u16.8+ (u16.8) (&rest u16.8) u16+) (sb-simd-test-suite:define-simple-simd-test u16.8- (u16.8) (u16.8 &rest u16.8) u16-) (sb-simd-test-suite:define-simple-simd-test u16.8= (u16.8) (u16.8 &rest u16.8) u16=) @@ -70,6 +78,8 @@ (sb-simd-test-suite:define-simple-simd-test u32.4-xor (u32.4) (&rest u32.4) u32-xor) (sb-simd-test-suite:define-simple-simd-test u32.4-andc1 (u32.4) (u32.4 u32.4) u32-andc1) (sb-simd-test-suite:define-simple-simd-test u32.4-not (u32.4) (u32.4) u32-not) +(sb-simd-test-suite:define-simple-simd-test u32.4-max (u32.4) (u32.4 &rest u32.4) u32-max) +(sb-simd-test-suite:define-simple-simd-test u32.4-min (u32.4) (u32.4 &rest u32.4) u32-min) (sb-simd-test-suite:define-simple-simd-test u32.4+ (u32.4) (&rest u32.4) u32+) (sb-simd-test-suite:define-simple-simd-test u32.4- (u32.4) (u32.4 &rest u32.4) u32-) (sb-simd-test-suite:define-simple-simd-test u32.4= (u32.4) (u32.4 &rest u32.4) u32=) @@ -84,6 +94,8 @@ (sb-simd-test-suite:define-simple-simd-test u64.2-xor (u64.2) (&rest u64.2) u64-xor) (sb-simd-test-suite:define-simple-simd-test u64.2-andc1 (u64.2) (u64.2 u64.2) u64-andc1) (sb-simd-test-suite:define-simple-simd-test u64.2-not (u64.2) (u64.2) u64-not) +(sb-simd-test-suite:define-simple-simd-test u64.2-max (u64.2) (u64.2 &rest u64.2) u64-max) +(sb-simd-test-suite:define-simple-simd-test u64.2-min (u64.2) (u64.2 &rest u64.2) u64-min) (sb-simd-test-suite:define-simple-simd-test u64.2+ (u64.2) (&rest u64.2) u64+) (sb-simd-test-suite:define-simple-simd-test u64.2- (u64.2) (u64.2 &rest u64.2) u64-) (sb-simd-test-suite:define-simple-simd-test u64.2= (u64.2) (u64.2 &rest u64.2) u64=) @@ -98,6 +110,8 @@ (sb-simd-test-suite:define-simple-simd-test s8.16-xor (s8.16) (&rest s8.16) s8-xor) (sb-simd-test-suite:define-simple-simd-test s8.16-andc1 (s8.16) (s8.16 s8.16) s8-andc1) (sb-simd-test-suite:define-simple-simd-test s8.16-not (s8.16) (s8.16) s8-not) +(sb-simd-test-suite:define-simple-simd-test s8.16-max (s8.16) (s8.16 &rest s8.16) s8-max) +(sb-simd-test-suite:define-simple-simd-test s8.16-min (s8.16) (s8.16 &rest s8.16) s8-min) (sb-simd-test-suite:define-simple-simd-test s8.16+ (s8.16) (&rest s8.16) s8+) (sb-simd-test-suite:define-simple-simd-test s8.16- (s8.16) (s8.16 &rest s8.16) s8-) (sb-simd-test-suite:define-simple-simd-test s8.16= (u8.16) (s8.16 &rest s8.16) s8=) @@ -112,6 +126,8 @@ (sb-simd-test-suite:define-simple-simd-test s16.8-xor (s16.8) (&rest s16.8) s16-xor) (sb-simd-test-suite:define-simple-simd-test s16.8-andc1 (s16.8) (s16.8 s16.8) s16-andc1) (sb-simd-test-suite:define-simple-simd-test s16.8-not (s16.8) (s16.8) s16-not) +(sb-simd-test-suite:define-simple-simd-test s16.8-max (s16.8) (s16.8 &rest s16.8) s16-max) +(sb-simd-test-suite:define-simple-simd-test s16.8-min (s16.8) (s16.8 &rest s16.8) s16-min) (sb-simd-test-suite:define-simple-simd-test s16.8+ (s16.8) (&rest s16.8) s16+) (sb-simd-test-suite:define-simple-simd-test s16.8- (s16.8) (s16.8 &rest s16.8) s16-) (sb-simd-test-suite:define-simple-simd-test s16.8= (u16.8) (s16.8 &rest s16.8) s16=) @@ -126,6 +142,8 @@ (sb-simd-test-suite:define-simple-simd-test s32.4-xor (s32.4) (&rest s32.4) s32-xor) (sb-simd-test-suite:define-simple-simd-test s32.4-andc1 (s32.4) (s32.4 s32.4) s32-andc1) (sb-simd-test-suite:define-simple-simd-test s32.4-not (s32.4) (s32.4) s32-not) +(sb-simd-test-suite:define-simple-simd-test s32.4-max (s32.4) (s32.4 &rest s32.4) s32-max) +(sb-simd-test-suite:define-simple-simd-test s32.4-min (s32.4) (s32.4 &rest s32.4) s32-min) (sb-simd-test-suite:define-simple-simd-test s32.4+ (s32.4) (&rest s32.4) s32+) (sb-simd-test-suite:define-simple-simd-test s32.4- (s32.4) (s32.4 &rest s32.4) s32-) (sb-simd-test-suite:define-simple-simd-test s32.4= (u32.4) (s32.4 &rest s32.4) s32=) @@ -140,6 +158,8 @@ (sb-simd-test-suite:define-simple-simd-test s64.2-xor (s64.2) (&rest s64.2) s64-xor) (sb-simd-test-suite:define-simple-simd-test s64.2-andc1 (s64.2) (s64.2 s64.2) s64-andc1) (sb-simd-test-suite:define-simple-simd-test s64.2-not (s64.2) (s64.2) s64-not) +(sb-simd-test-suite:define-simple-simd-test s64.2-max (s64.2) (s64.2 &rest s64.2) s64-max) +(sb-simd-test-suite:define-simple-simd-test s64.2-min (s64.2) (s64.2 &rest s64.2) s64-min) (sb-simd-test-suite:define-simple-simd-test s64.2+ (s64.2) (&rest s64.2) s64+) (sb-simd-test-suite:define-simple-simd-test s64.2- (s64.2) (s64.2 &rest s64.2) s64-) (sb-simd-test-suite:define-simple-simd-test s64.2= (u64.2) (s64.2 &rest s64.2) s64=) diff --git a/src/compiler/arm64/insts.lisp b/src/compiler/arm64/insts.lisp index 234b9b5c3..70023117c 100644 --- a/src/compiler/arm64/insts.lisp +++ b/src/compiler/arm64/insts.lisp @@ -2810,38 +2810,42 @@ (fpr-offset rd))))) (defmacro def-fp-data-processing-1+simd (name op - simd-u simd-neg simd-op) + simd-u simd-neg simd-op6 simd-op) `(define-instruction ,name (segment rd rn &optional vector-size) (:printer fp-data-processing-1 ((op ,op))) - (:printer simd-two-same-float ((u ,simd-u) (neg ,simd-neg) (op ,simd-op))) + (:printer simd-two-same-float ((u ,simd-u) (neg ,simd-neg) (op6 ,simd-op6) + (op ,simd-op))) (:emitter (assert (and (eq (tn-sc rd) (tn-sc rn))) (rd rn) "Arguments should have the same FP storage class: ~s ~s." rd rn) - (if vector-size - (multiple-value-bind (q size) (encode-vector-size vector-size) - (emit-simd-two-same-float - segment - q - ,simd-u - ,simd-neg - (logand 1 size) - ,simd-op - (fpr-offset rn) - (fpr-offset rd))) - (emit-fp-data-processing-1 segment - (fp-reg-type rn) - ,op - (fpr-offset rn) - (fpr-offset rd)))))) + (cond (vector-size + (aver (member vector-size '(:2s :4s :2d))) + (multiple-value-bind (q size) (encode-vector-size vector-size) + (emit-simd-two-same-float + segment + q + ,simd-u + ,simd-neg + (logand 1 size) + ,simd-op6 + ,simd-op + (fpr-offset rn) + (fpr-offset rd)))) + (t + (emit-fp-data-processing-1 segment + (fp-reg-type rn) + ,op + (fpr-offset rn) + (fpr-offset rd))))))) (def-fp-data-processing-1+simd fabs #b0001 - #b0 #b1 #b11111) + #b0 #b1 #b00000 #b11111) (def-fp-data-processing-1+simd fneg #b0010 - #b1 #b1 #b11111) + #b1 #b1 #b00000 #b11111) (def-fp-data-processing-1+simd fsqrt #b0011 - #b1 #b0 #b11111) + #b1 #b1 #b00001 #b11111) (def-fp-data-processing-1 frintn #b1000) (def-fp-data-processing-1 frintp #b1001) (def-fp-data-processing-1 frintm #b1010) @@ -2888,24 +2892,26 @@ (:printer fp-data-processing-2 ((op ,op))) (:printer simd-three-same-float ((u ,simd-u) (neg ,simd-neg) (op ,simd-op))) (:emitter - (if vector-size - (multiple-value-bind (q size) (encode-vector-size vector-size) - (emit-simd-three-same-float - segment - q - ,simd-u - ,simd-neg - (logand 1 size) - (fpr-offset rm) - ,simd-op - (fpr-offset rn) - (fpr-offset rd))) - (emit-fp-data-processing-2 segment - (fp-reg-type rn) - (fpr-offset rm) - ,op - (fpr-offset rn) - (fpr-offset rd)))))) + (cond (vector-size + (aver (member vector-size '(:2s :4s :2d))) + (multiple-value-bind (q size) (encode-vector-size vector-size) + (emit-simd-three-same-float + segment + q + ,simd-u + ,simd-neg + (logand 1 size) + (fpr-offset rm) + ,simd-op + (fpr-offset rn) + (fpr-offset rd)))) + (t + (emit-fp-data-processing-2 segment + (fp-reg-type rn) + (fpr-offset rm) + ,op + (fpr-offset rn) + (fpr-offset rd))))))) (def-fp-data-processing-2+simd fmul #b0000 #b1 #b0 #b11011) @@ -3479,8 +3485,8 @@ (neg 1 23) (size 1 22) (#b1 1 21) - (#b00000 5 16) - (opc 5 11) + (op6 5 16) + (op 5 11) (#b0 1 10) (rn 5 5) (rd 5 0)) @@ -3533,10 +3539,10 @@ (op3 :field (byte 1 31) :value #b0) (u :field (byte 1 29)) (op4 :field (byte 5 24) :value #b01110) - (neg :field (byte 1 23)) + (neg :field (byte 1 23) :value #b1) (size :field (byte 1 22)) (op5 :field (byte 1 21) :value #b1) - (op6 :field (byte 5 16) :value #b00000) + (op6 :field (byte 5 16)) (op :field (byte 5 11)) (op7 :field (byte 1 10) :value #b0) (rn :fields (list (byte 1 30) (byte 1 22) (byte 5 5)) :type 'simd-float-reg) @@ -3612,7 +3618,9 @@ (def bit #b1 #b10 #b00011) (def bif #b1 #b11 #b00011)) -(macrolet ((def (name u op &optional zero-u zero) +(macrolet ((def (name u op &optional + (2d t) + zero-u zero) `(define-instruction ,name (segment rd rn rm size) ,@(when op `((:printer simd-three-same-sized ((u ,u) (op ,op))))) @@ -3620,6 +3628,9 @@ `((:printer simd-two-misc ((u ,zero-u) (op ,zero)) '(:name :tab rd ", " rn ", " "#0")))) (:emitter + (aver (member size ',(if 2d + '(:8b :16b :4h :8h :2s :4s :2d) + '(:8b :16b :4h :8h :2s :4s)))) (multiple-value-bind (q size) (encode-vector-size size) (cond ,@(when zero `(((eql rm 0) @@ -3644,32 +3655,32 @@ (fpr-offset rd)) `(error "Can be compared only with zero, not ~s" rm))))))))) (def cmtst #b0 #b10001) - (def cmeq #b1 #b10001 0 #b01001) - (def cmgt #b0 #b00110 0 #b01000) - (def cmge #b0 #b00111 1 #b01000) - (def cmlt nil nil 0 #b01010) - (def cmle nil nil 1 #b01001) + (def cmeq #b1 #b10001 t 0 #b01001) + (def cmgt #b0 #b00110 t 0 #b01000) + (def cmge #b0 #b00111 t 1 #b01000) + (def cmlt nil nil t 0 #b01010) + (def cmle nil nil t 1 #b01001) (def cmhi #b1 #b00110) (def cmhs #b1 #b00111) - (def umin #b1 #b01101) - (def umax #b1 #b01100) - (def smin #b0 #b01101) - (def smax #b0 #b01100) - (def uhadd #b1 #b00000) + (def umin #b1 #b01101 nil) + (def umax #b1 #b01100 nil) + (def smin #b0 #b01101 nil) + (def smax #b0 #b01100 nil) + (def uhadd #b1 #b00000 nil) (def uqadd #b1 #b00001) - (def urhadd #b1 #b00010) - (def uhsub #b1 #b00100) + (def urhadd #b1 #b00010 nil) + (def uhsub #b1 #b00100 nil) (def uqsub #b1 #b00101) (def addp #b0 #b10111) - (def shadd #b0 #b00000) + (def shadd #b0 #b00000 nil) (def sqadd #b0 #b00001) - (def srhadd #b0 #b00010) - (def shsub #b0 #b00100) + (def srhadd #b0 #b00010 nil) + (def shsub #b0 #b00100 nil) (def sqsub #b0 #b00101) - (def uminp #b1 #b10101) - (def umaxp #b1 #b10100) - (def sminp #b0 #b10101) - (def smaxp #b0 #b10100) + (def uminp #b1 #b10101 nil) + (def umaxp #b1 #b10100 nil) + (def sminp #b0 #b10101 nil) + (def smaxp #b0 #b10100 nil) (def sshl #b0 #b01001) (def ushl #b1 #b01001)) @@ -3677,6 +3688,7 @@ `(define-instruction ,name (segment rd rn rm size) (:printer simd-three-same-float ((u ,u) (neg ,neg) (op ,op))) (:emitter + (aver (member size '(:2s :4s :2d))) (multiple-value-bind (q size) (encode-vector-size size) (emit-simd-three-same-float segment @@ -3759,6 +3771,7 @@ (fpr-offset rn) (fpr-offset rd))) (t + (aver (member vector-size '(:2s :4s :2d))) (multiple-value-bind (q size) (encode-vector-size vector-size) (emit-simd-three-same-float segment @@ -4082,6 +4095,7 @@ (:printer simd-across-lanes ((u ,u) (op ,op) (rd nil :type 'vbhs))) (:emitter + (aver (member size '(:8b :16b :4h :8h :2s :4s))) (multiple-value-bind (q size) (encode-vector-size size) (emit-simd-across-lanes segment @@ -4171,6 +4185,7 @@ `(define-instruction ,name (segment rd rn size) (:printer simd-two-misc ((u ,u) (op ,op) (rd nil :type 'simd-reg-2x))) (:emitter + (aver (member size '(:8b :16b :4h :8h :2s :4s))) (multiple-value-bind (q size) (encode-vector-size size) (emit-simd-two-misc segment q @@ -4366,8 +4381,8 @@ (fpr-offset rn) (fpr-offset rd))))))) (def shl #b0 #b01010 nil t) - (def sli #b1 #b01010) - (def sri #b1 #b01000 t) + (def sli #b1 #b01010 nil t) + (def sri #b1 #b01000 t t) (def sshr #b0 #b00000 t t) (def shrn #b0 #b10000 t) (def ssra #b0 #b00010 t t) diff --git a/src/compiler/arm64/simd-pack.lisp b/src/compiler/arm64/simd-pack.lisp index 2f4811365..6cedbe04f 100644 --- a/src/compiler/arm64/simd-pack.lisp +++ b/src/compiler/arm64/simd-pack.lisp @@ -35,13 +35,13 @@ (zerop (dpb 0 (byte 8 8) (ldb (byte 32 0) value))) (zerop (dpb 0 (byte 8 16) (ldb (byte 32 0) value))) (zerop (dpb 0 (byte 8 24) (ldb (byte 32 0) value))))) - (inst movi dst value :4s)) + (inst movi dst (ldb (byte 32 0) value) :4s)) ((and wordp (or (zerop (dpb 0 (byte 8 0) (ldb (byte 16 0) value))) (zerop (dpb 0 (byte 8 8) (ldb (byte 16 0) value))))) - (inst movi dst value :8h)) + (inst movi dst (ldb (byte 16 0) value) :8h)) (bytep - (inst movi dst value :16b)) + (inst movi dst (ldb (byte 8 0) value) :16b)) ((and (member (ldb (byte 8 0) value) '(0 #xFF)) (member (ldb (byte 8 8) value) '(0 #xFF)) (member (ldb (byte 8 16) value) '(0 #xFF)) @@ -50,7 +50,7 @@ (member (ldb (byte 8 40) value) '(0 #xFF)) (member (ldb (byte 8 48) value) '(0 #xFF)) (member (ldb (byte 8 56) value) '(0 #xFF))) - (inst movi value :2d)) + (inst movi dst value :2d)) ;; Can't do movi, try via the scalar regs. (wordp (inst movz tmp-tn (ldb (byte 16 0) value)) diff --git a/src/compiler/arm64/vm.lisp b/src/compiler/arm64/vm.lisp index 7067eff56..e38541185 100644 --- a/src/compiler/arm64/vm.lisp +++ b/src/compiler/arm64/vm.lisp @@ -148,11 +148,11 @@ (complex-single-stack non-descriptor-stack) (complex-double-stack non-descriptor-stack :element-size 2 :alignment 2) #+sb-simd-pack - (int-neon-stack non-descriptor-stack :element-size 2) + (int-neon-stack non-descriptor-stack :element-size 2 :alignment 2) #+sb-simd-pack - (double-neon-stack non-descriptor-stack :element-size 2) + (double-neon-stack non-descriptor-stack :element-size 2 :alignment 2) #+sb-simd-pack - (single-neon-stack non-descriptor-stack :element-size 2) + (single-neon-stack non-descriptor-stack :element-size 2 :alignment 2) ;; **** Things that can go in the integer registers. diff --git a/tests/sb-simd.impure.lisp b/tests/sb-simd.impure.lisp index 0e647a95c..a71bd9b8d 100644 --- a/tests/sb-simd.impure.lisp +++ b/tests/sb-simd.impure.lisp @@ -28,6 +28,7 @@ "test-horizontal-functions.lisp" #+x86-64 "test-horizontal-functions-x86-64.lisp" #+arm64 "test-horizontal-functions-arm64.lisp" + #+arm64 "test-arm64-regressions.lisp" "test-hairy-simd-functions.lisp" "test-packages.lisp")) (load (merge-pathnames file #P"../contrib/sb-simd/test-suite/"))))