[llvm] [AMDGPU][LibCallSimplify] Use target type's float-semantics in `ConstantFP::get` (PR #213721)
Juan Manuel Martinez CaamaƱo via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 6 02:09:33 PDT 2026
https://github.com/jmmartinez updated https://github.com/llvm/llvm-project/pull/213721
>From abd29a70081d671491cbb33781857d5c586b6d3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juamarti at amd.com>
Date: Mon, 3 Aug 2026 17:33:11 +0200
Subject: [PATCH 1/4] Pre-commit test for AMDGPULibCallSimplify
---
llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
index da0f6f065d241..d19b4fa18efd1 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
@@ -6109,6 +6109,11 @@ define <2 x float> @test_pow_v2f32_known_integral_constant_vector_poison_elt(<2
ret <2 x float> %pow
}
+define float @test_pow_f32_known_args_with_fpclass() {
+ %pow = call fast nofpclass(nan inf) float @_Z3powff(float noundef nofpclass(nan inf) 0.0, float noundef nofpclass(nan inf) 0.0)
+ ret float %pow
+}
+
attributes #0 = { minsize }
attributes #1 = { noinline }
attributes #2 = { strictfp }
>From f7dc00d3f9d905b8c29bef5b36051992b768f3ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juamarti at amd.com>
Date: Mon, 3 Aug 2026 17:36:04 +0200
Subject: [PATCH 2/4] [AMDGPU][AMDGPULibCallSimplify] Use target type's
float-semantics in `ConstantFP::get`
Compiler was crashing with:
```
Constants.cpp:1124: static llvm::ConstantFP* llvm::ConstantFP::get(llvm::Type*, const llvm::APFloat&):
Assertion `Ty->getScalarType() == Type::getFloatingPointTy(Cont ext, V.getSemantics()) &&
"ConstantFP type doesn't match the type implied by its value!"' failed.
```
Since the code was quite similar to `getConstantFloatVector`, I've ended
up modifying its implementation to also handle scalars and renamed it.
---
llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp | 26 +++++++++----------
.../AMDGPU/amdgpu-simplify-libcall-pow.ll | 3 +++
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index cddfbdd7818db..db33a83633c9d 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -802,8 +802,8 @@ bool AMDGPULibCalls::fold(CallInst *CI) {
return false;
}
-static Constant *getConstantFloatVector(const ArrayRef<APFloat> Values,
- const Type *Ty) {
+static Constant *getConstantFloat(const ArrayRef<APFloat> Values,
+ const Type *Ty) {
Type *ElemTy = Ty->getScalarType();
const fltSemantics &FltSem = ElemTy->getFltSemantics();
@@ -814,6 +814,12 @@ static Constant *getConstantFloatVector(const ArrayRef<APFloat> Values,
APF.convert(FltSem, APFloat::rmNearestTiesToEven, &Unused);
ConstValues.push_back(ConstantFP::get(ElemTy, APF));
}
+
+ if (!Ty->isVectorTy()) {
+ assert(Values.size() == 1 && "Expected exactly one constant value");
+ return ConstValues[0];
+ }
+
return ConstantVector::get(ConstValues);
}
@@ -843,7 +849,7 @@ bool AMDGPULibCalls::TDOFold(CallInst *CI, const FuncInfo &FInfo) {
return false;
Values.push_back(APFloat(MatchingRow->result));
}
- Constant *NewValues = getConstantFloatVector(Values, CI->getType());
+ Constant *NewValues = getConstantFloat(Values, CI->getType());
LLVM_DEBUG(errs() << "AMDIC: " << *CI << " ---> " << *NewValues << "\n");
replaceCall(CI, NewValues);
return true;
@@ -2017,16 +2023,10 @@ bool AMDGPULibCalls::evaluateCall(CallInst *aCI, const FuncInfo &FInfo) {
}
}
- Constant *nval0 = nullptr, *nval1 = nullptr;
- if (FuncVecSize == 1) {
- nval0 = ConstantFP::get(aCI->getType(), Val0[0]);
- if (hasTwoResults)
- nval1 = ConstantFP::get(aCI->getType(), Val1[0]);
- } else {
- nval0 = getConstantFloatVector(Val0, aCI->getType());
- if (hasTwoResults)
- nval1 = getConstantFloatVector(Val1, aCI->getType());
- }
+ Constant *nval0 = getConstantFloat(Val0, aCI->getType());
+ Constant *nval1 = nullptr;
+ if (hasTwoResults)
+ nval1 = getConstantFloat(Val1, aCI->getType());
if (hasTwoResults) {
// sincos
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
index d19b4fa18efd1..11745f83fe119 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
@@ -6110,6 +6110,9 @@ define <2 x float> @test_pow_v2f32_known_integral_constant_vector_poison_elt(<2
}
define float @test_pow_f32_known_args_with_fpclass() {
+; CHECK-LABEL: define float @test_pow_f32_known_args_with_fpclass() {
+; CHECK-NEXT: ret float 1.000000e+00
+;
%pow = call fast nofpclass(nan inf) float @_Z3powff(float noundef nofpclass(nan inf) 0.0, float noundef nofpclass(nan inf) 0.0)
ret float %pow
}
>From 4e41485c210bc676169ca75eb444e2b05799d436 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?=
<jmartinezcaamao at gmail.com>
Date: Thu, 6 Aug 2026 11:00:55 +0200
Subject: [PATCH 3/4] [review] Move asserts and simplify return
---
llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index db33a83633c9d..1fb3b3067a1b1 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -804,6 +804,15 @@ bool AMDGPULibCalls::fold(CallInst *CI) {
static Constant *getConstantFloat(const ArrayRef<APFloat> Values,
const Type *Ty) {
+
+ assert(Ty->isSingleValueType() &&
+ "Type must either be a scalar or a vector.");
+ assert((!Ty->isVectorType() || Ty->isScalableTy() ||
+ Values.size() == cast<FixedVectorType>(Ty)->getNumElements()) &&
+ "Unexpected number of constant values.");
+ assert((Ty->isVectorType() || Values.size() == 1) &&
+ "Expected exactly one constant value");
+
Type *ElemTy = Ty->getScalarType();
const fltSemantics &FltSem = ElemTy->getFltSemantics();
@@ -815,12 +824,7 @@ static Constant *getConstantFloat(const ArrayRef<APFloat> Values,
ConstValues.push_back(ConstantFP::get(ElemTy, APF));
}
- if (!Ty->isVectorTy()) {
- assert(Values.size() == 1 && "Expected exactly one constant value");
- return ConstValues[0];
- }
-
- return ConstantVector::get(ConstValues);
+ return Ty->isVectorTy() ? ConstantVector::get(ConstValues) : ConstValues[0];
}
bool AMDGPULibCalls::TDOFold(CallInst *CI, const FuncInfo &FInfo) {
>From efa2303eb87061e9766ed27abd0ca4a8e580b486 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?=
<jmartinezcaamao at gmail.com>
Date: Thu, 6 Aug 2026 11:01:39 +0200
Subject: [PATCH 4/4] [review] Sink second argument closer to where it is used
---
llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index 1fb3b3067a1b1..090c78914aa7a 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -2028,14 +2028,12 @@ bool AMDGPULibCalls::evaluateCall(CallInst *aCI, const FuncInfo &FInfo) {
}
Constant *nval0 = getConstantFloat(Val0, aCI->getType());
- Constant *nval1 = nullptr;
- if (hasTwoResults)
- nval1 = getConstantFloat(Val1, aCI->getType());
if (hasTwoResults) {
// sincos
assert(FInfo.getId() == AMDGPULibFunc::EI_SINCOS &&
"math function with ptr arg not supported yet");
+ Constant *nval1 = getConstantFloat(Val1, aCI->getType());
new StoreInst(nval1, aCI->getArgOperand(1), aCI->getIterator());
}
More information about the llvm-commits
mailing list