我想在llvm IR文件中插入一个load语句



我有llvm IR代码,比如:

%0 = load i32* %b, align 4
%mul = mul nsw i32 %0, 1

我想用负载替换第二条指令:%mul = load i32* %0, align4

所以我使用以下代码:

new LoadInst(op1, "mul", x);

其中x是指向我希望替换的指令的指针(指令*),值*op1=x->getOperand(0);

在x之前插入该指令之后,我擦除x(当前指令)。当我运行它时,这里会出现错误。我觉得我没有提出正确的论点。

PS:我不允许使用实用程序类进行更改。

您正在做的事情有两个问题。

首先,如果这是您的目标代码,则它是非法的:

%0 = load i32* %b, align 4
%mul = load i32* %0, align 4

由于%0的类型是i32,但在负载中,您假定它是i32*

第二步,用另一条指令替换一条指令的正确方法是使用ReplaceInstWithInst(位于BasicBlockUtils.h),因为它还会更新旧指令的所有用户以使用新指令。

为了澄清为什么你的方法不起作用,这里有一个演示(忽略类型问题):

%0 = load i32* %b, align 4
%mul = mul nsw i32 %0, 1
ret i32 %mul

现在运行new LoadInst(op1, "mul", x);并获得:

%0 = load i32* %b, align 4
%mul = load i32* %0, align 4
%mul.1 = mul nsw i32 %0, 1
ret i32 %mul.1

为什么要将第二条指令从%mul重命名为%mul.1?我没有;均命名为CCD_ 9。但是,当您打印出来时,打印机会将.<serial number>附加到共享相同作用域和名称的所有指令中,以防止混淆。

不用添加,删除后你会得到这个:

%0 = load i32* %b, align 4
%mul = load i32* %0, align 4
ret i32 %mul.1

并且CCD_ 11是指一个缺失的值。

简言之,您不能依赖指令名称来做任何事情,它只是为了帮助调试并使IR的文本表示更可读。

最新更新