Compiler should use comparisons to restrict integer range types
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
(defun f (i)
(declare (type (integer 0) i))
(cond
((= i 0) 'a)
((> i 0) 'b)
(t 'c)))
does not conclude the T branch is dead.
; disassembly for F
; Size: 47 bytes. Origin: #x52DD60E6
; 0E6: 4885D2 TEST RDX, RDX ; no-arg-parsing entry point
; 0E9: 7421 JEQ L1
; 0EB: 31FF XOR EDI, EDI
; 0ED: FF1425D8001052 CALL QWORD PTR [#x521000D8] ; GENERIC->
; 0F4: 488B0595FFFFFF MOV RAX, [RIP-107] ; 'B
; 0FB: 488B1596FFFFFF MOV RDX, [RIP-106] ; 'C
; 102: 480F4FD0 CMOVNLE RDX, RAX
; 106: L0: 488BE5 MOV RSP, RBP
; 109: F8 CLC
; 10A: 5D POP RBP
; 10B: C3 RET
; 10C: L1: 488B158DFFFFFF MOV RDX, [RIP-115] ; 'A
; 113: EBF1 JMP L0
The reason I want this is so we can insert ASSERT statements that the compiler can completely remove. These statements are useful for mutation testing, where a piece of lisp code is mutated to see if the mutations are caught by a test suite. Assertions can turn correctness-
Changed in sbcl: | |
status: | New → Fix Committed |
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
If I change the first test there to (<= a 0), then the optimization works. This suggests to me that most of the logic is already there in the type propagator.