2014-03-31 82 views
-1

我正在使用自定義LLVM傳遞,其中如果遇到 的商店,其中編譯器將該值轉換爲常量;例如有一個明確的店:LLVM將常量轉換爲值

X[gidx] = 10; 

然後LLVM會產生這樣的錯誤:

aoc: ../../../Instructions.cpp:1056: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed. 

繼承順序都按:值< - 用戶<的常數,所以這不應該是一個問題,但它是。在ConstantInt或ConstantFP上使用強制轉換對此錯誤沒有影響。 所以我試過這個臃腫的解決方案:

Value *new_value; 
if(isa<ConstantInt>(old_value) || isa<ConstantFP>(old_value)){ 
    Instruction *allocInst = builder.CreateAlloca(old_value->getType()); 
    builder.CreateStore(old_value, allocInst); 
    new_value = builder.CreateLoad(allocResultInst); 
} 

然而,當不同類型的參與這種解決方案創建自己的寄存器的錯誤,所以我想,以避免它。

有誰知道如何將常量轉換爲值?這一定是一個簡單的問題,我沒有看到。我正在開發Ubuntu 12.04,LLVM 3,AMD gpu,OpenCL內核。

提前致謝。

編輯:

產生列出的第一個錯誤的原代碼只是:

builder.CreateStore(old_value, store_addr); 

EDIT2:

這OLD_VALUE被聲明爲 值* OLD_VALUE = current_instruction-> getOperand( 0);

所以我抓住要存儲的值,在這種情況下,從第一個代碼行中選擇「10」。

+0

「產生列出的第一個錯誤的原始代碼很簡單」 - 您能否提供更大的片段,包括如何創建'old_value'和'new_value'? – Oak

回答

0

您沒有提供導致此第一個斷言的代碼,但其語句非常清晰:您正試圖創建一個存儲區,其中的值操作數和指針操作數不同意它們的類型。如果你提供產生該錯誤的代碼,這將是有用的。

您的第二個所謂的「臃腫」解決方案是將old_value存儲到堆棧中,然後再次加載它的正確方法。你寫:

However this solution creates its own register errors when different type are involved

這些「註冊錯誤」是你應該解決真正問題。在任何情況下,「將常數轉換爲數值」的前提是有缺陷的 - 正如您已經正確觀察到的那樣,所有常數都是值。將值存入堆棧並沒有意義,只能重新加載它,而實際上標準的LLVM pass「mem2reg」將完全刪除這樣一個序列,將負載的所有用途替換爲原始值。

+0

已編輯。註冊問題是原始[post](http:// http://stackoverflow.com/questions/22647180/llvm-front-end-register-class-error-opencl-gpu-target)的要點。但是,考慮到你的最後一點,我不明白爲什麼這個問題首先存在。 – user2765828