[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