【问题标题】:LLVM: Make LLVMFP128Type from long doubleLLVM:从 long double 制作 LLVMFP128Type
【发布时间】:2020-12-01 18:02:42
【问题描述】:

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

我可以执行以下操作(使用 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

但是我该如何为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

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

【问题讨论】:

    标签: c floating-point llvm llvm-ir 128-bit


    【解决方案1】:

    我不知道那些 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得到和上面一样的效果

    【讨论】:

    • 问题是关于为 store 操作生成合适的 ir。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 2019-05-20
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多