1

我正在尝试用常量替换地址的所有实例。

我正在使用以下内容获取并测试商店的地址(我是一条指令)

//already know it's a store instruction at this point
llvm::Value *addy = i->getOperand(0);
if(llvm::ConstantInt* c = dyn_cast<llvm:::ConstantInt>(addy)){
   //replace all uses of the address with the constant
   //operand(1) will be the address the const would be stored at
   i->getOperand(1)->replaceAllUsesWith(c);
}

我认为这会起作用,但我收到的错误是

"Assertion: New->getType()== getType() && replaceAllUses of value with new value of different type!" failed

而且我不确定为什么...我对 replaceAllUses 的理解是它会用常量替换地址 (i->getOperand(1) 的使用?

4

1 回答 1

2

错误消息非常简单:新值的类型与您要替换的旧值的类型不同。

LLVM IR 是强类型的,正如您在语言参考中看到的那样,每条指令都有一个它期望作为每个操作数的特定类型。例如,store要求地址的类型始终是指向所存储值的类型的指针。

因此,每当您替换值的用法时,您必须首先确保它们都具有相同的类型 -replaceAllUsesWith实际上有一个断言来验证它,如您所见,并且您失败了。原因也很简单:存储指令的操作数 1 总是某种指针类型,而 aConstantInt总是代表某种整数类型,所以它们肯定永远不会匹配。

你到底想达到什么目的?也许您正在考虑用load常量替换每个商店的地址?在这种情况下,您必须自己找到所有load使用该地址的 s,并且对于它们中的每一个(我的意思是,对于每个负载,而不是地址)replaceAllUsesWith都使用常量执行。顺便说一下,有标准的 LLVM 通行证可以为您做这些事情 - 查看通行证列表。我猜 mem2reg 后跟一些恒定的传播传递会解决这个问题。

于 2013-04-29T03:45:33.803 回答