Repository: numba/numba

Issue:
Conditions on constant expr not working in stencil
Hello, i just noticed a weird behaviour with condition in stencil:
```
from numba import stencil
import numpy as np

@stencil
def kernel1(a):
    b = 0
    if(2==0): b=2
    return a[0,0]+b

in_arr = np.arange(100).reshape((10, 10))
print(in_arr)
output_arr = kernel1(in_arr)
print(output_arr)
```

the output_arr should be identical to in_arr, but it is not, output:
```
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]
 [60 61 62 63 64 65 66 67 68 69]
 [70 71 72 73 74 75 76 77 78 79]
 [80 81 82 83 84 85 86 87 88 89]
 [90 91 92 93 94 95 96 97 98 99]]
[[  2   3   4   5   6   7   8   9  10  11]
 [ 12  13  14  15  16  17  18  19  20  21]
 [ 22  23  24  25  26  27  28  29  30  31]
 [ 32  33  34  35  36  37  38  39  40  41]
 [ 42  43  44  45  46  47  48  49  50  51]
 [ 52  53  54  55  56  57  58  59  60  61]
 [ 62  63  64  65  66  67  68  69  70  71]
 [ 72  73  74  75  76  77  78  79  80  81]
 [ 82  83  84  85  86  87  88  89  90  91]
 [ 92  93  94  95  96  97  98  99 100 101]]
```
Python:
```
> python --version
> Python 3.6.5 :: Anaconda, Inc.
```
Numba:
```
> numba.__version__
> '0.41.0dev0+94.g361809189'
```

Also, if you try to put `print(2==0)` in the stencil it prints `True`


Discussion:
@ehsantn, @DrTodd13: Any ideas?
operators `>` `<` `>=` `<=` work fine, the only problem is with `==` and `!=`, i tried few combinations and apparently `==` returns always `True`, no matter what, while `!=` return always `False`. Something is definitively wrong in my build.

The obvious workaround is to combine `>` `<` `>=` `<=` to get the expected comparison.
After a quick look, I think this line is the problem:
https://github.com/numba/numba/blob/c24195c89e200fc36354ef0dd50d762886c5947c/numba/lowering.py#L533

the args are supposedly both `ir.UNDEFINED` but for some reason they do not evaluate as `True` under `is`, however the args are equal by reference to each other. As a guess, might be some re-import based issue from re-entering the pipeline/generating code leading to more than one `ir.UNDEFINED` instance. Changing the test there to check whether the args are an instance of `ir.UndefinedType` may well fix.
`ir.UndefinedType` should be a singleton class but it is not enforced. 

Resolving patch:
diff --git a/numba/ir.py b/numba/ir.py
--- a/numba/ir.py
+++ b/numba/ir.py
@@ -1094,6 +1094,18 @@ def dump_generator_info(self, file=None):
 
 # A stub for undefined global reference
 class UndefinedType(object):
+
+    _singleton = None
+
+    def __new__(cls):
+        obj = cls._singleton
+        if obj is not None:
+            return obj
+        else:
+            obj = object.__new__(cls)
+            cls._singleton = obj
+        return obj
+
     def __repr__(self):
         return "Undefined"
 


Test patch:
diff --git a/numba/tests/test_stencils.py b/numba/tests/test_stencils.py
--- a/numba/tests/test_stencils.py
+++ b/numba/tests/test_stencils.py
@@ -2479,6 +2479,17 @@ def kernel(a, b):
                 'neighborhood': (
                     (-3, 0), (-3, 0)), 'standard_indexing': 'b', 'cval': 1.5})
 
+    def test_basic91(self):
+        """ Issue #3454, const(int) == const(int) evaluating incorrectly. """
+        def kernel(a):
+            b = 0
+            if(2 == 0):
+                b = 2
+            return a[0, 0] + b
+
+        a = np.arange(10. * 20.).reshape(10, 20)
+        self.check(kernel, a)
+
 
 if __name__ == "__main__":
     unittest.main()