From baa0aa1348aa5fe526425efbf11707d8e02a2640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 21 Sep 2021 09:43:53 +0200 Subject: [PATCH] base32: Work around (ash x N) miscompilation at '-O1' and below. Fixes . Reported by Marius Bakke . * guix/base32.scm (bit-field): Introduce 'minus-start' syntax and use it. --- guix/base32.scm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/guix/base32.scm b/guix/base32.scm index d6c8a02243..8f097d4e77 100644 --- a/guix/base32.scm +++ b/guix/base32.scm @@ -53,7 +53,15 @@ (let* ((s (syntax->datum #'start)) (e (syntax->datum #'end)) (mask (- (expt 2 (- e s)) 1))) - #`(logand (ash n (- start)) #,mask)))))) + ;; The baseline compiler in Guile <= 3.0.7 miscompiles (ash x N) as + ;; (ash x (- N)) when N is a literal: . + ;; Here we take advantage of another bug in the baseline compiler, + ;; fixed in Guile commit 330c6ea83f492672578b62d0683acbb532d1a5d9: we + ;; introduce 'minus-start' such that it has a different source + ;; location, which in turn means that the baseline compiler pattern + ;; for (ash x N) doesn't match, thus avoiding the bug (!). + (with-syntax ((minus-start (datum->syntax #'start (- s)))) + #`(logand (ash n minus-start) #,mask))))))) (define bytevector-quintet-ref (let* ((ref bytevector-u8-ref)