[LLVMdev] Possible bug or misunderstanding of feature LLVMConstIntOfString

Sunny Narula mr.sunny.narula at gmail.com
Thu Sep 27 05:14:06 PDT 2012


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.
http://llvm.org/docs/doxygen/html/APInt_8cpp_source.html#l02024
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);
    LLVMDumpModule(modCEx);

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

    LLVMPassManagerRef rPassMgr = LLVMCreatePassManager();
    LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engExe), rPassMgr);
    LLVMAddConstantPropagationPass(rPassMgr);
    LLVMAddInstructionCombiningPass(rPassMgr);
    LLVMAddPromoteMemoryToRegisterPass(rPassMgr);
    LLVMAddGVNPass(rPassMgr);
    LLVMAddCFGSimplificationPass(rPassMgr);

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

    //  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);
    LLVMDisposeBuilder(bldr);
    LLVMDisposeExecutionEngine(engExe);
}


Regards

Sunny Narula
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120927/49472e13/attachment.html>


More information about the llvm-dev mailing list