0

在 LLVM 中,有一个LLVMFP128Type,尽管我似乎无法找到如何将实际long double转换为 a LLVMValueRefof 类型LLVMFP128Type

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

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

double num = 3.1415;

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

生成以下 LLVM IR:

%x = alloca double
store double 3.141500e+00, double* %x

但是我如何为 a 做同样的事情long double?有一个LLVMConstRealOfString函数,它从一个字符串中获取一个常量浮点数,尽管我发现必须使用类似的东西来转换字符串和从字符串转换是低效的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
);

给出以下(所需的)LLVM IR:

%x = alloca fp128
store fp128 0xLE978D4FDF3B645A24000921CAC083126, fp128* %x

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

4

1 回答 1

0

我不知道那些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

编译器资源管理器演示

实际上long double映射到__float128大多数现代架构。在 x86 中,硬件支持扩展精度,因此它被映射到__float80,您可以使用该-mlong-double-128选项使其成为IEEE-754 binary128类型,即__float128. 在 PowerPC 上默认long double使用double-double 算法,你可以使用-mabi=ieeelongdouble得到与上面相同的效果

于 2020-08-12T06:42:48.670 回答