[llvm] a4c7c48 - [SPIR-V] Preserve sign and payload when printing NaN as hex float (#212438)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 5 01:10:26 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-08-05T10:10:21+02:00
New Revision: a4c7c486b76b0fa0e894a5871a7599fb18f8ddd5
URL: https://github.com/llvm/llvm-project/commit/a4c7c486b76b0fa0e894a5871a7599fb18f8ddd5
DIFF: https://github.com/llvm/llvm-project/commit/a4c7c486b76b0fa0e894a5871a7599fb18f8ddd5.diff
LOG: [SPIR-V] Preserve sign and payload when printing NaN as hex float (#212438)
NaN was always printed as the canonical `0x1.8p+<MaxExp>`, silently
dropping the sign bit and any signaling/payload bits
Discussed in https://github.com/llvm/llvm-project/pull/212295
Added:
Modified:
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
llvm/test/CodeGen/SPIRV/literals.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
index 936e4976311b5..8a2618b5309a9 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
@@ -14,12 +14,14 @@
#include "SPIRV.h"
#include "SPIRVBaseInfo.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
using namespace llvm;
using namespace llvm::SPIRV;
@@ -93,12 +95,20 @@ void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI,
// require hex float notation.
if (FP.isInfinity() || FP.isNaN()) {
unsigned MaxExp = APFloat::semanticsMaxExponent(FP.getSemantics()) + 1;
+ if (FP.isNegative())
+ O << '-';
if (FP.isInfinity()) {
- if (FP.isNegative())
- O << '-';
O << "0x1p+" << MaxExp;
} else {
- O << "0x1.8p+" << MaxExp;
+ unsigned MantissaBits =
+ APFloat::semanticsPrecision(FP.getSemantics()) - 1;
+ uint64_t Mantissa = Imm & (maskTrailingOnes<uint64_t>(MantissaBits));
+ unsigned Pad = alignTo(MantissaBits, 4) - MantissaBits;
+ std::string Hex = utohexstr(Mantissa << Pad, /*LowerCase=*/true,
+ (MantissaBits + Pad) / 4);
+ while (Hex.size() > 1 && Hex.back() == '0')
+ Hex.pop_back();
+ O << "0x1." << Hex << "p+" << MaxExp;
}
return;
}
diff --git a/llvm/test/CodeGen/SPIRV/literals.ll b/llvm/test/CodeGen/SPIRV/literals.ll
index 81a50ecb8f28c..45dae75c28b13 100644
--- a/llvm/test/CodeGen/SPIRV/literals.ll
+++ b/llvm/test/CodeGen/SPIRV/literals.ll
@@ -12,9 +12,12 @@
; CHECK-DAG: OpConstant %[[#F32]] 0x1p+128{{$}}
; CHECK-DAG: OpConstant %[[#F32]] -0x1p+128{{$}}
; CHECK-DAG: OpConstant %[[#F32]] 0x1.8p+128{{$}}
+; CHECK-DAG: OpConstant %[[#F32]] -0x1.8p+128{{$}}
+; CHECK-DAG: OpConstant %[[#F32]] 0x1.4p+128{{$}}
; CHECK-DAG: OpConstant %[[#F64]] 0x1p+1024{{$}}
; CHECK-DAG: OpConstant %[[#F64]] -0x1p+1024{{$}}
; CHECK-DAG: OpConstant %[[#F64]] 0x1.8p+1024{{$}}
+; CHECK-DAG: OpConstant %[[#F64]] 0x1.0000000000001p+1024{{$}}
define void @main() {
entry:
@@ -30,11 +33,17 @@ entry:
store float 0xFFF0000000000000, ptr %ninf, align 4
%nan = alloca float, align 4
store float 0x7FF8000000000000, ptr %nan, align 4
+ %nnan = alloca float, align 4
+ store float 0xFFF8000000000000, ptr %nnan, align 4
+ %snan = alloca float, align 4
+ store float 0x7FF4000000000000, ptr %snan, align 4
%dinf = alloca double, align 8
store double 0x7FF0000000000000, ptr %dinf, align 8
%dninf = alloca double, align 8
store double 0xFFF0000000000000, ptr %dninf, align 8
%dnan = alloca double, align 8
store double 0x7FF8000000000000, ptr %dnan, align 8
+ %dsnan = alloca double, align 8
+ store double 0x7FF0000000000001, ptr %dsnan, align 8
ret void
}
More information about the llvm-commits
mailing list