Repository: numba/numba

Issue:
LLVM IR parsing error :1257:48: error: expected value token 
Hi, I encounter the error here. Here is my code:

```
class F1Optimizer():
    def __init__(self):
        pass

    @staticmethod
    @jit
    def get_expectations(P, pNone=None):
        expectations = []
        P = np.sort(P)[::-1]

        n = np.array(P).shape[0]
        DP_C = np.zeros((n + 2, n + 1))
        if pNone is None:
            pNone = (1.0 - P).prod()

        DP_C[0][0] = 1.0
        for j in range(1, n):
            DP_C[0][j] = (1.0 - P[j - 1]) * DP_C[0, j - 1]

        for i in range(1, n + 1):
            DP_C[i, i] = DP_C[i - 1, i - 1] * P[i - 1]
            for j in range(i + 1, n + 1):
                DP_C[i, j] = P[j - 1] * DP_C[i - 1, j - 1] + (1.0 - P[j - 1]) * DP_C[i, j - 1]

        DP_S = np.zeros((2 * n + 1,))
        DP_SNone = np.zeros((2 * n + 1,))
        for i in range(1, 2 * n + 1):
            DP_S[i] = 1. / (1. * i)
            DP_SNone[i] = 1. / (1. * i + 1)
        for k in range(n + 1)[::-1]:
            f1 = 0
            f1None = 0
            for k1 in range(n + 1):
                f1 += 2 * k1 * DP_C[k1][k] * DP_S[k + k1]
                f1None += 2 * k1 * DP_C[k1][k] * DP_SNone[k + k1]
            for i in range(1, 2 * k - 1):
                DP_S[i] = (1 - P[k - 1]) * DP_S[i] + P[k - 1] * DP_S[i + 1]
                DP_SNone[i] = (1 - P[k - 1]) * DP_SNone[i] + P[k - 1] * DP_SNone[i + 1]
            expectations.append([f1None + 2 * pNone / (2 + k), f1])

        return np.array(expectations[::-1]).T

    @staticmethod
    @jit
    def maximize_expectation(P, pNone=None):
        expectations = F1Optimizer.get_expectations(P, pNone)

        ix_max = np.unravel_index(expectations.argmax(), expectations.shape)
        max_f1 = expectations[ix_max]

        predNone = True if ix_max[0] == 0 else False
        best_k = ix_max[1]

        return best_k, predNone, max_f1

    @staticmethod
    def _F1(tp, fp, fn):
        return 2 * tp / (2 * tp + fp + fn)

    @staticmethod
    def _Fbeta(tp, fp, fn, beta=1.0):
        beta_squared = beta ** 2
        return (1.0 + beta_squared) * tp / ((1.0 + beta_squared) * tp + fp + beta_squared * fn)
```

`F1Optimizer.maximize_expectation([0.3])`

RuntimeError Traceback (most recent call last)
in ()
----> 1 F1Optimizer.maximize_expectation([0.3])

/root/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
305 argtypes.append(self.typeof_pyval(a))
306 try:
--> 307 return self.compile(tuple(argtypes))
308 except errors.TypingError as e:
309 # Intercept typing error that may be due to an argument

/root/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in compile(self, sig)
656 flags=flags, locals=self.locals,
657 lifted=(),
--> 658 lifted_from=self.lifted_from)
659
660 # Check typing error if object mode is used

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in compile_ir(typingctx, targetctx, func_ir, args, return_type, flags, locals, lifted, lifted_from, library)
752 args, return_type, flags, locals)
753 return pipeline.compile_ir(func_ir=func_ir, lifted=lifted,
--> 754 lifted_from=lifted_from)
755
756

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in compile_ir(self, func_ir, lifted, lifted_from)
366
367 self._set_and_check_ir(func_ir)
--> 368 return self._compile_ir()
369
370 def stage_analyze_bytecode(self):

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _compile_ir(self)
704 """
705 assert self.func_ir is not None
--> 706 return self._compile_core()
707
708

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _compile_core(self)
684
685 pm.finalize()
--> 686 res = pm.run(self.status)
687 if res is not None:
688 # Early pipeline completion

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in run(self, status)
244 # No more fallback pipelines?
245 if is_final_pipeline:
--> 246 raise patched_exception
247 # Go to next fallback pipeline
248 else:

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in run(self, status)
236 try:
237 event(stage_name)
--> 238 stage()
239 except _EarlyPipelineCompletion as e:
240 return e.result

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in stage_objectmode_backend(self)
597 """
598 lowerfn = self.backend_object_mode
--> 599 self._backend(lowerfn, objectmode=True)
600
601 # Warn if compiled function in object mode and force_pyobject not set

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _backend(self, lowerfn, objectmode)
574 self.library.enable_object_caching()
575
--> 576 lowered = lowerfn()
577 signature = typing.signature(self.return_type, *self.args)
578 self.cr = compile_result(typing_context=self.typingctx,

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in backend_object_mode(self)
548 self.library,
549 self.func_ir,
--> 550 self.flags)
551
552 def backend_nopython_mode(self):

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in py_lowering_stage(targetctx, library, interp, flags)
880 fndesc = funcdesc.PythonFunctionDescriptor.from_object_mode_function(interp)
881 lower = objmode.PyLower(targetctx, library, fndesc, interp)
--> 882 lower.lower()
883 if not flags.no_cpython_wrapper:
884 lower.create_cpython_wrapper()

/root/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower(self)
158
159 # Materialize LLVM Module
--> 160 self.library.add_ir_module(self.module)
161
162 def extract_function_arguments(self):

/root/anaconda3/lib/python3.6/site-packages/numba/targets/codegen.py in add_ir_module(self, ir_module)
183 ir = cgutils.normalize_ir_text(str(ir_module))
184 with llvmts.lock_llvm:
--> 185 ll_module = llvmts.parse_assembly(ir)
186 ll_module.name = ir_module.name
187 ll_module.verify()

/root/anaconda3/lib/python3.6/site-packages/numba/llvmthreadsafe.py in wrapped(*args, **kwargs)
28 def wrapped(*args, **kwargs):
29 with self:
---> 30 return fn(*args, **kwargs)
31 return wrapped
32

/root/anaconda3/lib/python3.6/site-packages/numba/llvmthreadsafe.py in wrapper(*args, **kwargs)
57 @functools.wraps(fn)
58 def wrapper(*args, **kwargs):
---> 59 return _patch_dispose(fn(*args, **kwargs))
60 return wrapper
61

/root/anaconda3/lib/python3.6/site-packages/llvmlite/binding/module.py in parse_assembly(llvmir)
20 if errmsg:
21 mod.close()
---> 22 raise RuntimeError("LLVM IR parsing error\n{0}".format(errmsg))
23 return mod
24

RuntimeError: Failed at object (object mode backend)
LLVM IR parsing error
:1257:48: error: expected value token
%".845" = call i8* @"PyLong_FromSsize_t"(i64 slice(None, None, -1))
^

However, when I pass [0.3,02] to the function, it works perfectly fine. Did I miss something? Thank you in advanced
LLVM IR parsing error :1257:48: error: expected value token 
Hi, I encounter the error here. Here is my code:

```
class F1Optimizer():
    def __init__(self):
        pass

    @staticmethod
    @jit
    def get_expectations(P, pNone=None):
        expectations = []
        P = np.sort(P)[::-1]

        n = np.array(P).shape[0]
        DP_C = np.zeros((n + 2, n + 1))
        if pNone is None:
            pNone = (1.0 - P).prod()

        DP_C[0][0] = 1.0
        for j in range(1, n):
            DP_C[0][j] = (1.0 - P[j - 1]) * DP_C[0, j - 1]

        for i in range(1, n + 1):
            DP_C[i, i] = DP_C[i - 1, i - 1] * P[i - 1]
            for j in range(i + 1, n + 1):
                DP_C[i, j] = P[j - 1] * DP_C[i - 1, j - 1] + (1.0 - P[j - 1]) * DP_C[i, j - 1]

        DP_S = np.zeros((2 * n + 1,))
        DP_SNone = np.zeros((2 * n + 1,))
        for i in range(1, 2 * n + 1):
            DP_S[i] = 1. / (1. * i)
            DP_SNone[i] = 1. / (1. * i + 1)
        for k in range(n + 1)[::-1]:
            f1 = 0
            f1None = 0
            for k1 in range(n + 1):
                f1 += 2 * k1 * DP_C[k1][k] * DP_S[k + k1]
                f1None += 2 * k1 * DP_C[k1][k] * DP_SNone[k + k1]
            for i in range(1, 2 * k - 1):
                DP_S[i] = (1 - P[k - 1]) * DP_S[i] + P[k - 1] * DP_S[i + 1]
                DP_SNone[i] = (1 - P[k - 1]) * DP_SNone[i] + P[k - 1] * DP_SNone[i + 1]
            expectations.append([f1None + 2 * pNone / (2 + k), f1])

        return np.array(expectations[::-1]).T

    @staticmethod
    @jit
    def maximize_expectation(P, pNone=None):
        expectations = F1Optimizer.get_expectations(P, pNone)

        ix_max = np.unravel_index(expectations.argmax(), expectations.shape)
        max_f1 = expectations[ix_max]

        predNone = True if ix_max[0] == 0 else False
        best_k = ix_max[1]

        return best_k, predNone, max_f1

    @staticmethod
    def _F1(tp, fp, fn):
        return 2 * tp / (2 * tp + fp + fn)

    @staticmethod
    def _Fbeta(tp, fp, fn, beta=1.0):
        beta_squared = beta ** 2
        return (1.0 + beta_squared) * tp / ((1.0 + beta_squared) * tp + fp + beta_squared * fn)
```

`F1Optimizer.maximize_expectation([0.3])`

RuntimeError Traceback (most recent call last)
in ()
----> 1 F1Optimizer.maximize_expectation([0.3])

/root/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
305 argtypes.append(self.typeof_pyval(a))
306 try:
--> 307 return self.compile(tuple(argtypes))
308 except errors.TypingError as e:
309 # Intercept typing error that may be due to an argument

/root/anaconda3/lib/python3.6/site-packages/numba/dispatcher.py in compile(self, sig)
656 flags=flags, locals=self.locals,
657 lifted=(),
--> 658 lifted_from=self.lifted_from)
659
660 # Check typing error if object mode is used

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in compile_ir(typingctx, targetctx, func_ir, args, return_type, flags, locals, lifted, lifted_from, library)
752 args, return_type, flags, locals)
753 return pipeline.compile_ir(func_ir=func_ir, lifted=lifted,
--> 754 lifted_from=lifted_from)
755
756

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in compile_ir(self, func_ir, lifted, lifted_from)
366
367 self._set_and_check_ir(func_ir)
--> 368 return self._compile_ir()
369
370 def stage_analyze_bytecode(self):

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _compile_ir(self)
704 """
705 assert self.func_ir is not None
--> 706 return self._compile_core()
707
708

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _compile_core(self)
684
685 pm.finalize()
--> 686 res = pm.run(self.status)
687 if res is not None:
688 # Early pipeline completion

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in run(self, status)
244 # No more fallback pipelines?
245 if is_final_pipeline:
--> 246 raise patched_exception
247 # Go to next fallback pipeline
248 else:

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in run(self, status)
236 try:
237 event(stage_name)
--> 238 stage()
239 except _EarlyPipelineCompletion as e:
240 return e.result

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in stage_objectmode_backend(self)
597 """
598 lowerfn = self.backend_object_mode
--> 599 self._backend(lowerfn, objectmode=True)
600
601 # Warn if compiled function in object mode and force_pyobject not set

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in _backend(self, lowerfn, objectmode)
574 self.library.enable_object_caching()
575
--> 576 lowered = lowerfn()
577 signature = typing.signature(self.return_type, *self.args)
578 self.cr = compile_result(typing_context=self.typingctx,

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in backend_object_mode(self)
548 self.library,
549 self.func_ir,
--> 550 self.flags)
551
552 def backend_nopython_mode(self):

/root/anaconda3/lib/python3.6/site-packages/numba/compiler.py in py_lowering_stage(targetctx, library, interp, flags)
880 fndesc = funcdesc.PythonFunctionDescriptor.from_object_mode_function(interp)
881 lower = objmode.PyLower(targetctx, library, fndesc, interp)
--> 882 lower.lower()
883 if not flags.no_cpython_wrapper:
884 lower.create_cpython_wrapper()

/root/anaconda3/lib/python3.6/site-packages/numba/lowering.py in lower(self)
158
159 # Materialize LLVM Module
--> 160 self.library.add_ir_module(self.module)
161
162 def extract_function_arguments(self):

/root/anaconda3/lib/python3.6/site-packages/numba/targets/codegen.py in add_ir_module(self, ir_module)
183 ir = cgutils.normalize_ir_text(str(ir_module))
184 with llvmts.lock_llvm:
--> 185 ll_module = llvmts.parse_assembly(ir)
186 ll_module.name = ir_module.name
187 ll_module.verify()

/root/anaconda3/lib/python3.6/site-packages/numba/llvmthreadsafe.py in wrapped(*args, **kwargs)
28 def wrapped(*args, **kwargs):
29 with self:
---> 30 return fn(*args, **kwargs)
31 return wrapped
32

/root/anaconda3/lib/python3.6/site-packages/numba/llvmthreadsafe.py in wrapper(*args, **kwargs)
57 @functools.wraps(fn)
58 def wrapper(*args, **kwargs):
---> 59 return _patch_dispose(fn(*args, **kwargs))
60 return wrapper
61

/root/anaconda3/lib/python3.6/site-packages/llvmlite/binding/module.py in parse_assembly(llvmir)
20 if errmsg:
21 mod.close()
---> 22 raise RuntimeError("LLVM IR parsing error\n{0}".format(errmsg))
23 return mod
24

RuntimeError: Failed at object (object mode backend)
LLVM IR parsing error
:1257:48: error: expected value token
%".845" = call i8* @"PyLong_FromSsize_t"(i64 slice(None, None, -1))
^

However, when I pass [0.3,02] to the function, it works perfectly fine. Did I miss something? Thank you in advanced


Discussion:
Thanks for the report.

Running independently works fine, i.e. once with:
```python
print(F1Optimizer.maximize_expectation([0.3]))
```
and once with:
```python
print(F1Optimizer.maximize_expectation([0.3, 0.2]))
```

However, running the function with the two calls one after the other does not, the problem you describe appears (order of calls makes no difference).
```python
print(F1Optimizer.maximize_expectation([0.3]))
print(F1Optimizer.maximize_expectation([0.3, 0.2]))
```
The parse error is due to `slice(...)` in the IR which occurs through the use of loop lifting.

This is a minimal reproducer:
```python
import numpy as np
from numba import jit

@jit
def foo(x):
    A = np.sort(x)[::-1]
    for k in range(1)[::-1]:
        A[k]

print(foo([0.3]))
print(foo([0.3, 0.4, 0.2]))
```
Thanks for the report.

Running independently works fine, i.e. once with:
```python
print(F1Optimizer.maximize_expectation([0.3]))
```
and once with:
```python
print(F1Optimizer.maximize_expectation([0.3, 0.2]))
```

However, running the function with the two calls one after the other does not, the problem you describe appears (order of calls makes no difference).
```python
print(F1Optimizer.maximize_expectation([0.3]))
print(F1Optimizer.maximize_expectation([0.3, 0.2]))
```
The parse error is due to `slice(...)` in the IR which occurs through the use of loop lifting.

This is a minimal reproducer:
```python
import numpy as np
from numba import jit

@jit
def foo(x):
    A = np.sort(x)[::-1]
    for k in range(1)[::-1]:
        A[k]

print(foo([0.3]))
print(foo([0.3, 0.4, 0.2]))
```

Resolving patch:
diff --git a/numba/dispatcher.py b/numba/dispatcher.py
--- a/numba/dispatcher.py
+++ b/numba/dispatcher.py
@@ -649,9 +649,11 @@ def compile(self, sig):
                     return existing.entry_point
 
                 assert not flags.enable_looplift, "Enable looplift flags is on"
+                # Clone IR to avoid mutation in rewrite pass
+                cloned_func_ir = self.func_ir.copy()
                 cres = compiler.compile_ir(typingctx=self.typingctx,
                                            targetctx=self.targetctx,
-                                           func_ir=self.func_ir,
+                                           func_ir=cloned_func_ir,
                                            args=args, return_type=return_type,
                                            flags=flags, locals=self.locals,
                                            lifted=(),


Test patch:
diff --git a/numba/tests/test_looplifting.py b/numba/tests/test_looplifting.py
--- a/numba/tests/test_looplifting.py
+++ b/numba/tests/test_looplifting.py
@@ -436,6 +436,38 @@ def foo(x):
         cfoo = jit(foo)
         self.assertEqual(foo(10), cfoo(10))
 
+    def test_recompilation_loop(self):
+        """
+        https://github.com/numba/numba/issues/2481
+        """
+        from numba import jit
+
+        def foo(x, y):
+            # slicing to make array `x` into different layout
+            # to cause a new compilation of the lifted loop
+            A = x[::y]
+            c = 1
+            for k in range(A.size):
+                object()  # to force objectmode and looplifting
+                c = c * A[::-1][k]   # the slice that is failing in static_getitem
+            return c
+
+        cfoo = jit(foo)
+        # First run just works
+        args = np.arange(10), 1
+        self.assertEqual(foo(*args), cfoo(*args))
+        # Exactly 1 lifted loop so far
+        self.assertEqual(len(cfoo.overloads[cfoo.signatures[0]].lifted), 1)
+        lifted = cfoo.overloads[cfoo.signatures[0]].lifted[0]
+        # The lifted loop has 1 signature
+        self.assertEqual(len(lifted.signatures), 1)
+        # Use different argument to trigger a new compilation of the lifted loop
+        args = np.arange(10), -1
+        self.assertEqual(foo(*args), cfoo(*args))
+        # Ensure that is really a new overload for the lifted loop
+        self.assertEqual(len(lifted.signatures), 2)
+
+
 
 if __name__ == '__main__':
     unittest.main()