In LLVM, there is a LLVMFP128Type, though I cannot seem to find out how to convert an actual long double into a LLVMValueRef of type LLVMFP128Type directly.
I can do the following (with a double):
LLVMValueRef var = LLVMBuildAlloca(
builder,
LLVMDoubleTypeInContext(ctx),
"x"
);
double num = 3.1415;
LLVMBuildStore(
builder,
LLVMConstReal(
LLVMDoubleTypeInContext(ctx),
num
),
var
);
Generating the following LLVM IR:
%x = alloca double
store double 3.141500e+00, double* %x
But how to I do the same for a long double? There is a LLVMConstRealOfString function, which takes makes a constant float from a string, though I find it inefficient to have to convert to and from a string using something like sprintf:
LLVMValueRef var = LLVMBuildAlloca(
builder,
LLVMFP128TypeInContext(ctx),
"x"
);
// long double num = 3.1415L;
LLVMBuildStore(
builder,
LLVMConstRealOfString(
LLVMFP128TypeInContext(ctx),
"3.1415" // would have to sprintf `num`
),
var
);
Gives the following (desired) LLVM IR:
%x = alloca fp128
store fp128 0xLE978D4FDF3B645A24000921CAC083126, fp128* %x
How can I get the desired results (lower example) with the simplicity of the first example?
I don't know about those
LLVMBuildStorebut GCC, ICC and Clang there's already a__float128as an extension so you can just use it.__float128 x = 3.1415;results in the following LLVM IRDemo on Compiler Explorer
In fact
long doubleis mapped to__float128for most modern architectures. In x86 there's hardware support for extended precision so it's mapped to__float80and you can use the-mlong-double-128option to make it an IEEE-754 binary128 type, i.e.__float128. On PowerPClong doubleuses double-double arithmetic by default and you can use-mabi=ieeelongdoubleto get the same effect as above