fix(std): render integer formatter extremes — i64::MIN and unsigned all-ones [F0.8]
Resolves issue 0090. The `{}` integer formatter mis-rendered both ends of
the 64-bit range:
- `int_to_string` computed the magnitude as `0 - n`, which overflows for
`s64::MIN` (its magnitude is unrepresentable as a positive s64) — the
value stayed negative, the digit loop ran zero times, so only `-`
printed. It now extracts digits straight from `n` (per-digit
`|n % 10|`, `n` truncating toward zero), never negating MIN.
- `any_to_string`'s `case int:` formatted every integer as s64, so a u64
all-ones value printed as `-1`. There was no `uint` type-category to
distinguish signedness. Added an additive `type_is_unsigned(T)`
reflection builtin (static fold + dynamic interp/LLVM paths, mirroring
`type_name`), backed by the new `TypeTable.isUnsignedInt` predicate, and
a `uint_to_string` formatter (unsigned decimal via long-division over
four 16-bit limbs). `case int:` routes through `type_is_unsigned(type)`.
The 16-bit-limb split is factored into a shared `decompose_u16x4`, now
reused by `int_to_hex_string` (no second unsigned-math routine).
Regression: examples/0046-basic-int-formatter-extremes pins both extremes
plus a width spread; unit tests cover `isUnsignedInt`. Docs (specs.md
representation note, readme std API) updated for unsigned/extreme `{}`
behavior. IR snapshots refreshed for the two new std functions.
This commit is contained in:
@@ -189,38 +189,43 @@ if.merge.17: ; preds = %entry
|
||||
%icmpN = icmp slt i64 %loadN, 0
|
||||
%allocaN = alloca i1, align 1
|
||||
store i1 %icmpN, ptr %allocaN, align 1
|
||||
%loadN = load i1, ptr %allocaN, align 1
|
||||
br i1 %loadN, label %if.then.18, label %if.else.19
|
||||
|
||||
if.then.18: ; preds = %if.merge.17
|
||||
%loadN = load i64, ptr %alloca, align 8
|
||||
%sub = sub i64 0, %loadN
|
||||
br label %if.merge.20
|
||||
|
||||
if.else.19: ; preds = %if.merge.17
|
||||
%loadN = load i64, ptr %alloca, align 8
|
||||
br label %if.merge.20
|
||||
|
||||
if.merge.20: ; preds = %if.else.19, %if.then.18
|
||||
%bp = phi i64 [ %sub, %if.then.18 ], [ %loadN, %if.else.19 ]
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %bp, ptr %allocaN, align 8
|
||||
%call = call { ptr, i64 } @cstring(ptr %0, i64 20)
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
store { ptr, i64 } %call, ptr %allocaN, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 19, ptr %allocaN, align 8
|
||||
br label %while.hdr.21
|
||||
%loadN = load i64, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %loadN, ptr %allocaN, align 8
|
||||
br label %while.hdr.18
|
||||
|
||||
while.hdr.21: ; preds = %while.body.22, %if.merge.20
|
||||
while.hdr.18: ; preds = %if.merge.22, %if.merge.17
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%icmpN = icmp sgt i64 %loadN, 0
|
||||
br i1 %icmpN, label %while.body.22, label %while.exit.23
|
||||
%icmpN = icmp ne i64 %loadN, 0
|
||||
br i1 %icmpN, label %while.body.19, label %while.exit.20
|
||||
|
||||
while.body.22: ; preds = %while.hdr.21
|
||||
while.body.19: ; preds = %while.hdr.18
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%srem = srem i64 %loadN, 10
|
||||
%add = add i64 %srem, 48
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %srem, ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%icmpN = icmp slt i64 %loadN, 0
|
||||
br i1 %icmpN, label %if.then.21, label %if.merge.22
|
||||
|
||||
while.exit.20: ; preds = %while.hdr.18
|
||||
%loadN = load i1, ptr %allocaN, align 1
|
||||
br i1 %loadN, label %if.then.23, label %if.merge.24
|
||||
|
||||
if.then.21: ; preds = %while.body.19
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%sub = sub i64 0, %loadN
|
||||
store i64 %sub, ptr %allocaN, align 8
|
||||
br label %if.merge.22
|
||||
|
||||
if.merge.22: ; preds = %if.then.21, %while.body.19
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%add = add i64 %loadN, 48
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%igp.data = extractvalue { ptr, i64 } %loadN, 0
|
||||
@@ -233,34 +238,32 @@ while.body.22: ; preds = %while.hdr.21
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%subN = sub i64 %loadN, 1
|
||||
store i64 %subN, ptr %allocaN, align 8
|
||||
br label %while.hdr.21
|
||||
br label %while.hdr.18
|
||||
|
||||
while.exit.23: ; preds = %while.hdr.21
|
||||
%loadN = load i1, ptr %allocaN, align 1
|
||||
br i1 %loadN, label %if.then.24, label %if.merge.25
|
||||
|
||||
if.then.24: ; preds = %while.exit.23
|
||||
if.then.23: ; preds = %while.exit.20
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%igp.data21 = extractvalue { ptr, i64 } %loadN, 0
|
||||
%igp.ptr22 = getelementptr i8, ptr %igp.data21, i64 %loadN
|
||||
store i8 45, ptr %igp.ptr22, align 1
|
||||
%igp.data24 = extractvalue { ptr, i64 } %loadN, 0
|
||||
%igp.ptr25 = getelementptr i8, ptr %igp.data24, i64 %loadN
|
||||
store i8 45, ptr %igp.ptr25, align 1
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%subN = sub i64 %loadN, 1
|
||||
store i64 %subN, ptr %allocaN, align 8
|
||||
br label %if.merge.25
|
||||
br label %if.merge.24
|
||||
|
||||
if.merge.25: ; preds = %if.then.24, %while.exit.23
|
||||
if.merge.24: ; preds = %if.then.23, %while.exit.20
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%addN = add i64 %loadN, 1
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%subN = sub i64 20, %loadN
|
||||
%subN = sub i64 %subN, 1
|
||||
%subN = sub i64 19, %loadN
|
||||
%callN = call { ptr, i64 } @substr(ptr %0, { ptr, i64 } %loadN, i64 %addN, i64 %subN)
|
||||
ret { ptr, i64 } %callN
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @uint_to_string(ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @bool_to_string(ptr, i1) #0
|
||||
|
||||
@@ -270,6 +273,9 @@ declare ptr @float_to_string(ptr, double) #0
|
||||
; Function Attrs: nounwind
|
||||
declare void @hex_group(ptr, ptr, i64, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare [4 x i64] @decompose_u16x4(ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @int_to_hex_string(ptr, i64) #0
|
||||
|
||||
@@ -383,7 +389,7 @@ while.exit.4: ; preds = %while.hdr.2
|
||||
%loadN = load { ptr, i64 }, ptr %alloca, align 8
|
||||
%lenN = extractvalue { ptr, i64 } %loadN, 1
|
||||
%icmpN = icmp slt i64 %loadN, %lenN
|
||||
br i1 %icmpN, label %if.then.38, label %if.merge.39
|
||||
br i1 %icmpN, label %if.then.37, label %if.merge.38
|
||||
|
||||
if.then.5: ; preds = %while.body.3
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
@@ -401,9 +407,9 @@ if.else.6: ; preds = %while.body.3
|
||||
%ig.val21 = load i8, ptr %ig.ptr20, align 1
|
||||
%cmp.ext22 = zext i8 %ig.val21 to i64
|
||||
%icmpN = icmp eq i64 %cmp.ext22, 125
|
||||
br i1 %icmpN, label %if.then.29, label %if.else.30
|
||||
br i1 %icmpN, label %if.then.28, label %if.else.29
|
||||
|
||||
if.merge.7: ; preds = %if.merge.31, %if.merge.10
|
||||
if.merge.7: ; preds = %if.merge.30, %if.merge.10
|
||||
br label %while.hdr.2
|
||||
|
||||
if.then.8: ; preds = %if.then.5
|
||||
@@ -441,9 +447,9 @@ if.else.12: ; preds = %if.then.8
|
||||
%ig.val42 = load i8, ptr %ig.ptr41, align 1
|
||||
%cmp.ext43 = zext i8 %ig.val42 to i64
|
||||
%icmpN = icmp eq i64 %cmp.ext43, 123
|
||||
br i1 %icmpN, label %if.then.26, label %if.else.27
|
||||
br i1 %icmpN, label %if.then.25, label %if.else.26
|
||||
|
||||
if.merge.13: ; preds = %if.merge.28, %if.merge.15
|
||||
if.merge.13: ; preds = %if.merge.27, %if.merge.15
|
||||
br label %if.merge.10
|
||||
|
||||
if.then.14: ; preds = %if.then.11
|
||||
@@ -492,7 +498,7 @@ if.merge.15: ; preds = %if.then.14, %if.the
|
||||
store i64 %loadN, ptr %allocaN, align 8
|
||||
br label %if.merge.13
|
||||
|
||||
if.then.26: ; preds = %if.else.12
|
||||
if.then.25: ; preds = %if.else.12
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%callN = call { ptr, i64 } @concat(ptr %0, { ptr, i64 } %loadN, { ptr, i64 } { ptr @str.7, i64 36 })
|
||||
store { ptr, i64 } %callN, ptr %allocaN, align 8
|
||||
@@ -520,35 +526,35 @@ if.then.26: ; preds = %if.else.12
|
||||
store i64 %addN, ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
store i64 %loadN, ptr %allocaN, align 8
|
||||
br label %if.merge.28
|
||||
br label %if.merge.27
|
||||
|
||||
if.else.27: ; preds = %if.else.12
|
||||
if.else.26: ; preds = %if.else.12
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%addN = add i64 %loadN, 1
|
||||
store i64 %addN, ptr %allocaN, align 8
|
||||
br label %if.merge.28
|
||||
br label %if.merge.27
|
||||
|
||||
if.merge.28: ; preds = %if.else.27, %if.then.26
|
||||
if.merge.27: ; preds = %if.else.26, %if.then.25
|
||||
br label %if.merge.13
|
||||
|
||||
if.then.29: ; preds = %if.else.6
|
||||
if.then.28: ; preds = %if.else.6
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%addN = add i64 %loadN, 1
|
||||
%loadN = load { ptr, i64 }, ptr %alloca, align 8
|
||||
%lenN = extractvalue { ptr, i64 } %loadN, 1
|
||||
%icmpN = icmp slt i64 %addN, %lenN
|
||||
br i1 %icmpN, label %if.then.32, label %if.else.33
|
||||
br i1 %icmpN, label %if.then.31, label %if.else.32
|
||||
|
||||
if.else.30: ; preds = %if.else.6
|
||||
if.else.29: ; preds = %if.else.6
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%addN = add i64 %loadN, 1
|
||||
store i64 %addN, ptr %allocaN, align 8
|
||||
br label %if.merge.31
|
||||
br label %if.merge.30
|
||||
|
||||
if.merge.31: ; preds = %if.merge.34, %if.else.30
|
||||
if.merge.30: ; preds = %if.merge.33, %if.else.29
|
||||
br label %if.merge.7
|
||||
|
||||
if.then.32: ; preds = %if.then.29
|
||||
if.then.31: ; preds = %if.then.28
|
||||
%loadN = load { ptr, i64 }, ptr %alloca, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%addN = add i64 %loadN, 1
|
||||
@@ -557,18 +563,18 @@ if.then.32: ; preds = %if.then.29
|
||||
%ig.val106 = load i8, ptr %ig.ptr105, align 1
|
||||
%cmp.ext107 = zext i8 %ig.val106 to i64
|
||||
%icmpN = icmp eq i64 %cmp.ext107, 125
|
||||
br i1 %icmpN, label %if.then.35, label %if.else.36
|
||||
br i1 %icmpN, label %if.then.34, label %if.else.35
|
||||
|
||||
if.else.33: ; preds = %if.then.29
|
||||
if.else.32: ; preds = %if.then.28
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%addN = add i64 %loadN, 1
|
||||
store i64 %addN, ptr %allocaN, align 8
|
||||
br label %if.merge.34
|
||||
br label %if.merge.33
|
||||
|
||||
if.merge.34: ; preds = %if.merge.37, %if.else.33
|
||||
br label %if.merge.31
|
||||
if.merge.33: ; preds = %if.merge.36, %if.else.32
|
||||
br label %if.merge.30
|
||||
|
||||
if.then.35: ; preds = %if.then.32
|
||||
if.then.34: ; preds = %if.then.31
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%callN = call { ptr, i64 } @concat(ptr %0, { ptr, i64 } %loadN, { ptr, i64 } { ptr @str.10, i64 36 })
|
||||
store { ptr, i64 } %callN, ptr %allocaN, align 8
|
||||
@@ -596,18 +602,18 @@ if.then.35: ; preds = %if.then.32
|
||||
store i64 %addN, ptr %allocaN, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
store i64 %loadN, ptr %allocaN, align 8
|
||||
br label %if.merge.37
|
||||
br label %if.merge.36
|
||||
|
||||
if.else.36: ; preds = %if.then.32
|
||||
if.else.35: ; preds = %if.then.31
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%addN = add i64 %loadN, 1
|
||||
store i64 %addN, ptr %allocaN, align 8
|
||||
br label %if.merge.37
|
||||
br label %if.merge.36
|
||||
|
||||
if.merge.37: ; preds = %if.else.36, %if.then.35
|
||||
br label %if.merge.34
|
||||
if.merge.36: ; preds = %if.else.35, %if.then.34
|
||||
br label %if.merge.33
|
||||
|
||||
if.then.38: ; preds = %while.exit.4
|
||||
if.then.37: ; preds = %while.exit.4
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%callN = call { ptr, i64 } @concat(ptr %0, { ptr, i64 } %loadN, { ptr, i64 } { ptr @str.13, i64 36 })
|
||||
store { ptr, i64 } %callN, ptr %allocaN, align 8
|
||||
@@ -630,9 +636,9 @@ if.then.38: ; preds = %while.exit.4
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
%callN = call { ptr, i64 } @concat(ptr %0, { ptr, i64 } %loadN, { ptr, i64 } { ptr @str.15, i64 4 })
|
||||
store { ptr, i64 } %callN, ptr %allocaN, align 8
|
||||
br label %if.merge.39
|
||||
br label %if.merge.38
|
||||
|
||||
if.merge.39: ; preds = %if.then.38, %while.exit.4
|
||||
if.merge.38: ; preds = %if.then.37, %while.exit.4
|
||||
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
|
||||
ret { ptr, i64 } %loadN
|
||||
}
|
||||
@@ -846,13 +852,13 @@ if.merge.1: ; preds = %entry
|
||||
store ptr %callN, ptr %allocaN, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
%icmpN = icmp eq ptr %loadN, null
|
||||
br i1 %icmpN, label %if.then.40, label %if.merge.41
|
||||
br i1 %icmpN, label %if.then.39, label %if.merge.40
|
||||
|
||||
if.then.40: ; preds = %if.merge.1
|
||||
if.then.39: ; preds = %if.merge.1
|
||||
call void @print__ct_sfe783e2b27a4beff__pack(ptr @__sx_default_context)
|
||||
ret i32 1
|
||||
|
||||
if.merge.41: ; preds = %if.merge.1
|
||||
if.merge.40: ; preds = %if.merge.1
|
||||
%allocaN = alloca ptr, align 8
|
||||
%callN = call ptr @sel_registerName(ptr @str.18)
|
||||
store ptr %callN, ptr %allocaN, align 8
|
||||
@@ -866,13 +872,13 @@ if.merge.41: ; preds = %if.merge.1
|
||||
store ptr %icall, ptr %allocaN, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
%icmpN = icmp eq ptr %loadN, null
|
||||
br i1 %icmpN, label %if.then.42, label %if.merge.43
|
||||
br i1 %icmpN, label %if.then.41, label %if.merge.42
|
||||
|
||||
if.then.42: ; preds = %if.merge.41
|
||||
if.then.41: ; preds = %if.merge.40
|
||||
call void @print__ct_scaebdbbd10c81716__pack(ptr @__sx_default_context)
|
||||
ret i32 1
|
||||
|
||||
if.merge.43: ; preds = %if.merge.41
|
||||
if.merge.42: ; preds = %if.merge.40
|
||||
%allocaN = alloca ptr, align 8
|
||||
%callN = call ptr @sel_registerName(ptr @str.19)
|
||||
store ptr %callN, ptr %allocaN, align 8
|
||||
@@ -890,13 +896,13 @@ if.merge.43: ; preds = %if.merge.41
|
||||
store ptr %icallN, ptr %allocaN, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
%icmpN = icmp eq ptr %loadN, null
|
||||
br i1 %icmpN, label %if.then.44, label %if.merge.45
|
||||
br i1 %icmpN, label %if.then.43, label %if.merge.44
|
||||
|
||||
if.then.44: ; preds = %if.merge.43
|
||||
if.then.43: ; preds = %if.merge.42
|
||||
call void @print__ct_s7c1052877b8cc801__pack(ptr @__sx_default_context)
|
||||
ret i32 1
|
||||
|
||||
if.merge.45: ; preds = %if.merge.43
|
||||
if.merge.44: ; preds = %if.merge.42
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
|
||||
Reference in New Issue
Block a user