[llvm] [AsmParser] Fix crash when hex literal exceeds 16-bit float range (PR #172669)

Miloš Poletanović via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 17 07:31:04 PST 2025


https://github.com/milos1397 updated https://github.com/llvm/llvm-project/pull/172669

>From 876c3f52f1df4af4c63ab70ebfee9465fa848242 Mon Sep 17 00:00:00 2001
From: Milos Poletanovic <mpoletanovic at syrmia.com>
Date: Wed, 17 Dec 2025 16:06:29 +0100
Subject: [PATCH 1/2] [AsmParser] Fix crash when hex literal exceeds 16-bit
 float range

---
 llvm/lib/AsmParser/LLLexer.cpp | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index ef1515ca10494..73b57ec3064cd 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -1129,16 +1129,26 @@ lltok::Kind LLLexer::Lex0x() {
     HexToIntPair(TokStart+3, CurPtr, Pair);
     APFloatVal = APFloat(APFloat::PPCDoubleDouble(), APInt(128, Pair));
     return lltok::APFloat;
-  case 'H':
-    APFloatVal = APFloat(APFloat::IEEEhalf(),
-                         APInt(16,HexIntToVal(TokStart+3, CurPtr)));
+  case 'H': {
+    uint64_t Val = HexIntToVal(TokStart + 3, CurPtr);
+    if (!llvm::isUIntN(16, Val)) {
+      LexError("hexadecimal constant too large for half (16-bit)");
+      return lltok::Error;
+    }
+    APFloatVal = APFloat(APFloat::IEEEhalf(), APInt(16, Val));
     return lltok::APFloat;
-  case 'R':
+  }
+  case 'R': {
     // Brain floating point
-    APFloatVal = APFloat(APFloat::BFloat(),
-                         APInt(16, HexIntToVal(TokStart + 3, CurPtr)));
+    uint64_t Val = HexIntToVal(TokStart + 3, CurPtr);
+    if (!llvm::isUIntN(16, Val)) {
+      LexError("hexadecimal constant too large for bfloat (16-bit)");
+      return lltok::Error;
+    }
+    APFloatVal = APFloat(APFloat::BFloat(), APInt(16, Val));
     return lltok::APFloat;
   }
+  }
 }
 
 /// Lex tokens for a label or a numeric constant, possibly starting with -.

>From 78d14a76bac7c9448c11f19520e71633e9eac3e3 Mon Sep 17 00:00:00 2001
From: Milos Poletanovic <mpoletanovic at syrmia.com>
Date: Wed, 17 Dec 2025 16:48:39 +0100
Subject: [PATCH 2/2] Added a test.

---
 llvm/test/Assembler/hex-float-overflow.ll | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 llvm/test/Assembler/hex-float-overflow.ll

diff --git a/llvm/test/Assembler/hex-float-overflow.ll b/llvm/test/Assembler/hex-float-overflow.ll
new file mode 100644
index 0000000000000..ba102fe7d544e
--- /dev/null
+++ b/llvm/test/Assembler/hex-float-overflow.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: not opt -S -disable-output < %s --check-prefix=HALF 2>&1
+; RUN: not opt -S -disable-output < %s --check-prefix=BFLOAT 2>&1
+
+; Test that providing a hex literal larger than 16 bits for half-precision
+; triggers a proper error message instead of a compiler crash.
+
+define half @test_half_overflow() {
+; HALF: error: hexadecimal constant too large for half (16-bit)
+  %1 = fadd half 0xH5F2F00, 0xH0000
+  ret half %1
+}
+
+define bfloat @test_bfloat_overflow() {
+; BFLOAT: error: hexadecimal constant too large for bfloat (16-bit)
+  %1 = fadd bfloat 0xR5F2F00, 0xR0000
+  ret bfloat %1
+}
+



More information about the llvm-commits mailing list