bug#39573: [3.0.0] Compiler fails to optimize out side-effect-free expression

Ludovic Courtès <[email protected]>
Newsgroups gmane.lisp.guile.bugs
Message-ID <[email protected]>
Hello!

Consider this loop:

  (let loop ((n (expt 2 18))
             (i 1))
    (unless (zero? n)
      (loop (- n 1)
            (logior 0 (ash i 1)))))

Guile 2.2 strips away the computation of ‘i’ (it cannot throw, has no
side effects, and the result is unused):

--8<---------------cut here---------------start------------->8---
   0    (assert-nargs-ee/locals 1 4)    ;; 5 slots (0 args)   at (unknown file):16:10
   1    (current-module 4)              
   2    (static-set! 4 74)              ;; #f
   4    (toplevel-box 4 84 72 82 #t)    ;; `expt'
   9    (box-ref 2 4)                   
  10    (make-short-immediate 1 10)     ;; 2
  11    (make-short-immediate 0 74)     ;; 18
  12    (handle-interrupts)                                   at (unknown file):16:24
  13    (call 2 3)                      
  15    (receive 0 2 5)                 
  17    (load-u64 3 0 0)                                      at (unknown file):18:11
  20    (br-if-u64-=-scm 3 4 #f 12)     ;; -> L2
  23    (sub/immediate 4 4 1)                                 at (unknown file):21:11
  24    (br-if-u64-=-scm 3 4 #f 8)      ;; -> L2              at (unknown file):18:11
L1:
  27    (handle-interrupts)                                   at (unknown file):21:11
  28    (sub/immediate 4 4 1)           
  29    (br-if-u64-=-scm 3 4 #t -2)     ;; -> L1              at (unknown file):18:11
L2:
  32    (make-short-immediate 3 2052)   ;; #<unspecified>     at (unknown file):21:11
  33    (handle-interrupts)             
  34    (return-values 2)               ;; 1 value
--8<---------------cut here---------------end--------------->8---

However, 3.0.0 keeps the computation of ‘i’:

--8<---------------cut here---------------start------------->8---
   0    (instrument-entry 192)                                at (unknown file):383:9
   2    (assert-nargs-ee/locals 1 5)    ;; 6 slots (0 args)
   3    (call-scm<-thread 5 62)         
   5    (static-set! 5 147)             ;; #f
   7    (static-ref 5 147)              ;; #f
   9    (immediate-tag=? 5 7 0)         ;; heap-object?
  11    (je 19)                         ;; -> L2
  12    (static-ref 5 140)              ;; #f
  14    (static-ref 4 150)              ;; expt
  16    (call-scm<-scm-scm 5 5 4 40)    
  18    (immediate-tag=? 5 7 0)         ;; heap-object?
  20    (jne 8)                         ;; -> L1
  21    (scm-ref/immediate 3 5 1)       
  22    (immediate-tag=? 3 4095 2308)   ;; undefined?
  24    (je 4)                          ;; -> L1
  25    (static-set! 5 129)             ;; #f
  27    (j 3)                           ;; -> L2
L1:
  28    (throw/value 4 156)             ;; #(unbound-variable #f "Unbound variable: ~S")
L2:
  30    (scm-ref/immediate 2 5 1)       
  31    (make-short-immediate 1 10)     ;; 2
  32    (make-short-immediate 0 74)     ;; 18
  33    (handle-interrupts)                                   at (unknown file):383:23
  34    (call 3 3)                      
  36    (receive 0 3 6)                 
  38    (make-short-immediate 4 2)      ;; 0                  at (unknown file):385:11
  39    (=? 5 4)                        
  40    (je 24)                         ;; -> L4
  41    (call-scm<-scm-uimm 5 5 1 3)                          at (unknown file):388:11
  43    (load-s64 3 0 0)                                      at (unknown file):389:11
  46    (load-s64 2 0 2)                
  49    (ulogior 3 3 2)                 
  50    (tag-fixnum 3 3)                
  51    (=? 5 4)                                              at (unknown file):385:11
  52    (je 12)                         ;; -> L4
L3:
  53    (instrument-loop 139)           
  55    (handle-interrupts)             
  56    (call-scm<-scm-uimm 5 5 1 3)                          at (unknown file):388:11
  58    (call-scm<-scm-uimm 3 3 1 34)                         at (unknown file):389:21
  60    (call-scm<-scm-scm 3 4 3 10)                          at (unknown file):389:11
  62    (=? 5 4)                                              at (unknown file):385:11
  63    (jne -10)                       ;; -> L3
L4:
  64    (make-short-immediate 5 2052)   ;; #<unspecified>     at (unknown file):388:5
  65    (reset-frame 1)                 ;; 1 slot
  66    (handle-interrupts)             
  67    (return-values)                 
--8<---------------cut here---------------end--------------->8---

I’m not sure where the optimization should be taking place.  Perhaps
it’s just a matter of amount-of-work threshold somewhere?

Thanks,
Ludo’.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.