diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py
index c2d0c76866a00c695b0c687022787bfd0f2f3b75..55505e5269f3bd2dbcfcac6ca8b5483d829c54b9 100644
--- a/Cython/Compiler/Optimize.py
+++ b/Cython/Compiler/Optimize.py
@@ -2129,14 +2129,31 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
         return test_node
 
     def _handle_simple_function_ord(self, node, pos_args):
-        """Unpack ord(Py_UNICODE).
+        """Unpack ord(Py_UNICODE) and ord('X').
         """
         if len(pos_args) != 1:
             return node
         arg = pos_args[0]
         if isinstance(arg, ExprNodes.CoerceToPyTypeNode):
             if arg.arg.type.is_unicode_char:
-                return arg.arg.coerce_to(node.type, self.current_env())
+                return ExprNodes.TypecastNode(
+                    arg.pos, operand=arg.arg, type=PyrexTypes.c_int_type
+                    ).coerce_to(node.type, self.current_env())
+        elif isinstance(arg, ExprNodes.UnicodeNode):
+            if len(arg.value) == 1:
+                return ExprNodes.IntNode(
+                    ord(arg.value), type=PyrexTypes.c_int_type,
+                    value=str(ord(arg.value)),
+                    constant_result=ord(arg.value)
+                    ).coerce_to(node.type, self.current_env())
+        elif isinstance(arg, ExprNodes.StringNode):
+            if arg.unicode_value and len(arg.unicode_value) == 1 \
+                   and ord(arg.unicode_value) <= 255: # Py2/3 portability
+                return ExprNodes.IntNode(
+                    ord(arg.unicode_value), type=PyrexTypes.c_int_type,
+                    value=str(ord(arg.unicode_value)),
+                    constant_result=ord(arg.unicode_value)
+                    ).coerce_to(node.type, self.current_env())
         return node
 
     ### special methods
diff --git a/tests/run/builtin_ord.pyx b/tests/run/builtin_ord.pyx
index 38c20a3c8646cc4157b79957cc8848bd1bf273a2..71e1b734d2bb8f12075a947c26f0cd752fee1553 100644
--- a/tests/run/builtin_ord.pyx
+++ b/tests/run/builtin_ord.pyx
@@ -4,6 +4,26 @@ cimport cython
 ustring_with_a = u'abcdefg'
 ustring_without_a = u'bcdefg'
 
+@cython.test_fail_if_path_exists('//SimpleCallNode')
+def ord_Py_UNICODE(unicode s):
+    """
+    >>> ord_Py_UNICODE(u' ')
+    32
+    """
+    cdef Py_UNICODE u
+    u = s[0]
+    return ord(u)
+
+@cython.test_assert_path_exists('//IntNode')
+@cython.test_fail_if_path_exists('//SimpleCallNode')
+def ord_const():
+    """
+    >>> ord_const()
+    32
+    """
+    return ord(u' ')
+
+@cython.test_assert_path_exists('//PrimaryCmpNode//IntNode')
 @cython.test_fail_if_path_exists('//SimpleCallNode')
 def unicode_for_loop_ord(unicode s):
     """
@@ -13,6 +33,6 @@ def unicode_for_loop_ord(unicode s):
     False
     """
     for c in s:
-        if ord(c) == u'a':
+        if ord(c) == ord(u'a'):
             return True
     return False