Possible bug or misunderstanding of feature LLVMConstIntOfString

Hi All
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.

Example code follows:

LLVMContextRef context = LLVMContextCreate();
LLVMValueRef value = LLVMConstIntOfString(LLVMInt64TypeInContext(context), “0x0000000f0000ffff”, 16);

This is working properly as expected.

However I have noticed that if the bits are not prefixed with enough zeros to correspond to 32 or 64 bits this gives me:

For 0x0fff := 0xffffffff0fff (incorrect)
For 0xfff := 0xfffffffffff (incorrect)
For 0x00000fff := 0xffffffff00000fff (incorrect)
For 0x0000fff := 0xffffffff0000fff (incorrect)
For 0xffffffff := 0xffffffffffffffff (incorrect)
For 0x00000000ffffffff := 0xffffffff (correct)
For 0xffffffffff := 0xffffffffffffffff (incorrect)

I hope that is sufficient data.
I explored the code a bit and found that APInt.cpp file’s fromString method deals with this.
I am hoping someone from the community can review and confirm if this is indeed a bug.

Please let me know if more data is required.

Please note the line where you can can check the various scenarios in the below test case:

Test case:

int main() {
LLVMContextRef context = LLVMContextCreate();
const char *moduleName = “LLVMConstHexIntOfString”;
const char *template = “Integer converted from hexadecimal string# %lx”;
LLVMValueRef testValue = LLVMConstIntOfString(LLVMInt64TypeInContext(context), “0x00fffff”, 16); <---------------------------- Change this hex representation to test multiple scenarios.
printf("[llvmPrintf# %s] Generating code from C program: \n", moduleName);
LLVMModuleRef modCEx = LLVMModuleCreateWithNameInContext(moduleName, context);

// “main” function type definition:
LLVMTypeRef ppInt8 = LLVMPointerType(LLVMPointerType(LLVMInt8Type(), 0), 0);
LLVMTypeRef vpMainFuncTypes[] = { LLVMInt32Type(), ppInt8 };
LLVMTypeRef rMainFuncType = LLVMFunctionType(LLVMInt32Type(), vpMainFuncTypes, 2, 0);
LLVMValueRef vFnMain = LLVMAddFunction(modCEx, “main”, rMainFuncType);
LLVMSetFunctionCallConv(vFnMain, LLVMCCallConv);

LLVMBasicBlockRef bEntry = LLVMAppendBasicBlock(vFnMain, “entry”);

LLVMBuilderRef bldr = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(bldr, bEntry);
// “C” printf function;
LLVMTypeRef vpFnPrintfArgsType[] = { LLVMPointerType(LLVMInt8Type(), 0) };
LLVMTypeRef vFnPrintfType = LLVMFunctionType(LLVMInt32Type(), vpFnPrintfArgsType, 1, 1);
LLVMValueRef vFnPrintf = LLVMAddFunction(modCEx, “printf”, vFnPrintfType);
LLVMSetLinkage(vFnPrintf, LLVMExternalLinkage);

// printf with arguments
LLVMValueRef printfArgTemplate = LLVMBuildGlobalStringPtr(bldr, template, “privateString”);
LLVMValueRef vpArgsPrintf[] = { printfArgTemplate, testValue };
LLVMBuildCall(bldr, vFnPrintf, vpArgsPrintf, 2, “printf”);
LLVMBuildRet(bldr, LLVMConstInt(LLVMInt32Type(), 0, 0));

// Dump Code:
printf("\n[llvmPrintf# %s] Verifying Function:\n", moduleName);
LLVMVerifyFunction(vFnMain, LLVMPrintMessageAction);
printf("\n[llvmPrintf# %s] Dumping LLVM generated Code:\n", moduleName);

// Compile and JIT above generated function:
LLVMExecutionEngineRef engExe;
char * pErr = NULL;
LLVMCreateJITCompilerForModule(&engExe, modCEx, 4, &pErr);
if (pErr) {
printf("[Creating JIT Compiler] Error: %s\n", pErr);

LLVMPassManagerRef rPassMgr = LLVMCreatePassManager();
LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engExe), rPassMgr);

LLVMRunPassManager(rPassMgr, modCEx);
printf("\n[llvmPrintf# %s] Dumping OPTIMIZED LLVM generated Code\n", moduleName);

// printf Executing:
printf("\n[llvmPrintf# %s] Executing generated Code\n", moduleName);
LLVMRunFunctionAsMain(engExe, vFnMain, 0, NULL, NULL);
printf("\n[llvmPrintf# %s] Finished executing generated Code\n", moduleName);


Sunny Narula