From 57579a37cd99283e946ecb8a8b582997f2c59dfe Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Thu, 23 Jul 2026 03:37:26 +0000 Subject: [PATCH 18/25] 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 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 8e625a48..a4094305 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -2947,6 +2947,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(ord))); + } else { MIR_TODO(state, "Call intrinsic \"" << te->name << "\" - " << terminator); } -- 2.43.0