GNU bug report logs -
#39573
[3.0.0] Compiler fails to optimize (logior 0 INT)
Previous Next
Reported by: Ludovic Courtès <ludo <at> gnu.org>
Date: Wed, 12 Feb 2020 11:51:01 UTC
Severity: normal
Done: Ludovic Courtès <ludo <at> gnu.org>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
[Message part 1 (text/plain, inline)]
Your bug report
#39573: [3.0.0] Compiler fails to optimize out side-effect-free expression
which was filed against the guile package, has been closed.
The explanation is attached below, along with your original report.
If you require more details, please reply to 39573 <at> debbugs.gnu.org.
--
39573: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=39573
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
Hi Andy,
Andy Wingo <wingo <at> igalia.com> skribis:
>> However, 3.0.0 keeps the computation of ‘i’:
>>
> [...]
>> 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
>
> Hoo, we need to fix the disassembler to output something more sensible
> than this :P IP 56 appears to be the 1-, 58 is the lsh/immediate, and
> 60 is the logior.
Oh, I hadn’t read that much into these lines. :-)
>> I’m not sure where the optimization should be taking place. Perhaps
>> it’s just a matter of amount-of-work threshold somewhere?
>
> It's not an amount-of-work, that's only in peval which does nothing to
> either of these (though it certainly could).
>
> I took a look. I just pushed something to make (logior 0 INT) reduce to
> INT, but it doesn't remove the loop variable.
OK.
> Then I thought it was surely dead code elimination that just wasn't
> doing its thing. The value is unused, so it must be that it thought
> that the `ash' was effectful. That `ash' gets compiled to
> `lsh/immediate', which does indeed raise an exception if the operand
> isn't an int; but here we prove that it is. The problem was a missing
> "type checker" implementation for lsh/immediate, a problem introduced in
> the refactored compilation of `ash'. So, fixed in git now:
>
> L3:
> 45 (instrument-loop 135)
> 47 (handle-interrupts)
> 48 (call-scm<-scm-uimm 5 5 1 3) at (unknown file):4:12
> 50 (=? 5 4) at (unknown file):3:12
> 51 (jne -6) ;; -> L3
Yay! It’s nice to see how 7dc90a17e03045c7cd8894b14b027b845b68aa4f is
short and clear.
Thanks,
Ludo’.
[Message part 3 (message/rfc822, inline)]
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’.
This bug report was last modified 5 years and 70 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.