LLVM: Make LLVMFP128Type from long double

507 Views Asked by At

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?

1

There are 1 best solutions below

1
phuclv On

I don't know about those LLVMBuildStore but GCC, ICC and Clang there's already a __float128 as an extension so you can just use it. __float128 x = 3.1415; results in the following LLVM IR

%7 = load fp128*, fp128** %4, align 8, !dbg !22
store fp128 0xLF0000000000000004000921CAC083126, fp128* %7, align 16, !dbg !23

Demo on Compiler Explorer

In fact long double is mapped to __float128 for most modern architectures. In x86 there's hardware support for extended precision so it's mapped to __float80 and you can use the -mlong-double-128 option to make it an IEEE-754 binary128 type, i.e. __float128. On PowerPC long double uses double-double arithmetic by default and you can use -mabi=ieeelongdouble to get the same effect as above