I have the following problem with llvm and c++: Given an array, I want to shift every entry of that array by one to the right, ie, I want to implement the following c code:
int arr[5];
for(int i=1;i<5;++i){
arr[i] = arr[i-1];
}
I tried the following c++ code:
IntegerType *Int32Ty = IntegerType::getInt32Ty(M.getContext(););
GlobalVariable *arrVariable;
arrVariable = new GlobalVariable(M, PointerType::get(Int32Ty, 0), false,
GlobalValue::ExternalLinkage, 0, "__arr");
for(int i=0;i<ARRAY_LENGTH;++i){
Constant* fromIdx = Constant::getIntegerValue(Int32Ty, llvm::APInt(32, i-1));
Value *fromLocPtrIdx = IRB.CreateGEP(arrVariable, fromIdx);
Constant* toIdx = Constant::getIntegerValue(Int32Ty, llvm::APInt(32, i));
Value *toLocPtrIdx = IRB.CreateGEP(arrVariable, toIdx);
StoreInst *MoveStoreInst = IRB.CreateStore(fromLocPtrIdx,toLocPtrIdx);
}
where __arr
is defined as:
__thread u32 __arr[ARRAY_LENGTH];
However, when compiling, this yields the following error message:
/usr/bin/ld: __arr: TLS definition in ../inject.o section .tbss mismatches non-TLS reference in /tmp/test-inject.o
What is the right way to move values in an arrays using the llvm c++ api?
You need to specify that your global variable is thread_local
.
The way to do that is to add the thread-local mode to your global creation:
arrVariable = new GlobalVariable(M, PointerType::get(Int32Ty, 0), false,
GlobalValue::ExternalLinkage, 0, "__arr", nullptr, InitialExecTLSModel);
The exact mode depends on what your target is, but I think InitialExecTLSModel
is a generally "good starting point".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.