【问题标题】:llvm getelementptr getting wrong valuellvm getelementptr 得到错误的值
【发布时间】:2019-12-15 11:33:50
【问题描述】:

我正在学习 llvm getelementptr 指令,并尝试从结构中获取元素。我的结构是这样的,

struct Foo {
    int32_t a;
    int32_t b;
    int32_t c;
};

对应的llvm类型:

Type *getType() {
    vector<Type *> tps;
    tps.push_back(Type::getInt32Ty(TheContext));
    tps.push_back(Type::getInt32Ty(TheContext));
    tps.push_back(Type::getInt32Ty(TheContext));
    StructType *tp = StructType::create(TheContext, tps, "foo_type");
    return tp;
}

还有一个测试函数,

%foo_type = type { i32, i32, i32 }

define i32 @_func_(%foo_type) {
entry:
  %1 = alloca %foo_type
  store %foo_type %0, %foo_type* %1
  %2 = getelementptr %foo_type, %foo_type* %1, i32 0, i32 1
  %3 = load i32, i32* %2
  ret i32 %3
}

但是通过运行编译函数,我总是得到第三个元素,即 Foo::c,而不是 Foo::b,那么我的代码有什么问题?我认为问题可能出在商店指令上。

Complete working program here

编辑 2019.12.13

通过将指针作为参数传递,我得到了正确的答案

define i32 @_func_(%foo_type*) {
entry:
  %1 = alloca %foo_type*
  store %foo_type* %0, %foo_type** %1
  %ptr = load %foo_type*, %foo_type** %1
  %2 = getelementptr %foo_type, %foo_type* %ptr, i32 0, i32 1
  %3 = load i32, i32* %2
  ret i32 %3
}

所以问题一定是FP(f)实际上并没有将f传递给之前版本中的编译函数。

【问题讨论】:

  • 如果这解决了您的问题。请添加它作为答案:)

标签: c++ llvm


【解决方案1】:

如果你用 c 编写函数并让 clang 为它发出 IR,你可以看到:

struct Foo {
    int a;
    int b;
    int c;
};

int bar(Foo f) {
    return f.b;
}

define dso_local i32 @_Z3bar3Foo(i64, i32) #0 {
  %3 = alloca %struct.Foo, align 4
  %4 = alloca { i64, i32 }, align 4
  %5 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %4, i32 0, i32 0
  store i64 %0, i64* %5, align 4
  %6 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %4, i32 0, i32 1
  store i32 %1, i32* %6, align 4
  %7 = bitcast %struct.Foo* %3 to i8*
  %8 = bitcast { i64, i32 }* %4 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %7, i8* align 4 %8, i64 12, i1 false)
  %9 = getelementptr inbounds %struct.Foo, %struct.Foo* %3, i32 0, i32 1
  %10 = load i32, i32* %9, align 4
  ret i32 %10
}

这意味着bar(Foo()) 实际上接受int64int32 作为参数,而不是Foo 本身。可能是一些我不太了解的 c/cpp ABI。

但是通过指针传递的时候,就没有这个问题了,所以按预期工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2023-03-04
    • 2019-12-28
    • 1970-01-01
    相关资源
    最近更新 更多