From 67bf3ebc32e21bdc9f6ac4639f3b1fad4509e885 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 13 Aug 2026 10:22:30 +0800 Subject: [PATCH] Explain LoongArch f16 NaN-boxing in inline asm The psABI leaves the upper bits of a widened f16 value undefined, so the NaN-boxing here isn't ABI-required. It's intentional: it matches LLVM's own codegen and avoids an f16 value being mistaken for a valid f32 value. Update the comment to reflect this. --- compiler/rustc_codegen_llvm/src/asm.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 0f74f5e81d684..1d14e31ffa94f 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -1256,7 +1256,10 @@ fn llvm_fixup_input<'ll, 'tcx>( (LoongArch(LoongArchInlineAsmRegClass::freg), BackendRepr::Scalar(s)) if s.primitive() == Primitive::Float(Float::F16) => { - // Smaller floats are always "NaN-boxed" inside larger floats on LoongArch. + // The LoongArch psABI only requires the upper bits to be widened to + // GRLEN, leaving them undefined. We NaN-box instead (set all upper + // bits to 1), matching LLVM's own codegen, to avoid an `f16` value + // being mistaken for a valid `f32` value. let value = bx.bitcast(value, bx.type_i16()); let value = bx.zext(value, bx.type_i32()); let value = bx.or(value, bx.const_u32(0xFFFF_0000));