[llvm] [Analysis] Adding convert_from_arbitrary_fp support in computeKnownFPClass. (PR #208585)
Chirag Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 15 01:27:21 PDT 2026
https://github.com/ChiragPatel8 updated https://github.com/llvm/llvm-project/pull/208585
>From ad7a5b62e2f0aad161be5a54e4f0b1a3dcf590c1 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Fri, 10 Jul 2026 01:36:24 +0530
Subject: [PATCH 01/18] [Analysis] Initial implementation of
convert_from_arbitrary_fp computeKnownFPClass.
---
llvm/lib/Analysis/ValueTracking.cpp | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 59631873305d4..239c3c81723c2 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5709,6 +5709,34 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Known.knownNot(fcNan | fcInf | fcNegative);
break;
}
+ case Intrinsic::convert_from_arbitrary_fp: {
+ auto *MD = cast<MetadataAsValue>(II->getArgOperand(1))->getMetadata();
+ StringRef FormatStr = cast<MDString>(MD)->getString();
+ const fltSemantics *SrcSemanticsPtr = APFloat::getArbitraryFPSemantics(FormatStr);
+ if (!SrcSemanticsPtr)
+ break;
+
+ const fltSemantics SrcSemantics = *SrcSemanticsPtr;
+ const fltSemantics DestSemantics = II->getType()->getFltSemantics();
+
+ int SrcMaxExp = APFloat::semanticsMaxExponent(SrcSemantics);
+ int DestMaxExp = APFloat::semanticsMaxExponent(DestSemantics);
+
+ if (!APFloat::semanticsHasInf(SrcSemantics) &&
+ (SrcMaxExp <= DestMaxExp))
+ Known.KnownFPClasses &= ~fcInf;
+
+ const bool SrcSupportsNaN = APFloat::semanticsHasNaN(SrcSemantics);
+ // If the source format doesn't have NaN, the output cannot be NaN
+ if (!SrcSupportsNaN)
+ Known.KnownFPClasses &= ~fcNan;
+
+ // override compile-time flag
+ if (II->hasNoNaNs())
+ Known.KnownFPClasses &= ~fcNan;
+
+ break;
+ }
default:
break;
}
>From 8074c15904cf63b0c98bd92c3568539795ffddba Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Fri, 10 Jul 2026 04:59:36 +0530
Subject: [PATCH 02/18] minor format cleanup
---
llvm/lib/Analysis/ValueTracking.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 239c3c81723c2..144408b52bad1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5712,9 +5712,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
case Intrinsic::convert_from_arbitrary_fp: {
auto *MD = cast<MetadataAsValue>(II->getArgOperand(1))->getMetadata();
StringRef FormatStr = cast<MDString>(MD)->getString();
- const fltSemantics *SrcSemanticsPtr = APFloat::getArbitraryFPSemantics(FormatStr);
+ const fltSemantics *SrcSemanticsPtr =
+ APFloat::getArbitraryFPSemantics(FormatStr);
if (!SrcSemanticsPtr)
- break;
+ break;
const fltSemantics SrcSemantics = *SrcSemanticsPtr;
const fltSemantics DestSemantics = II->getType()->getFltSemantics();
@@ -5722,8 +5723,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
int SrcMaxExp = APFloat::semanticsMaxExponent(SrcSemantics);
int DestMaxExp = APFloat::semanticsMaxExponent(DestSemantics);
- if (!APFloat::semanticsHasInf(SrcSemantics) &&
- (SrcMaxExp <= DestMaxExp))
+ if (!APFloat::semanticsHasInf(SrcSemantics) && (SrcMaxExp <= DestMaxExp))
Known.KnownFPClasses &= ~fcInf;
const bool SrcSupportsNaN = APFloat::semanticsHasNaN(SrcSemantics);
>From fb3802e3046f658915fcf07f7bc58ad96ad68f12 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Fri, 10 Jul 2026 21:00:32 +0530
Subject: [PATCH 03/18] [test] Adding testcase for llvm.convert.from.arbitrary.
---
.../known-fp-class-convert-arbitrary.ll | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
diff --git a/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll b/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
new file mode 100644
index 0000000000000..6a43bb77b3f5a
--- /dev/null
+++ b/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+; Test 1: Source format "Float8E4M3FN" structurally does not support NaN or Infinity.
+; InstCombine should completely optimize away the is.fpclass checks to 'false'.
+define i1 @test_no_nan_no_inf(i8 %bits) {
+; CHECK-LABEL: @test_no_nan_no_inf(
+; CHECK-NEXT: ret i1 false
+;
+ ; Convert from a format that has no NaN and no Infinity
+ %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float8E4M3FN")
+
+ ; Query if the result is either a NaN or an Infinity (fcNaN | fcInf = 3 | 512 = 515)
+ %is.nan.or.inf = call i1 @llvm.is.fpclass.f32(float %fp, i32 515)
+ ret i1 %is.nan.or.inf
+}
+
+; Test 2: Fast Math Flags (nnan) should also be respected and clear fcNaN.
+define i1 @test_fmf_nnan(i8 %bits) {
+; CHECK-LABEL: @test_fmf_nnan(
+; CHECK-NEXT: ret i1 false
+;
+ ; Even if the format supported NaN, the 'nnan' flag forces fcNaN to clear
+ %fp = call nnan float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float8E5M2")
+
+ ; Query if the result is a NaN (fcNaN = 3)
+ %is.nan = call i1 @llvm.is.fpclass.f32(float %fp, i32 3)
+ ret i1 %is.nan
+}
+
+declare float @llvm.convert.from.arbitrary.fp(i8, metadata)
+declare i1 @llvm.is.fpclass.f32(float, i32)
\ No newline at end of file
>From 57db066973fee631fde0c69838f8e1bc8f89464f Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Fri, 10 Jul 2026 21:17:14 +0530
Subject: [PATCH 04/18] Adding compile-time override flag for
convert_from_arbitrary_fp
---
llvm/lib/Analysis/ValueTracking.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 144408b52bad1..1fd038a4b8eb4 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5734,6 +5734,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// override compile-time flag
if (II->hasNoNaNs())
Known.KnownFPClasses &= ~fcNan;
+ if (II->hasNoInfs())
+ Known.KnownFPClasses &= ~fcInf;
break;
}
>From 15d889380255210826091685f32aed70119e0927 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Fri, 10 Jul 2026 21:29:32 +0530
Subject: [PATCH 05/18] Fixing testcase, selected proper format with no nan and
no inf.
---
.../ValueTracking/known-fp-class-convert-arbitrary.ll | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll b/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
index 6a43bb77b3f5a..843058fd82a7b 100644
--- a/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
+++ b/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
@@ -1,14 +1,14 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
-; Test 1: Source format "Float8E4M3FN" structurally does not support NaN or Infinity.
+; Test 1: Source format "Float4E2M1FN" structurally does not support NaN or Infinity.
; InstCombine should completely optimize away the is.fpclass checks to 'false'.
define i1 @test_no_nan_no_inf(i8 %bits) {
; CHECK-LABEL: @test_no_nan_no_inf(
; CHECK-NEXT: ret i1 false
;
; Convert from a format that has no NaN and no Infinity
- %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float8E4M3FN")
+ %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float4E2M1FN")
; Query if the result is either a NaN or an Infinity (fcNaN | fcInf = 3 | 512 = 515)
%is.nan.or.inf = call i1 @llvm.is.fpclass.f32(float %fp, i32 515)
>From 168b01fbff17bc10f2272b31a2b003d3c9218b93 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Fri, 10 Jul 2026 23:14:09 +0530
Subject: [PATCH 06/18] 1. Fixed vector support segfault in
@llvm.convert.from.arbitrary.fp 2. Added vector testcase in ll file 3. format
cleanup, removed useless code.
---
llvm/lib/Analysis/ValueTracking.cpp | 25 ++++++-------------
.../known-fp-class-convert-arbitrary.ll | 18 ++++++++++++-
2 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1fd038a4b8eb4..1c4aa96351148 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5712,30 +5712,19 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
case Intrinsic::convert_from_arbitrary_fp: {
auto *MD = cast<MetadataAsValue>(II->getArgOperand(1))->getMetadata();
StringRef FormatStr = cast<MDString>(MD)->getString();
- const fltSemantics *SrcSemanticsPtr =
- APFloat::getArbitraryFPSemantics(FormatStr);
- if (!SrcSemanticsPtr)
- break;
-
- const fltSemantics SrcSemantics = *SrcSemanticsPtr;
- const fltSemantics DestSemantics = II->getType()->getFltSemantics();
+ const fltSemantics SrcSemantics =
+ *(APFloat::getArbitraryFPSemantics(FormatStr));
- int SrcMaxExp = APFloat::semanticsMaxExponent(SrcSemantics);
- int DestMaxExp = APFloat::semanticsMaxExponent(DestSemantics);
+ Type *DestTy = II->getType()->getScalarType();
+ const fltSemantics DestSemantics = DestTy->getFltSemantics();
- if (!APFloat::semanticsHasInf(SrcSemantics) && (SrcMaxExp <= DestMaxExp))
- Known.KnownFPClasses &= ~fcInf;
+ if (!APFloat::semanticsHasInf(SrcSemantics))
+ Known.knownNot(fcInf);
const bool SrcSupportsNaN = APFloat::semanticsHasNaN(SrcSemantics);
// If the source format doesn't have NaN, the output cannot be NaN
if (!SrcSupportsNaN)
- Known.KnownFPClasses &= ~fcNan;
-
- // override compile-time flag
- if (II->hasNoNaNs())
- Known.KnownFPClasses &= ~fcNan;
- if (II->hasNoInfs())
- Known.KnownFPClasses &= ~fcInf;
+ Known.knownNot(fcNan);
break;
}
diff --git a/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll b/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
index 843058fd82a7b..a84caf0d72104 100644
--- a/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
+++ b/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
@@ -28,5 +28,21 @@ define i1 @test_fmf_nnan(i8 %bits) {
ret i1 %is.nan
}
+; Test 3: Vector support. The underlying scalar format "Float4E2M1FN" lacks NaN/Inf.
+; The vector check should optimize completely down to a zeroinitializer (all false).
+define <4 x i1> @test_vector_no_nan_no_inf(<4 x i8> %bits) {
+; CHECK-LABEL: @test_vector_no_nan_no_inf(
+; CHECK-NEXT: ret <4 x i1> zeroinitializer
+;
+ ; Convert a vector of bits into a vector of floats
+ %fp = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8> %bits, metadata !"Float4E2M1FN")
+
+ ; Query if any lane is NaN or Infinity (3 | 512 = 515)
+ %is.nan.or.inf = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %fp, i32 515)
+ ret <4 x i1> %is.nan.or.inf
+}
+
declare float @llvm.convert.from.arbitrary.fp(i8, metadata)
-declare i1 @llvm.is.fpclass.f32(float, i32)
\ No newline at end of file
+declare i1 @llvm.is.fpclass.f32(float, i32)
+declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8>, metadata)
+declare <4 x i1> @llvm.is.fpclass.v4f32(<4 x float>, i32)
>From fad92c560ac82b442a4ee3ca500a13717c73c8f0 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Fri, 10 Jul 2026 23:22:37 +0530
Subject: [PATCH 07/18] simplfy changes
---
llvm/lib/Analysis/ValueTracking.cpp | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1c4aa96351148..838a2c7033ec8 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5715,17 +5715,11 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
const fltSemantics SrcSemantics =
*(APFloat::getArbitraryFPSemantics(FormatStr));
- Type *DestTy = II->getType()->getScalarType();
- const fltSemantics DestSemantics = DestTy->getFltSemantics();
-
+ if (!APFloat::semanticsHasNaN(SrcSemantics))
+ Known.knownNot(fcNan);
if (!APFloat::semanticsHasInf(SrcSemantics))
Known.knownNot(fcInf);
- const bool SrcSupportsNaN = APFloat::semanticsHasNaN(SrcSemantics);
- // If the source format doesn't have NaN, the output cannot be NaN
- if (!SrcSupportsNaN)
- Known.knownNot(fcNan);
-
break;
}
default:
>From f003c6fbe538032c5254e6751db88dfb2e994f15 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Sat, 11 Jul 2026 00:03:00 +0530
Subject: [PATCH 08/18] moving testfile to proper location.
---
.../known-fp-class-convert-arbitrary.ll | 48 -------------------
.../Attributor/nofpclass-arbitrary-fp.ll | 41 ++++++++++++++++
2 files changed, 41 insertions(+), 48 deletions(-)
delete mode 100644 llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
create mode 100644 llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
diff --git a/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll b/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
deleted file mode 100644
index a84caf0d72104..0000000000000
--- a/llvm/test/Analysis/ValueTracking/known-fp-class-convert-arbitrary.ll
+++ /dev/null
@@ -1,48 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=instcombine < %s | FileCheck %s
-
-; Test 1: Source format "Float4E2M1FN" structurally does not support NaN or Infinity.
-; InstCombine should completely optimize away the is.fpclass checks to 'false'.
-define i1 @test_no_nan_no_inf(i8 %bits) {
-; CHECK-LABEL: @test_no_nan_no_inf(
-; CHECK-NEXT: ret i1 false
-;
- ; Convert from a format that has no NaN and no Infinity
- %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float4E2M1FN")
-
- ; Query if the result is either a NaN or an Infinity (fcNaN | fcInf = 3 | 512 = 515)
- %is.nan.or.inf = call i1 @llvm.is.fpclass.f32(float %fp, i32 515)
- ret i1 %is.nan.or.inf
-}
-
-; Test 2: Fast Math Flags (nnan) should also be respected and clear fcNaN.
-define i1 @test_fmf_nnan(i8 %bits) {
-; CHECK-LABEL: @test_fmf_nnan(
-; CHECK-NEXT: ret i1 false
-;
- ; Even if the format supported NaN, the 'nnan' flag forces fcNaN to clear
- %fp = call nnan float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float8E5M2")
-
- ; Query if the result is a NaN (fcNaN = 3)
- %is.nan = call i1 @llvm.is.fpclass.f32(float %fp, i32 3)
- ret i1 %is.nan
-}
-
-; Test 3: Vector support. The underlying scalar format "Float4E2M1FN" lacks NaN/Inf.
-; The vector check should optimize completely down to a zeroinitializer (all false).
-define <4 x i1> @test_vector_no_nan_no_inf(<4 x i8> %bits) {
-; CHECK-LABEL: @test_vector_no_nan_no_inf(
-; CHECK-NEXT: ret <4 x i1> zeroinitializer
-;
- ; Convert a vector of bits into a vector of floats
- %fp = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8> %bits, metadata !"Float4E2M1FN")
-
- ; Query if any lane is NaN or Infinity (3 | 512 = 515)
- %is.nan.or.inf = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %fp, i32 515)
- ret <4 x i1> %is.nan.or.inf
-}
-
-declare float @llvm.convert.from.arbitrary.fp(i8, metadata)
-declare i1 @llvm.is.fpclass.f32(float, i32)
-declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8>, metadata)
-declare <4 x i1> @llvm.is.fpclass.v4f32(<4 x float>, i32)
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
new file mode 100644
index 0000000000000..4de5d74b03a54
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+
+; Test 1: Float4E2M1FN has absolutely no NaN or Inf support.
+; The Attributor should deduce and attach nofpclass(nan inf) to the function return.
+define float @ret_arbitrary_fp_no_nan_no_inf(i8 %bits) {
+; CHECK-LABEL: define nofpclass(nan inf) float @ret_arbitrary_fp_no_nan_no_inf
+; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: %fp = call nofpclass(nan inf) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: ret float %fp
+;
+ %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float4E2M1FN")
+ ret float %fp
+}
+
+; Test 2: Float8E4M3FN supports NaNs but lacks Infinities (NaNOnly).
+; The Attributor should safely deduce and attach nofpclass(inf) to the function return.
+define float @ret_arbitrary_fp_nan_only(i8 %bits) {
+; CHECK-LABEL: define nofpclass(inf) float @ret_arbitrary_fp_nan_only
+; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: %fp = call nofpclass(inf) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float8E4M3FN") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: ret float %fp
+;
+ %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float8E4M3FN")
+ ret float %fp
+}
+
+; Test 3: Vector variation checking that your getScalarType() unpacks cleanly.
+; The Attributor should successfully attach nofpclass(nan inf) to the returning vector topology.
+define <4 x float> @ret_arbitrary_fp_vector(<4 x i8> %bits) {
+; CHECK-LABEL: define nofpclass(nan inf) <4 x float> @ret_arbitrary_fp_vector
+; CHECK-SAME: (<4 x i8> [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: %fp = call nofpclass(nan inf) <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i8(<4 x i8> [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: ret <4 x float> %fp
+;
+ %fp = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8> %bits, metadata !"Float4E2M1FN")
+ ret <4 x float> %fp
+}
+
+declare float @llvm.convert.from.arbitrary.fp(i8, metadata)
+declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8>, metadata)
>From bf67fba4e31462b5c623785744edc4009966e556 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Sat, 11 Jul 2026 00:07:08 +0530
Subject: [PATCH 09/18] Removing unnecessary tag
---
llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
index 4de5d74b03a54..175bba96a5086 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK
; Test 1: Float4E2M1FN has absolutely no NaN or Inf support.
; The Attributor should deduce and attach nofpclass(nan inf) to the function return.
>From 13fde9fae1f9dee64e1b6fb08b689a87b114fa02 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Sat, 11 Jul 2026 00:13:01 +0530
Subject: [PATCH 10/18] removing unnecessary LLM generated comment
---
llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
index 175bba96a5086..a2074b527e403 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -25,7 +25,7 @@ define float @ret_arbitrary_fp_nan_only(i8 %bits) {
ret float %fp
}
-; Test 3: Vector variation checking that your getScalarType() unpacks cleanly.
+; Test 3: Vector variation.
; The Attributor should successfully attach nofpclass(nan inf) to the returning vector topology.
define <4 x float> @ret_arbitrary_fp_vector(<4 x i8> %bits) {
; CHECK-LABEL: define nofpclass(nan inf) <4 x float> @ret_arbitrary_fp_vector
>From a1854f7664e296e14416c269127d72f6df841a42 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Sat, 11 Jul 2026 07:23:51 +0530
Subject: [PATCH 11/18] Testcases refactoring
---
.../Attributor/nofpclass-arbitrary-fp.ll | 20 +++++++------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
index a2074b527e403..6bca7d2656c4e 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -1,10 +1,8 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK
-; Test 1: Float4E2M1FN has absolutely no NaN or Inf support.
-; The Attributor should deduce and attach nofpclass(nan inf) to the function return.
-define float @ret_arbitrary_fp_no_nan_no_inf(i8 %bits) {
-; CHECK-LABEL: define nofpclass(nan inf) float @ret_arbitrary_fp_no_nan_no_inf
+define float @ret_arbitrary_fp_nan_inf(i8 %bits) {
+; CHECK-LABEL: define nofpclass(nan inf) float @ret_arbitrary_fp_nan_inf
; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: %fp = call nofpclass(nan inf) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret float %fp
@@ -13,10 +11,8 @@ define float @ret_arbitrary_fp_no_nan_no_inf(i8 %bits) {
ret float %fp
}
-; Test 2: Float8E4M3FN supports NaNs but lacks Infinities (NaNOnly).
-; The Attributor should safely deduce and attach nofpclass(inf) to the function return.
-define float @ret_arbitrary_fp_nan_only(i8 %bits) {
-; CHECK-LABEL: define nofpclass(inf) float @ret_arbitrary_fp_nan_only
+define float @ret_arbitrary_fp_inf_only(i8 %bits) {
+; CHECK-LABEL: define nofpclass(inf) float @ret_arbitrary_fp_inf_only
; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: %fp = call nofpclass(inf) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float8E4M3FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret float %fp
@@ -25,10 +21,8 @@ define float @ret_arbitrary_fp_nan_only(i8 %bits) {
ret float %fp
}
-; Test 3: Vector variation.
-; The Attributor should successfully attach nofpclass(nan inf) to the returning vector topology.
-define <4 x float> @ret_arbitrary_fp_vector(<4 x i8> %bits) {
-; CHECK-LABEL: define nofpclass(nan inf) <4 x float> @ret_arbitrary_fp_vector
+define <4 x float> @ret_arbitrary_fp_vector_nan_inf(<4 x i8> %bits) {
+; CHECK-LABEL: define nofpclass(nan inf) <4 x float> @ret_arbitrary_fp_vector_nan_inf
; CHECK-SAME: (<4 x i8> [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: %fp = call nofpclass(nan inf) <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i8(<4 x i8> [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret <4 x float> %fp
>From d9211b0ca660dc3ef9127e6689410b0c29447de7 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Sat, 11 Jul 2026 07:49:29 +0530
Subject: [PATCH 12/18] adding fcPosZero and improving fcInf check for
---
llvm/lib/Analysis/ValueTracking.cpp | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 838a2c7033ec8..e9133de7f4632 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5712,14 +5712,27 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
case Intrinsic::convert_from_arbitrary_fp: {
auto *MD = cast<MetadataAsValue>(II->getArgOperand(1))->getMetadata();
StringRef FormatStr = cast<MDString>(MD)->getString();
+
const fltSemantics SrcSemantics =
- *(APFloat::getArbitraryFPSemantics(FormatStr));
+ *APFloat::getArbitraryFPSemantics(FormatStr);
+ const fltSemantics DstSemantics =
+ II->getType()->getScalarType()->getFltSemantics();
if (!APFloat::semanticsHasNaN(SrcSemantics))
Known.knownNot(fcNan);
- if (!APFloat::semanticsHasInf(SrcSemantics))
+ if (!APFloat::semanticsHasInf(SrcSemantics) &&
+ APFloat::isRepresentableBy(SrcSemantics, DstSemantics))
Known.knownNot(fcInf);
+ if (!APFloat::semanticsHasZero(SrcSemantics)) {
+ Known.knownNot(fcZero);
+ } else {
+ KnownBits IntKnown =
+ computeKnownBits(Op->getOperand(0), DemandedElts, Q, Depth + 1);
+ if (IntKnown.isNonZero())
+ Known.knownNot(fcPosZero);
+ }
+
break;
}
default:
>From c73cbd6be3d92524d856211b03cd03f8bbd14d9a Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Sat, 11 Jul 2026 10:17:30 +0530
Subject: [PATCH 13/18] Adding subnormal test for convert_from_arbitrary_fp.
---
llvm/lib/Analysis/ValueTracking.cpp | 3 +++
.../Transforms/Attributor/nofpclass-arbitrary-fp.ll | 12 ++++++------
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e9133de7f4632..6891bc5464683 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5733,6 +5733,9 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Known.knownNot(fcPosZero);
}
+ // if src lands normaly in dest, result can never be sub-normal.
+ if (APFloat::isRepresentableAsNormalIn(SrcSemantics, DstSemantics))
+ Known.knownNot(fcSubnormal);
break;
}
default:
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
index 6bca7d2656c4e..df2c74591beaa 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -2,9 +2,9 @@
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK
define float @ret_arbitrary_fp_nan_inf(i8 %bits) {
-; CHECK-LABEL: define nofpclass(nan inf) float @ret_arbitrary_fp_nan_inf
+; CHECK-LABEL: define nofpclass(nan inf sub) float @ret_arbitrary_fp_nan_inf
; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: %fp = call nofpclass(nan inf) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: %fp = call nofpclass(nan inf sub) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret float %fp
;
%fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float4E2M1FN")
@@ -12,9 +12,9 @@ define float @ret_arbitrary_fp_nan_inf(i8 %bits) {
}
define float @ret_arbitrary_fp_inf_only(i8 %bits) {
-; CHECK-LABEL: define nofpclass(inf) float @ret_arbitrary_fp_inf_only
+; CHECK-LABEL: define nofpclass(inf sub) float @ret_arbitrary_fp_inf_only
; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: %fp = call nofpclass(inf) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float8E4M3FN") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: %fp = call nofpclass(inf sub) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float8E4M3FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret float %fp
;
%fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float8E4M3FN")
@@ -22,9 +22,9 @@ define float @ret_arbitrary_fp_inf_only(i8 %bits) {
}
define <4 x float> @ret_arbitrary_fp_vector_nan_inf(<4 x i8> %bits) {
-; CHECK-LABEL: define nofpclass(nan inf) <4 x float> @ret_arbitrary_fp_vector_nan_inf
+; CHECK-LABEL: define nofpclass(nan inf sub) <4 x float> @ret_arbitrary_fp_vector_nan_inf
; CHECK-SAME: (<4 x i8> [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: %fp = call nofpclass(nan inf) <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i8(<4 x i8> [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: %fp = call nofpclass(nan inf sub) <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i8(<4 x i8> [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret <4 x float> %fp
;
%fp = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8> %bits, metadata !"Float4E2M1FN")
>From de4b1b5c956860125beb1864198132f2ab312346 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Mon, 13 Jul 2026 01:39:33 +0530
Subject: [PATCH 14/18] Adding nullpte check.
---
llvm/lib/Analysis/ValueTracking.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6891bc5464683..b23089a9a1b5f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5713,8 +5713,14 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
auto *MD = cast<MetadataAsValue>(II->getArgOperand(1))->getMetadata();
StringRef FormatStr = cast<MDString>(MD)->getString();
- const fltSemantics SrcSemantics =
- *APFloat::getArbitraryFPSemantics(FormatStr);
+ const fltSemantics *SrcSemanticsPtr =
+ APFloat::getArbitraryFPSemantics(FormatStr);
+ // TODO: the unsupported formats should be handle way before this
+ // remove once the verifier is updated.
+ if (!SrcSemanticsPtr)
+ break;
+
+ const fltSemantics SrcSemantics = *SrcSemanticsPtr;
const fltSemantics DstSemantics =
II->getType()->getScalarType()->getFltSemantics();
>From b46f90f6babde3b95d4d8fdce356e2d4cb373730 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Mon, 13 Jul 2026 05:53:33 +0530
Subject: [PATCH 15/18] Fixing test case.
---
.../Attributor/nofpclass-arbitrary-fp.ll | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
index df2c74591beaa..204d506246be3 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -1,13 +1,13 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s
-define float @ret_arbitrary_fp_nan_inf(i8 %bits) {
+define float @ret_arbitrary_fp_nan_inf(i4 %bits) {
; CHECK-LABEL: define nofpclass(nan inf sub) float @ret_arbitrary_fp_nan_inf
-; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: %fp = call nofpclass(nan inf sub) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
+; CHECK-SAME: (i4 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: %fp = call nofpclass(nan inf sub) float @llvm.convert.from.arbitrary.fp.f32.i4(i4 [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret float %fp
;
- %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float4E2M1FN")
+ %fp = call float @llvm.convert.from.arbitrary.fp.f32.i4(i4 %bits, metadata !"Float4E2M1FN")
ret float %fp
}
@@ -17,19 +17,20 @@ define float @ret_arbitrary_fp_inf_only(i8 %bits) {
; CHECK-NEXT: %fp = call nofpclass(inf sub) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float8E4M3FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret float %fp
;
- %fp = call float @llvm.convert.from.arbitrary.fp(i8 %bits, metadata !"Float8E4M3FN")
+ %fp = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 %bits, metadata !"Float8E4M3FN")
ret float %fp
}
-define <4 x float> @ret_arbitrary_fp_vector_nan_inf(<4 x i8> %bits) {
+define <4 x float> @ret_arbitrary_fp_vector_nan_inf(<4 x i4> %bits) {
; CHECK-LABEL: define nofpclass(nan inf sub) <4 x float> @ret_arbitrary_fp_vector_nan_inf
-; CHECK-SAME: (<4 x i8> [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: %fp = call nofpclass(nan inf sub) <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i8(<4 x i8> [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
+; CHECK-SAME: (<4 x i4> [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: %fp = call nofpclass(nan inf sub) <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4> [[BITS]], metadata !"Float4E2M1FN") #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret <4 x float> %fp
;
- %fp = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8> %bits, metadata !"Float4E2M1FN")
+ %fp = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4> %bits, metadata !"Float4E2M1FN")
ret <4 x float> %fp
}
-declare float @llvm.convert.from.arbitrary.fp(i8, metadata)
-declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32(<4 x i8>, metadata)
+declare float @llvm.convert.from.arbitrary.fp.f32.i4(i4, metadata)
+declare float @llvm.convert.from.arbitrary.fp.f32.i8(i8, metadata)
+declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4>, metadata)
>From 0ac310b04dd6d8fa236116b897765538dab04de6 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Wed, 15 Jul 2026 11:46:05 +0530
Subject: [PATCH 16/18] correcting comment format
---
llvm/lib/Analysis/ValueTracking.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f0ba175d888e9..6599a031a9825 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5757,7 +5757,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Known.knownNot(fcPosZero);
}
- // if src lands normaly in dest, result can never be sub-normal.
+ // If src lands normaly in dest, result can never be sub-normal.
if (APFloat::isRepresentableAsNormalIn(SrcSemantics, DstSemantics))
Known.knownNot(fcSubnormal);
break;
>From 4ba83427c10c571858e862e7ab8853ec6dcb8b86 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Wed, 15 Jul 2026 13:12:19 +0530
Subject: [PATCH 17/18] Adding no-signed-zero testcase.
---
llvm/lib/Analysis/ValueTracking.cpp | 3 +++
.../Transforms/Attributor/nofpclass-arbitrary-fp.ll | 10 ++++++++++
2 files changed, 13 insertions(+)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6599a031a9825..010702615c85e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5748,6 +5748,9 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
APFloat::isRepresentableBy(SrcSemantics, DstSemantics))
Known.knownNot(fcInf);
+ if (SrcSemantics.nanEncoding == fltNanEncoding::NegativeZero)
+ Known.knownNot(fcNegZero);
+
if (!APFloat::semanticsHasZero(SrcSemantics)) {
Known.knownNot(fcZero);
} else {
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
index 204d506246be3..fd044b2b4aa87 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -31,6 +31,16 @@ define <4 x float> @ret_arbitrary_fp_vector_nan_inf(<4 x i4> %bits) {
ret <4 x float> %fp
}
+define float @ret_arbitrary_fp_inf_nzero_sub(i8 %bits) {
+; CHECK-LABEL: define nofpclass(inf nzero sub) float @ret_arbitrary_fp_inf_nzero_sub
+; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: %fp = call nofpclass(inf nzero sub) float @llvm.convert.from.arbitrary.fp.f32.i8(i8 [[BITS]], metadata !"Float8E4M3FNUZ") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: ret float %fp
+;
+ %fp = call float @llvm.convert.from.arbitrary.fp.f32.i8(i8 %bits, metadata !"Float8E4M3FNUZ")
+ ret float %fp
+}
+
declare float @llvm.convert.from.arbitrary.fp.f32.i4(i4, metadata)
declare float @llvm.convert.from.arbitrary.fp.f32.i8(i8, metadata)
declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4>, metadata)
>From aa4729d6bb2775bfedd2a863a1951169cd389a57 Mon Sep 17 00:00:00 2001
From: chirag <chirag198838 at gmail.com>
Date: Wed, 15 Jul 2026 13:56:54 +0530
Subject: [PATCH 18/18] Adding not representable inf case.
---
.../Transforms/Attributor/nofpclass-arbitrary-fp.ll | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
index fd044b2b4aa87..3062f3c3e97d3 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-arbitrary-fp.ll
@@ -31,6 +31,7 @@ define <4 x float> @ret_arbitrary_fp_vector_nan_inf(<4 x i4> %bits) {
ret <4 x float> %fp
}
+;TODO: this format is not fully supported at the moment in LLVM and may cause crash.
define float @ret_arbitrary_fp_inf_nzero_sub(i8 %bits) {
; CHECK-LABEL: define nofpclass(inf nzero sub) float @ret_arbitrary_fp_inf_nzero_sub
; CHECK-SAME: (i8 [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -41,6 +42,17 @@ define float @ret_arbitrary_fp_inf_nzero_sub(i8 %bits) {
ret float %fp
}
+define <2 x float> @ret_arbitrary_fp_vector_no_inf(<2 x i8> %bits) {
+; CHECK-LABEL: define nofpclass(sub) <2 x float> @ret_arbitrary_fp_vector_no_inf
+; CHECK-SAME: (<2 x i8> [[BITS:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: %fp = call nofpclass(sub) <2 x float> @llvm.convert.from.arbitrary.fp.v2f32.v2i8(<2 x i8> [[BITS]], metadata !"Float8E5M2") #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: ret <2 x float> %fp
+;
+ %fp = call <2 x float> @llvm.convert.from.arbitrary.fp.v2f32.v2i8(<2 x i8> %bits, metadata !"Float8E5M2")
+ ret <2 x float> %fp
+}
+
declare float @llvm.convert.from.arbitrary.fp.f32.i4(i4, metadata)
declare float @llvm.convert.from.arbitrary.fp.f32.i8(i8, metadata)
declare <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4>, metadata)
+declare <2 x float> @llvm.convert.from.arbitrary.fp.v2f32.v2i8(<2 x i8>, metadata)
More information about the llvm-commits
mailing list