[LLVMdev] loop only executes once

Andrew Ferguson andrewf at idlearts.com
Fri Jun 17 22:49:45 PDT 2011


Hello, 
I'm trying to get to grips with the c interface of llvm 
intending to eventually develop a front end for Purebasic 
Though I've hit the wall already writing an iterative Fibonacci
function.
While I think the module dump looks ok it doesn't work 
for any input > 2 the function returns 2, the loop only executes once

Hopefully someone can see what the problem is from the output and the
source. Does the input ArgX require to be cast? 

Cheers  

module dump 
verifying module
; ModuleID = 'test fib'

define fastcc i32 @fib2(i32 %ArgX) {
EntryBlock:
  %A = alloca i32
  %B = alloca i32
  %C = alloca i32
  %D = alloca i32
  store i32 1, i32* %A
  store i32 1, i32* %B
  store i32 0, i32* %C
  store i32 %ArgX, i32* %D
  %cond = icmp sle i32 %ArgX, 2
  br i1 %cond, label %IF, label %Else

IF:                                               ; preds = %EntryBlock
  ret i32 1

Else:                                             ; preds = %while, %
EntryBlock
  %PD = load i32* %D
  %cond1 = icmp sgt i32 %PD, 2
  br i1 %cond1, label %while, label %ewhile

while:                                            ; preds = %Else
  %pA = load i32* %A
  %pB = load i32* %B
  %addab = add i32 %pA, %pB
  store i32 %addab, i32* %C
  store i32 %pA, i32* %B
  store i32 %addab, i32* %A
  %sub = sub i32 %PD, 1
  store i32 %sub, i32* %D
  br label %Else

ewhile:                                           ; preds = %Else
  %CR = load i32* %C
  ret i32 %CR
}

Source of function 

Procedure CreateFibFunction(M.i,Context.i)     
intType = LLVMInt32Type()
//Function returns an int And takes an int As the only parameter.
 FunctionReturnType = LLVMFunctionType(IntType, at IntType,1,0)
//Create the fib function definition And insert it into the module M. 
Fib2 = LLVMAddFunction(M, "fib2",FunctionReturnType)
 //Set the function call convention To FastCall so it can utilize tail
call 
LLVMSetFunctionCallConv(Fib2,#LLVMFastCallConv)
//Get a pointer To the ArgX.i And add To function...
ArgX = LLVMGetFirstParam(Fib2) // Get the arg.
LLVMSetValueName(ArgX, "ArgX") // Give it a symbolic name.

Builder = LLVMCreateBuilderInContext(Context)
BB = LLVMAppendBasicBlockInContext(Context, Fib2, "EntryBlock")
//Entry 
LLVMPositionBuilderAtEnd(Builder, BB)
//Protected a,b,c
//a=1:b=1:c=0:d=argx
A = LLVMBuildAlloca(Builder, IntType,"A")//
B = LLVMBuildAlloca(Builder, IntType,"B")//
C = LLVMBuildAlloca(Builder, IntType,"C")//
D =  LLVMBuildAlloca(Builder, IntType,"D")//   
One = LLVMConstInt(IntType, 1, 0)
LLVMBuildStore(Builder,One,A)//
LLVMBuildStore(Builder,One,B)//
Zero = LLVMConstInt(IntType, 0, 0)
LLVMBuildStore(Builder,Zero,C)
LLVMBuildStore(Builder,ArgX,D)
   
 //If argx <= 2 : Return 1 : Goto Else 
IFBB = LLVMAppendBasicBlockInContext(Context, Fib2, "IF")
ElseBB = LLVMAppendBasicBlockInContext(Context, Fib2, "Else")
Two = LLVMConstInt(IntType, 2, 0)
CondInst = LLVMBuildICmp(Builder, #LLVMIntSLE, ArgX,Two, "cond")
LLVMBuildCondBr(Builder, CondInst, IFBB, ElseBB)
//If
LLVMPositionBuilderAtEnd(Builder, IFBB)
LLVMBuildRet(Builder,One)
//Else
LLVMPositionBuilderAtEnd(Builder, ElseBB)

WhileBB = LLVMAppendBasicBlockInContext(Context, Fib2, "while") 
EWhileBB = LLVMAppendBasicBlockInContext(Context, Fib2, "ewhile") 
//  While argx > 2
PD  = LLVMBuildLoad(Builder,D,"PD")//
CondInst1 = LLVMBuildICmp(Builder, #LLVMIntSGT, PD, Two, "cond1")
LLVMBuildCondBr(Builder, CondInst1, WhileBB, EWhileBB)
//WhileBB
LLVMPositionBuilderAtEnd(Builder, WhileBB)   
//c = a + b//
//b = a//
//a = c//
//argx-1//
PA  = LLVMBuildLoad(Builder,A,"pA")//
PB =  LLVMBuildLoad(Builder,B,"pB")//
AddAB = LLVMBuildAdd(Builder,PA,PB,"addab")
LLVMBuildStore(Builder,AddAB,C)//
LLVMBuildStore(Builder,PA,B)//
LLVMBuildStore(Builder,AddAB,A)//
sub = LLVMBuildSub(Builder,PD,One,"sub")
LLVMBuildStore(Builder,sub,D)//
LLVMBuildBr(Builder,ElseBB)//

//Ewhile 
 LLVMPositionBuilderAtEnd(Builder, EWhileBB)
 CR  = LLVMBuildLoad(Builder,C,"CR")//
 //ProcedureReturn C
 LLVMBuildRet(Builder, CR)
 
  //Don't forget to free the builder.
    LLVMDisposeBuilder(Builder)
    
    //Return the function ref
    ProcedureReturn Fib2
EndProcedure   


-- 
Andrew Ferguson





More information about the llvm-dev mailing list