20-promote-sign.scm (1145B)
1 ;; tests/cc-cg/20-promote-sign.scm — integer promotion preserves sign 2 ;; (§A.6 of docs/CC-PUNCHLIST.md). 3 ;; 4 ;; Models: signed char x = -1; return ((int)x + 2) == 1; 5 ;; If promotion doesn't sign-extend, the i8 -1 reads as 255 and 6 ;; 255+2 == 257 (mod 256 == 1) — exit code can't distinguish 1 vs 7 ;; 1 directly. So we instead compare the post-promote post-add 8 ;; value against 1 as a 64-bit comparison: properly-promoted 9 ;; -1 + 2 == 0x0000000000000001; without sext, 0xFF + 2 == 0x101. 10 ;; The %ifelse_eq compares full registers, so the 0x101 case fails 11 ;; → exit 0; the canonical 1 case → exit 1. 12 13 (let ((cg (cg-init))) 14 (cg-fn-begin cg "main" '() %t-i32) 15 (let* ((off-x (cg-alloc-slot cg 1 1)) 16 (sym-x (%sym "x" 'var 'auto %t-i8 off-x))) 17 ;; x = -1 18 (cg-push-sym cg sym-x) 19 (cg-push-imm cg %t-i8 -1) 20 (cg-assign cg) (cg-pop cg) 21 ;; (int)x + 2 == 1 22 (cg-push-sym cg sym-x) 23 (cg-load cg) 24 (cg-promote cg) 25 (cg-push-imm cg %t-i32 2) 26 (cg-arith-conv cg) 27 (cg-binop cg 'add) 28 (cg-push-imm cg %t-i32 1) 29 (cg-binop cg 'eq) 30 (cg-return cg)) 31 (cg-fn-end cg) 32 (write-bv-fd 1 (cg-finish cg)))