Hi All<div>I am a novice LLVM user trying to use LLVMConstIntOfString using the c api to get a integer of arbitrary size from a hexadecimal string.</div><div><br></div><div>Example code follows:</div><div><br></div><div><div>
LLVMContextRef context = LLVMContextCreate();</div><div> LLVMValueRef value = LLVMConstIntOfString(LLVMInt64TypeInContext(context), "0x0000000f0000ffff", 16);</div></div><div>This is working properly as expected.</div>
<div><br></div><div>However I have noticed that if the bits are not prefixed with enough zeros to correspond to 32 or 64 bits this gives me:</div><div><br></div><div>For 0x0fff := 0xffffffff0fff (incorrect)</div><div>For 0xfff := 0xfffffffffff (incorrect)</div>
<div>For 0x00000fff := 0xffffffff00000fff (incorrect)</div><div>For 0x0000fff := 0xffffffff0000fff (incorrect)</div><div>For 0xffffffff := 0xffffffffffffffff (incorrect)</div><div>For 0x00000000ffffffff := 0xffffffff (correct)</div>
<div>For 0xffffffffff := 0xffffffffffffffff (incorrect)</div><div><br></div><div>I hope that is sufficient data.</div><div>I explored the code a bit and found that APInt.cpp file's fromString method deals with this.</div>
<div><a href="http://llvm.org/docs/doxygen/html/APInt_8cpp_source.html#l02024">http://llvm.org/docs/doxygen/html/APInt_8cpp_source.html#l02024</a></div><div>I am hoping someone from the community can review and confirm if this is indeed a bug.</div>
<div><br></div><div>Please let me know if more data is required.</div><div><br></div><div>Please note the line where you can can check the various scenarios in the below test case:</div><div><br></div><div>Test case:</div>
<div><div>int main() {</div><div> LLVMContextRef context = LLVMContextCreate();</div><div> const char *moduleName = "LLVMConstHexIntOfString";</div><div> const char *template = "Integer converted from hexadecimal string# %lx";</div>
<div> LLVMValueRef testValue = LLVMConstIntOfString(LLVMInt64TypeInContext(context), "0x00fffff", 16); <---------------------------- Change this hex representation to test multiple scenarios.</div><div>
printf("[llvmPrintf# %s] Generating code from C program: \n", moduleName);</div><div> LLVMModuleRef modCEx = LLVMModuleCreateWithNameInContext(moduleName, context);</div><div><br></div><div> // "main" function type definition:</div>
<div> LLVMTypeRef ppInt8 = LLVMPointerType(LLVMPointerType(LLVMInt8Type(), 0), 0);</div><div> LLVMTypeRef vpMainFuncTypes[] = { LLVMInt32Type(), ppInt8 };</div><div> LLVMTypeRef rMainFuncType = LLVMFunctionType(LLVMInt32Type(), vpMainFuncTypes, 2, 0);</div>
<div> LLVMValueRef vFnMain = LLVMAddFunction(modCEx, "main", rMainFuncType);</div><div> LLVMSetFunctionCallConv(vFnMain, LLVMCCallConv);</div><div><br></div><div> LLVMBasicBlockRef bEntry = LLVMAppendBasicBlock(vFnMain, "entry");</div>
<div><br></div><div> LLVMBuilderRef bldr = LLVMCreateBuilder();</div><div> LLVMPositionBuilderAtEnd(bldr, bEntry);</div><div> // "C" printf function;</div><div> LLVMTypeRef vpFnPrintfArgsType[] = { LLVMPointerType(LLVMInt8Type(), 0) };</div>
<div> LLVMTypeRef vFnPrintfType = LLVMFunctionType(LLVMInt32Type(), vpFnPrintfArgsType, 1, 1);</div><div> LLVMValueRef vFnPrintf = LLVMAddFunction(modCEx, "printf", vFnPrintfType);</div><div> LLVMSetLinkage(vFnPrintf, LLVMExternalLinkage);</div>
<div><br></div><div> // printf with arguments</div><div> LLVMValueRef printfArgTemplate = LLVMBuildGlobalStringPtr(bldr, template, "privateString");</div><div> LLVMValueRef vpArgsPrintf[] = { printfArgTemplate, testValue };</div>
<div> LLVMBuildCall(bldr, vFnPrintf, vpArgsPrintf, 2, "printf");</div><div> LLVMBuildRet(bldr, LLVMConstInt(LLVMInt32Type(), 0, 0));</div><div><br></div><div> // Dump Code:</div><div> printf("\n[llvmPrintf# %s] Verifying Function:\n", moduleName);</div>
<div> LLVMVerifyFunction(vFnMain, LLVMPrintMessageAction);</div><div> printf("\n[llvmPrintf# %s] Dumping LLVM generated Code:\n", moduleName);</div><div> LLVMDumpModule(modCEx);</div><div><br></div><div>
// Compile and JIT above generated function:</div><div> LLVMInitializeNativeTarget();</div><div> LLVMExecutionEngineRef engExe;</div><div> char * pErr = NULL;</div><div> LLVMCreateJITCompilerForModule(&engExe, modCEx, 4, &pErr);</div>
<div> if (pErr) {</div><div> printf("[Creating JIT Compiler] Error: %s\n", pErr);</div><div> LLVMDisposeMessage(pErr);</div><div> exit(0);</div><div> }</div><div><br></div><div> LLVMPassManagerRef rPassMgr = LLVMCreatePassManager();</div>
<div> LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engExe), rPassMgr);</div><div> LLVMAddConstantPropagationPass(rPassMgr);</div><div> LLVMAddInstructionCombiningPass(rPassMgr);</div><div> LLVMAddPromoteMemoryToRegisterPass(rPassMgr);</div>
<div> LLVMAddGVNPass(rPassMgr);</div><div> LLVMAddCFGSimplificationPass(rPassMgr);</div><div><br></div><div> LLVMRunPassManager(rPassMgr, modCEx);</div><div> printf("\n[llvmPrintf# %s] Dumping OPTIMIZED LLVM generated Code\n", moduleName);</div>
<div> LLVMDumpModule(modCEx);</div><div><br></div><div> // printf Executing:</div><div> printf("\n[llvmPrintf# %s] Executing generated Code\n", moduleName);</div><div> LLVMRunFunctionAsMain(engExe, vFnMain, 0, NULL, NULL);</div>
<div> printf("\n[llvmPrintf# %s] Finished executing generated Code\n", moduleName);</div><div> LLVMDisposeBuilder(bldr);</div><div> LLVMDisposeExecutionEngine(engExe);</div><div>}</div><div><br></div></div>
<div><br></div><div>Regards</div><div><br></div><div>Sunny Narula</div>