From f33bc24954ec242bbc7fa6af6f365c8e41443b52 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Thu, 23 Jul 2026 03:37:26 +0000
Subject: [PATCH 22/30] hir_conv: implement the three_way_compare intrinsic in
 const-eval

Used by integer signum/cmp in const context since ~1.75; jiff 0.2.23
evaluates `i64::signum` at compile time and hit the MIR TODO. Result is
core::cmp::Ordering's tag byte (-1/0/1), matching codegen_c's runtime
lowering (`.TAG = a == b ? 0 : (a < b ? -1 : 1)`).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wCVW89GjmNyYviEcANPHM
---
 src/hir_conv/constant_evaluation.cpp | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 15c54ea7..a4ddb641 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -2930,6 +2930,25 @@ namespace HIR {
                 else if( te->name == "is_val_statically_known" ) {
                     dst.write_uint(state, 8, e.args.at(0).is_Constant() || e.args.at(0).is_Borrow());
                 }
+                else if( te->name == "three_way_compare" ) {
+                    auto ty = local_state.monomorph_expand(te->params.m_types.at(0));
+                    MIR_ASSERT(state, ty.data().is_Primitive(), "`three_way_compare` with non-primitive " << ty);
+                    auto ti = TypeInfo::for_type(ty);
+                    int8_t ord;
+                    if( ti.ty == TypeInfo::Signed ) {
+                        auto a = local_state.read_param_sint(ti.bits, e.args.at(0));
+                        auto b = local_state.read_param_sint(ti.bits, e.args.at(1));
+                        ord = (a == b) ? 0 : ((a < b) ? -1 : 1);
+                    }
+                    else {
+                        auto a = local_state.read_param_uint(ti.bits, e.args.at(0));
+                        auto b = local_state.read_param_uint(ti.bits, e.args.at(1));
+                        ord = (a == b) ? 0 : ((a < b) ? -1 : 1);
+                    }
+                    // Result is `core::cmp::Ordering` (repr(i8): Less=-1, Equal=0, Greater=1),
+                    // written as the tag byte (matches codegen_c's `.TAG = ...`)
+                    dst.write_uint(state, 8, U128(static_cast<uint8_t>(ord)));
+                }
                 else {
                     MIR_TODO(state, "Call intrinsic \"" << te->name << "\" - " << terminator);
                 }
-- 
2.43.0

