Skip to content

Commit 0ba73fb

Browse files
authored
[llvm-c] Add LLVMConstFPFromBits() API (#164381)
This change adds the ability to create a 128 bit floating point value from 2 64 bit integer values. Some language frontends have already parsed a floating point string into a proper 128 bit quad value and need to get the llvm value directly.
1 parent a25e367 commit 0ba73fb

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ Changes to the C API
177177

178178
* Add `LLVMGetOrInsertFunction` to get or insert a function, replacing the combination of `LLVMGetNamedFunction` and `LLVMAddFunction`.
179179
* Allow `LLVMGetVolatile` to work with any kind of Instruction.
180+
* Add `LLVMConstFPFromBits` to get a constant floating-point value from an array of 64 bit values.
180181

181182
Changes to the CodeGen infrastructure
182183
-------------------------------------

llvm/include/llvm-c/Core.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,6 +2346,14 @@ LLVM_C_ABI LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy,
23462346
const char *Text,
23472347
unsigned SLen);
23482348

2349+
/**
2350+
* Obtain a constant for a floating point value from array of 64 bit values.
2351+
* The length of the array N must be ceildiv(bits, 64), where bits is the
2352+
* scalar size in bits of the floating-point type.
2353+
*/
2354+
2355+
LLVM_C_ABI LLVMValueRef LLVMConstFPFromBits(LLVMTypeRef Ty, const uint64_t N[]);
2356+
23492357
/**
23502358
* Obtain the zero extended value for an integer constant value.
23512359
*

llvm/lib/IR/Core.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,14 @@ LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[],
15731573
return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Str, SLen)));
15741574
}
15751575

1576+
LLVMValueRef LLVMConstFPFromBits(LLVMTypeRef Ty, const uint64_t N[]) {
1577+
Type *T = unwrap(Ty);
1578+
unsigned SB = T->getScalarSizeInBits();
1579+
APInt AI(SB, ArrayRef<uint64_t>(N, divideCeil(SB, 64)));
1580+
APFloat Quad(T->getFltSemantics(), AI);
1581+
return wrap(ConstantFP::get(T, Quad));
1582+
}
1583+
15761584
unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal) {
15771585
return unwrap<ConstantInt>(ConstantVal)->getZExtValue();
15781586
}

llvm/unittests/IR/ConstantsTest.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,5 +835,35 @@ TEST(ConstantsTest, BlockAddressCAPITest) {
835835
EXPECT_EQ(&BB, OutBB);
836836
}
837837

838+
TEST(ConstantsTest, Float128Test) {
839+
LLVMContextRef C = LLVMContextCreate();
840+
LLVMTypeRef Ty128 = LLVMFP128TypeInContext(C);
841+
LLVMTypeRef TyPPC128 = LLVMPPCFP128TypeInContext(C);
842+
LLVMTypeRef TyFloat = LLVMFloatTypeInContext(C);
843+
LLVMTypeRef TyDouble = LLVMDoubleTypeInContext(C);
844+
LLVMTypeRef TyHalf = LLVMHalfTypeInContext(C);
845+
LLVMBuilderRef Builder = LLVMCreateBuilder();
846+
uint64_t n[2] = {0x4000000000000000, 0x0}; //+2
847+
uint64_t m[2] = {0xC000000000000000, 0x0}; //-2
848+
LLVMValueRef val1 = LLVMConstFPFromBits(Ty128, n);
849+
EXPECT_TRUE(val1 != nullptr);
850+
LLVMValueRef val2 = LLVMConstFPFromBits(Ty128, m);
851+
EXPECT_TRUE(val2 != nullptr);
852+
LLVMValueRef val3 = LLVMBuildFAdd(Builder, val1, val2, "test");
853+
EXPECT_TRUE(val3 != nullptr);
854+
LLVMValueRef val4 = LLVMConstFPFromBits(TyPPC128, n);
855+
EXPECT_TRUE(val4 != nullptr);
856+
uint64_t p[1] = {0x0000000040000000}; //+2
857+
LLVMValueRef val5 = LLVMConstFPFromBits(TyFloat, p);
858+
EXPECT_EQ(APFloat(2.0f), unwrap<ConstantFP>(val5)->getValue());
859+
uint64_t q[1] = {0x4000000000000000}; //+2
860+
LLVMValueRef val6 = LLVMConstFPFromBits(TyDouble, q);
861+
EXPECT_EQ(APFloat(2.0), unwrap<ConstantFP>(val6)->getValue());
862+
uint64_t r[1] = {0x0000000000003c00}; //+1
863+
LLVMValueRef val7 = LLVMConstFPFromBits(TyHalf, r);
864+
EXPECT_TRUE(val7 != nullptr);
865+
LLVMContextDispose(C);
866+
}
867+
838868
} // end anonymous namespace
839869
} // end namespace llvm

0 commit comments

Comments
 (0)