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