LLVM:将LLVMFP128Type从长整型

问题描述

在LLVM中,有一个LLVmfp128Type,尽管我似乎无法找出如何将实际的long double转换为类型LLVMValueRef的{​​{1}}的方法

我可以执行以下操作(使用LLVmfp128Type):

double

生成以下LLVM IR:

LLVMValueRef var = LLVMBuildAlloca(
    builder,LLVMDoubleTypeInContext(ctx),"x"
);

double num = 3.1415;

LLVMBuildStore(
    builder,LLVMConstReal(
        LLVMDoubleTypeInContext(ctx),num
    ),var
);

但是对于%x = alloca double store double 3.141500e+00,double* %x ,我该怎么做?有一个long double函数,它使字符串恒定浮点数,尽管我发现必须使用LLVMConstRealOfString之类的字符串来回转换效率不高:

sprintf

给出以下(期望的)LLVM IR:

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
);

如何通过第一个示例的简单性获得期望的结果(下例)?

解决方法

我不知道这些LLVMBuildStore,但是GCC,ICC和Clang已经有了__float128作为扩展名,因此您可以使用它。 __float128 x = 3.1415;产生以下LLVM IR

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

Demo on Compiler Explorer

实际上,对于大多数现代体系结构,long double映射到__float128。在x86中,硬件支持扩展精度,因此将其映射到__float80,您可以使用-mlong-double-128选项将其设置为IEEE-754 binary128类型,即__float128。在PowerPC上,long double默认使用double-double arithmetic,您可以使用-mabi=ieeelongdouble获得与上述相同的效果