[llvm] b02de9d - [GlobalISel] Use correct fp semantics when building constants. (#210190)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 21 07:18:22 PDT 2026
Author: nvmitch
Date: 2026-07-21T09:18:16-05:00
New Revision: b02de9d35e7aad5b1dfb6dd8bc759bb8fa2d539f
URL: https://github.com/llvm/llvm-project/commit/b02de9d35e7aad5b1dfb6dd8bc759bb8fa2d539f
DIFF: https://github.com/llvm/llvm-project/commit/b02de9d35e7aad5b1dfb6dd8bc759bb8fa2d539f.diff
LOG: [GlobalISel] Use correct fp semantics when building constants. (#210190)
This bug can materialize as a `bfloat 1.0` becoming `0x3C00` which is
the bit pattern for `half 1.0`. After this change, `0x3F80` is correctly
returned.
The fix is to use the destination type to convert the provided
constant's semantics in `buildFConstant`. Added a unit test.
Removed `getAPFloatFromSize`, no more users.
Added:
Modified:
llvm/include/llvm/CodeGen/GlobalISel/Utils.h
llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
llvm/lib/CodeGen/GlobalISel/Utils.cpp
llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index 97d40ac1fdac3..2feaf76aaeaa6 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -299,9 +299,6 @@ T *getOpcodeDef(Register Reg, const MachineRegisterInfo &MRI) {
return dyn_cast_or_null<T>(DefMI);
}
-/// Returns an APFloat from Val converted to the appropriate size.
-LLVM_ABI APFloat getAPFloatFromSize(double Val, unsigned Size);
-
/// Modify analysis usage so it preserves passes required for the SelectionDAG
/// fallback.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU);
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index bd6cd3c325951..d9eb4e7019be1 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -409,9 +409,11 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
double Val) {
LLT DstTy = Res.getLLTTy(*getMRI());
auto &Ctx = getMF().getFunction().getContext();
- auto *CFP =
- ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getScalarSizeInBits()));
- return buildFConstant(Res, *CFP);
+ APFloat APF(Val);
+ bool Ignored;
+ APF.convert(getFltSemanticForLLT(DstTy.getScalarType()),
+ APFloat::rmNearestTiesToEven, &Ignored);
+ return buildFConstant(Res, *ConstantFP::get(Ctx, APF));
}
MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 7efde30bc88e2..52f2f089f7c46 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -659,19 +659,6 @@ MachineInstr *llvm::getOpcodeDef(unsigned Opcode, Register Reg,
return DefMI && DefMI->getOpcode() == Opcode ? DefMI : nullptr;
}
-APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
- if (Size == 32)
- return APFloat(float(Val));
- if (Size == 64)
- return APFloat(Val);
- if (Size != 16)
- llvm_unreachable("Unsupported FPConstant size");
- bool Ignored;
- APFloat APF(Val);
- APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
- return APF;
-}
-
std::optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode,
const Register Op1,
const Register Op2,
diff --git a/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp b/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
index 67e5c0964cba4..83fe8c7cb0f63 100644
--- a/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
@@ -37,6 +37,24 @@ TEST_F(AArch64GISelMITest, TestBuildConstantFConstant) {
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
+TEST_F(AArch64GISelMITest, TestBuildFConstantBFloatSemantics) {
+ setUp();
+ if (!TM)
+ GTEST_SKIP();
+
+ // bfloat 1.0 -> 0x3F80
+ auto BF16One = B.buildFConstant(LLT::bfloat16(), 1.0);
+ const APFloat &BF16APF = BF16One->getOperand(1).getFPImm()->getValueAPF();
+ EXPECT_EQ(&BF16APF.getSemantics(), &APFloat::BFloat());
+ EXPECT_EQ(BF16APF.bitcastToAPInt().getZExtValue(), 0x3F80u);
+
+ // half 1.0 -> 0x3C00
+ auto F16One = B.buildFConstant(LLT::float16(), 1.0);
+ const APFloat &F16APF = F16One->getOperand(1).getFPImm()->getValueAPF();
+ EXPECT_EQ(&F16APF.getSemantics(), &APFloat::IEEEhalf());
+ EXPECT_EQ(F16APF.bitcastToAPInt().getZExtValue(), 0x3C00u);
+}
+
#ifdef GTEST_HAS_DEATH_TEST
#ifndef NDEBUG
More information about the llvm-commits
mailing list