You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LLVM IR中通过ConstantFP获取load/store指令的浮点值

问题描述

现有如下LLVM IR代码片段:

store float 1.000000e+00, float* %f, align 4, !dbg !860
%0 = load float, float* %f, align 4, !dbg !861

在已知变量名%f的前提下,需要分别从上述load、store指令中获取对应的浮点值1.000000e+00。
已知调用constant_int->getSExtValue()方法可获取整型常量值,但未找到ConstantFP类提供的同类取值函数。当前编写的C++实现代码如下:

if (auto *op = dyn_cast<LoadInst>(&I))
{
  Value *val = arg1;
  // HERE didn't work
  if (auto constant_int = dyn_cast<ConstantInt>(val))
  {
    int number = constant_int->getSExtValue();
  }
  else if (auto constant_fp = dyn_cast<ConstantFP>(val))
  {
    // ??
  }
}

if (auto *op = dyn_cast<StoreInst>(&I))
{
  Value *val = op->getValueOperand();
  // HERE works!
  if (auto constant_int = dyn_cast<ConstantInt>(val))
  {
    int number = constant_int->getSExtValue();
    errs() << "store " << number << ".\n";
  }
  else if (auto constant_fp = dyn_cast<ConstantFP>(val))
  {
    // ??
  }
}

当前代码存在两个待解决问题:

  • store指令分支的整型常量提取逻辑可正常运行,但load指令分支取值逻辑失效
  • 两处ConstantFP判断分支的浮点值提取逻辑尚未实现
解决方案

ConstantFP浮点值提取

ConstantFP没有和getSExtValue()完全对应的直接返回数值的方法,需要通过它持有的APFloat实例做转换:

  • 32位单精度float:调用getValueAPF().convertToFloat(),返回C++原生float类型
  • 64位双精度double:调用getValueAPF().convertToDouble(),返回C++原生double类型

对应分支代码直接写为:

else if (auto constant_fp = dyn_cast<ConstantFP>(val))
{
  float f32_val = constant_fp->getValueAPF().convertToFloat();
  // double f64_val = constant_fp->getValueAPF().convertToDouble();
  errs() << "float constant: " << f32_val << "\n";
}

可配合constant_fp->getType()->isFloatTy()/isDoubleTy()判断常量精度选择对应转换方法。

load指令取值失效修复

load分支取值逻辑错误原因有两个:

  1. 代码中取的arg1不是load的合法操作数,LoadInst获取加载的源指针要调用getPointerOperand();同时LLVM是SSA形式,load指令本身仅代表从内存读值的操作,不会内嵌常量值
  2. 示例中的1.0是store指令写入%f指向内存的值,不是load指令自带的立即数,必须追踪指针对应的写入操作才能拿到值

适配你给出的单store写入场景的load分支修正代码:

if (auto *load_op = dyn_cast<LoadInst>(&I))
{
  Value* target_ptr = load_op->getPointerOperand();
  // 遍历指针的所有使用,找到对它写入的store指令
  for (User* u : target_ptr->users()) {
    auto *store_op = dyn_cast<StoreInst>(u);
    if (!store_op || store_op->getPointerOperand() != target_ptr)
      continue;
    Value* stored_val = store_op->getValueOperand();
    // 常量判断逻辑和store分支完全一致
    if (auto ci = dyn_cast<ConstantInt>(stored_val)) {
      int i_val = ci->getSExtValue();
      errs() << "load got int: " << i_val << "\n";
    } else if (auto cf = dyn_cast<ConstantFP>(stored_val)) {
      float f_val = cf->getValueAPF().convertToFloat();
      errs() << "load got float: " << f_val << "\n";
    }
    break;
  }
}

若存在控制流分支、多次写入、指针别名等复杂场景,需要额外配合支配树分析、别名分析、流敏感追踪才能保证拿到准确的常量值,上述代码仅适配单写入的简单场景。

内容的提问来源于stack exchange,提问作者Rong Luo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 11:12:31