[Codegen] Adjust saturation test. NFC.
[llvm-core.git] / bindings / go / llvm / executionengine_test.go
blob4462f8fb20468bc61f255a71e175899f169bdb7e
1 //===- executionengine_test.go - Tests for executionengine ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file tests bindings for the executionengine component.
11 //===----------------------------------------------------------------------===//
13 package llvm
15 import (
16 "testing"
19 func TestFactorial(t *testing.T) {
20 LinkInMCJIT()
21 InitializeNativeTarget()
22 InitializeNativeAsmPrinter()
24 mod := NewModule("fac_module")
26 fac_args := []Type{Int32Type()}
27 fac_type := FunctionType(Int32Type(), fac_args, false)
28 fac := AddFunction(mod, "fac", fac_type)
29 fac.SetFunctionCallConv(CCallConv)
30 n := fac.Param(0)
32 entry := AddBasicBlock(fac, "entry")
33 iftrue := AddBasicBlock(fac, "iftrue")
34 iffalse := AddBasicBlock(fac, "iffalse")
35 end := AddBasicBlock(fac, "end")
37 builder := NewBuilder()
38 defer builder.Dispose()
40 builder.SetInsertPointAtEnd(entry)
41 If := builder.CreateICmp(IntEQ, n, ConstInt(Int32Type(), 0, false), "cmptmp")
42 builder.CreateCondBr(If, iftrue, iffalse)
44 builder.SetInsertPointAtEnd(iftrue)
45 res_iftrue := ConstInt(Int32Type(), 1, false)
46 builder.CreateBr(end)
48 builder.SetInsertPointAtEnd(iffalse)
49 n_minus := builder.CreateSub(n, ConstInt(Int32Type(), 1, false), "subtmp")
50 call_fac_args := []Value{n_minus}
51 call_fac := builder.CreateCall(fac, call_fac_args, "calltmp")
52 res_iffalse := builder.CreateMul(n, call_fac, "multmp")
53 builder.CreateBr(end)
55 builder.SetInsertPointAtEnd(end)
56 res := builder.CreatePHI(Int32Type(), "result")
57 phi_vals := []Value{res_iftrue, res_iffalse}
58 phi_blocks := []BasicBlock{iftrue, iffalse}
59 res.AddIncoming(phi_vals, phi_blocks)
60 builder.CreateRet(res)
62 err := VerifyModule(mod, ReturnStatusAction)
63 if err != nil {
64 t.Errorf("Error verifying module: %s", err)
65 return
68 options := NewMCJITCompilerOptions()
69 options.SetMCJITOptimizationLevel(2)
70 options.SetMCJITEnableFastISel(true)
71 options.SetMCJITNoFramePointerElim(true)
72 options.SetMCJITCodeModel(CodeModelJITDefault)
73 engine, err := NewMCJITCompiler(mod, options)
74 if err != nil {
75 t.Errorf("Error creating JIT: %s", err)
76 return
78 defer engine.Dispose()
80 pass := NewPassManager()
81 defer pass.Dispose()
83 pass.AddConstantPropagationPass()
84 pass.AddInstructionCombiningPass()
85 pass.AddPromoteMemoryToRegisterPass()
86 pass.AddGVNPass()
87 pass.AddCFGSimplificationPass()
88 pass.Run(mod)
90 exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)}
91 exec_res := engine.RunFunction(fac, exec_args)
92 var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
93 if exec_res.Int(false) != fac10 {
94 t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false))