如何在LLVM IR中初始化常量向量?

3

我正在尝试使用LLVM IR初始化一个全是1的常量向量,以此作为熟悉各种目标支持的向量操作的起点。下面是一个简单的main函数定义:

target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc19.31.31104"

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i64 @main() #0 {  
  %one = <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
  %i = bitcast <8 x i8> %one to i64
  ret i64 %i
}

下面这行代码:%one = <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>,在clang 13.0.1编译时会报错:

error: expected instruction opcode
%one = <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
       ^

我不知道问题出在哪里,因为文档在freeze指令的示例中列出了以下代码:

; example with vectors
%v = <2 x i32> <i32 undef, i32 poison>
%a = extractelement <2 x i32> %v, i32 0    ; undef
%b = extractelement <2 x i32> %v, i32 1    ; poison
%add = add i32 %a, %a                      ; undef

似乎是使用我正在使用的向量初始化格式。 我还尝试在等号后面添加constant,但这仍然会产生相同的错误。 向量类型 的文档也使用这种格式描述常量。 供参考,我正在使用以下clang命令行参数:
clang test.ll -o test.exe

你知道为什么clang无法理解这段代码吗?我无法弄清楚它期望的操作码是什么。

1个回答

4

常量字面值不能被赋值给变量,必须直接指定:

%i = bitcast <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> to i64

你可以通过将常量包装在虚拟操作中来“分配”它:
%one = add <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, zeroinitializer

出于好奇,您或其他人是否知道为什么会出现这种情况?因为文档强烈建议这应该是可能的,甚至给出了相关示例。 - hatch22
这在过去可能有效。我建议向LLVM开发人员报告文档中的错误。 - yugr
2
“%name = constant” 从未是有效的LLVM IR。我认为这个例子是伪代码。如果您尝试在LLVM中创建相同的常量两次,它将返回相同的llvm::Constant指针。常量(除了GlobalValue)不能有名称。在文本格式中,这意味着要获得对同一常量的多个引用,必须每次都写出完整的常量。我认为“freeze”的示例文本的作者认为,即使它实际上不是有效的语法,给他们的未定义一个名称会更清晰。也许他们可以通过“假设:%w = i32 undef”来使它更清晰。 - Nick Lewycky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接