[pypy-svn] r65624 - in pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm: . test

arigo at codespeak.net arigo at codespeak.net
Sat Jun 6 17:16:10 CEST 2009


Author: arigo
Date: Sat Jun  6 17:16:10 2009
New Revision: 65624

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo1.c
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.h
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_llvm_rffi.py
Log:
Add the LLVM_Intrinsic_add_ovf() function, returning the intrinsic function
"llvm.sadd.with.overflow".  Test it in test_llvm_rffi.


Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo1.c
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo1.c	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo1.c	Sat Jun  6 17:16:10 2009
@@ -10,5 +10,6 @@
  */
 void* llvm_c_functions[] = {
   (void*) LLVMModuleCreateWithName,
-  (void*) _LLVM_EE_getPointerToFunction
+  (void*) _LLVM_EE_getPointerToFunction,
+  (void*) _LLVM_Intrinsic_add_ovf
 };

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp	Sat Jun  6 17:16:10 2009
@@ -4,6 +4,7 @@
 #include "llvm/ExecutionEngine/GenericValue.h"
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/Intrinsics.h"
 #include "demo2.h"
 
 using namespace llvm;
@@ -39,3 +40,13 @@
 {
   return unwrap(EE)->getPointerToFunction(unwrap<Function>(F));
 }
+
+LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty)
+{
+  const Type *array_of_types[1];
+  Function *F;
+  array_of_types[0] = unwrap(Ty);
+  F = Intrinsic::getDeclaration(unwrap(M), Intrinsic::sadd_with_overflow,
+                                array_of_types, 1);
+  return wrap(F);
+}

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.h
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.h	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.h	Sat Jun  6 17:16:10 2009
@@ -7,6 +7,7 @@
 LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M);
 void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE,
                                     LLVMValueRef F);
+LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty);
 
 #ifdef __cplusplus
 }

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py	Sat Jun  6 17:16:10 2009
@@ -256,6 +256,19 @@
                             rffi.UINT,                    # argument count
                             rffi.CCHARP],                 # name of result
                            LLVMValueRef)
+LLVMBuildSelect = llexternal('LLVMBuildSelect',
+                             [LLVMBuilderRef,             # builder
+                              LLVMValueRef,               # if
+                              LLVMValueRef,               # then
+                              LLVMValueRef,               # else
+                              rffi.CCHARP],               # name of result
+                             LLVMValueRef)
+LLVMBuildExtractValue = llexternal('LLVMBuildExtractValue',
+                                   [LLVMBuilderRef,       # builder
+                                    LLVMValueRef,         # aggregated value
+                                    rffi.UINT,            # index
+                                    rffi.CCHARP],         # name of result
+                                   LLVMValueRef)
 
 LLVMCreateModuleProviderForExistingModule = llexternal(
     'LLVMCreateModuleProviderForExistingModule', [LLVMModuleRef],
@@ -300,3 +313,6 @@
                                           [LLVMExecutionEngineRef,
                                            LLVMValueRef],           # function
                                           rffi.VOIDP)
+LLVM_Intrinsic_add_ovf = llexternal('_LLVM_Intrinsic_add_ovf',
+                                    [LLVMModuleRef, LLVMTypeRef],
+                                    LLVMValueRef)

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_llvm_rffi.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_llvm_rffi.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_llvm_rffi.py	Sat Jun  6 17:16:10 2009
@@ -53,13 +53,8 @@
     pass
 
 
-def test_from_llvm_py_example_2():
+def create_execution_engine(my_module):
     teardown_now()
-    d = test_from_llvm_py_example_1()
-    my_module = d['my_module']
-    ty_int = d['ty_int']
-    f_sum = d['f_sum']
-
     # Create a module provider object first. Modules can come from
     # in-memory IRs like what we created now, or from bitcode (.bc)
     # files. The module provider abstracts this detail.
@@ -82,6 +77,18 @@
         lltype.free(ee_out, flavor='raw')
 
     set_teardown_function(lambda: LLVMDisposeExecutionEngine(ee))
+    return ee
+
+
+def test_from_llvm_py_example_2():
+    d = test_from_llvm_py_example_1()
+    my_module = d['my_module']
+    ty_int = d['ty_int']
+    f_sum = d['f_sum']
+
+    # Create an execution engine object. This creates a JIT compiler,
+    # or complain on platforms that don't support it.
+    ee = create_execution_engine(my_module)
 
     # The arguments needs to be passed as "GenericValue" objects.
     args = lltype.malloc(rffi.CArray(LLVMGenericValueRef), 2, flavor='raw')
@@ -105,3 +112,59 @@
     """This test is the same as the previous one.  Just tests that we
     have freed enough stuff to be able to call it again."""
     test_from_llvm_py_example_2()
+
+
+def test_add_ovf():
+    my_module = LLVMModuleCreateWithName("my_module")
+    ty_int = LLVMInt32Type()
+    f_add_ovf = LLVM_Intrinsic_add_ovf(my_module, ty_int)
+    #
+    arglist = lltype.malloc(rffi.CArray(LLVMTypeRef), 2, flavor='raw')
+    arglist[0] = ty_int
+    arglist[1] = ty_int
+    ty_func = LLVMFunctionType(ty_int, arglist, 2, False)
+    lltype.free(arglist, flavor='raw')
+    #
+    f_sum_ovf = LLVMAddFunction(my_module, "sum_ovf", ty_func)
+    f_arg_0 = LLVMGetParam(f_sum_ovf, 0)
+    f_arg_1 = LLVMGetParam(f_sum_ovf, 1)
+    #
+    bb = LLVMAppendBasicBlock(f_sum_ovf, "entry")
+    #
+    builder = LLVMCreateBuilder()
+    LLVMPositionBuilderAtEnd(builder, bb)
+    #
+    arglist = lltype.malloc(rffi.CArray(LLVMValueRef), 2, flavor='raw')
+    arglist[0] = f_arg_0
+    arglist[1] = f_arg_1
+    tmp = LLVMBuildCall(builder, f_add_ovf, arglist, 2, "tmp")
+    lltype.free(arglist, flavor='raw')
+    #
+    tmp0 = LLVMBuildExtractValue(builder, tmp, 0, "tmp0")
+    tmp1 = LLVMBuildExtractValue(builder, tmp, 1, "tmp1")
+    c666 = LLVMConstInt(ty_int, 666, 1)
+    tmp2 = LLVMBuildSelect(builder, tmp1, c666, tmp0, "tmp2")
+    #
+    LLVMBuildRet(builder, tmp2)
+    LLVMDisposeBuilder(builder)
+    #
+    LLVMDumpModule(my_module)
+
+    ee = create_execution_engine(my_module)
+    #
+    OVERFLOW = 666
+    for x, y, z in [(100, 42, 142),
+                    (sys.maxint, 1, OVERFLOW),
+                    (-10, -sys.maxint, OVERFLOW)]:
+        args = lltype.malloc(rffi.CArray(LLVMGenericValueRef), 2, flavor='raw')
+        args[0] = LLVMCreateGenericValueOfInt(ty_int, x, True)
+        args[1] = LLVMCreateGenericValueOfInt(ty_int, y, True)
+        retval = LLVMRunFunction(ee, f_sum_ovf, 2, args)
+        LLVMDisposeGenericValue(args[1])
+        LLVMDisposeGenericValue(args[0])
+        lltype.free(args, flavor='raw')
+        #
+        ulonglong = LLVMGenericValueToInt(retval, True)
+        LLVMDisposeGenericValue(retval)
+        res = rffi.cast(lltype.Signed, ulonglong)
+        assert res == z



More information about the Pypy-commit mailing list