diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # kempe
 
+## 0.2.0.5
+
+  * Fix bug in arm control-flow analysis
+  * Fix bugs in IR optimization pass
+  * Improve IR optimization
+  * Add `fromMaybe` and `fromRight` functions
+
 ## 0.2.0.4
 
   * Kind-check external function declarations
diff --git a/golden/Golden.hs b/golden/Golden.hs
new file mode 100644
--- /dev/null
+++ b/golden/Golden.hs
@@ -0,0 +1,29 @@
+module Main (main) where
+
+import           Data.Tuple.Extra (uncurry3)
+import           Harness
+import           System.Info      (arch)
+import           Test.Tasty
+
+main :: IO ()
+main = defaultMain $
+    testGroup "Golden output tests" $
+        fmap (uncurry3 goldenOutput) allGoldens ++ crossTests
+
+-- These are redundant on arm
+crossTests :: [TestTree]
+crossTests = case arch of
+    "x86_64"  -> fmap (uncurry3 crossGolden) allGoldens
+    "aarch64" -> []
+    _         -> error "Test suite must be run on x86_64 or aarch64"
+
+allGoldens :: [(FilePath, FilePath, FilePath)]
+allGoldens =
+    [ ("examples/factorial.kmp", "test/harness/factorial.c", "test/golden/factorial.out")
+    , ("test/examples/splitmix.kmp", "test/harness/splitmix.c", "test/golden/splitmix.out")
+    , ("lib/numbertheory.kmp", "test/harness/numbertheory.c", "test/golden/numbertheory.out")
+    , ("test/examples/hamming.kmp", "test/harness/hamming.c", "test/golden/hamming.out")
+    , ("test/examples/bool.kmp", "test/harness/bool.c", "test/golden/bool.out")
+    , ("test/examples/const.kmp", "test/harness/const.c", "test/golden/const.out")
+    , ("test/data/badCodegen.kmp", "test/harness/id.c", "test/golden/id.out")
+    ]
diff --git a/golden/Harness.hs b/golden/Harness.hs
new file mode 100644
--- /dev/null
+++ b/golden/Harness.hs
@@ -0,0 +1,72 @@
+module Harness ( goldenOutput
+               , crossGolden
+               ) where
+
+import qualified Data.ByteString.Lazy       as BSL
+import qualified Data.ByteString.Lazy.Char8 as ASCII
+import           Data.Functor               (void)
+import           Kempe.File
+import           System.FilePath            ((</>))
+import           System.IO.Temp
+import           System.Info                (arch)
+import           System.Process             (CreateProcess (env, std_err), StdStream (Inherit), proc, readCreateProcess)
+import           Test.Tasty
+import           Test.Tasty.Golden          (goldenVsString)
+import           Test.Tasty.HUnit           (assertBool, testCase)
+
+data CC = CC
+        | ArmCC
+
+instance Show CC where
+    show CC    = "cc"
+    show ArmCC = "aarch64-linux-gnu-gcc"
+
+runGcc :: CC
+       -> [FilePath]
+       -> FilePath
+       -> IO ()
+runGcc cc fps o =
+    void $ readCreateProcess ((proc (show cc) (fps ++ ["-o", o])) { std_err = Inherit }) ""
+
+compileOutput :: FilePath
+              -> FilePath
+              -> IO BSL.ByteString
+compileOutput fp harness =
+    withSystemTempDirectory "kmp" $ \dir -> do
+        let oFile = dir </> "kempe.o"
+            exe = dir </> "kempe"
+            compiler = case arch of
+                "x86_64"  -> compile
+                "aarch64" -> armCompile
+                _         -> error "Internal error in test suite! Must run on either x86_64 or aarch64"
+        compiler fp oFile False
+        runGcc CC [oFile, harness] exe
+        readExe exe
+    where readExe fp' = ASCII.pack <$> readCreateProcess ((proc fp' []) { std_err = Inherit }) ""
+
+crossCompileOutput :: FilePath
+                   -> FilePath
+                   -> IO BSL.ByteString
+crossCompileOutput fp harness =
+    withSystemTempDirectory "kmp" $ \dir -> do
+        let oFile = dir </> "kempe.o"
+            exe = dir </> "kempe"
+        armCompile fp oFile False
+        runGcc ArmCC [oFile, harness] exe
+        readExe exe
+    where readExe fp' = ASCII.pack <$> readCreateProcess ((proc "qemu-aarch64-static" [fp']) { std_err = Inherit, env = qemuEnv }) ""
+          qemuEnv = Just [("QEMU_LD_PREFIX", "/usr/aarch64-linux-gnu/")]
+
+goldenOutput :: FilePath -- ^ Kempe file
+             -> FilePath -- ^ C test harness
+             -> FilePath -- ^ Golden file path
+             -> TestTree
+goldenOutput kFp cFp golden =
+    goldenVsString kFp golden (compileOutput kFp cFp)
+
+crossGolden :: FilePath -- ^ Kempe file
+            -> FilePath -- ^ C test harness
+            -> FilePath -- ^ Golden file path
+            -> TestTree
+crossGolden kFp cFp golden =
+    goldenVsString kFp golden (crossCompileOutput kFp cFp)
diff --git a/kempe.cabal b/kempe.cabal
--- a/kempe.cabal
+++ b/kempe.cabal
@@ -1,6 +1,6 @@
 cabal-version:   3.0
 name:            kempe
-version:         0.2.0.4
+version:         0.2.0.5
 license:         BSD-3-Clause
 license-file:    LICENSE
 copyright:       Copyright: (c) 2020-2021 Vanessa McHale
@@ -12,6 +12,7 @@
 build-type:      Simple
 data-files:
     test/data/*.kmp
+    test/data/diamond/*.kmp
     test/err/*.kmp
     test/examples/*.kmp
     test/golden/*.out
@@ -208,7 +209,7 @@
 test-suite kempe-golden
     type:             exitcode-stdio-1.0
     main-is:          Golden.hs
-    hs-source-dirs:   test
+    hs-source-dirs:   golden
     other-modules:    Harness
     default-language: Haskell2010
     ghc-options:      -threaded -rtsopts "-with-rtsopts=-N -K1K" -Wall
diff --git a/lib/either.kmp b/lib/either.kmp
--- a/lib/either.kmp
+++ b/lib/either.kmp
@@ -3,6 +3,14 @@
 
 type Either a b { Left a | Right b }
 
+fromRight : b ((Either a) b) -- b
+          =: [
+    { case
+        | Left  -> drop
+        | Right -> dip(drop)
+    }
+]
+
 isLeft : ((Either a) b) -- Bool
        =: [
     { case
diff --git a/lib/maybe.kmp b/lib/maybe.kmp
--- a/lib/maybe.kmp
+++ b/lib/maybe.kmp
@@ -1,5 +1,13 @@
 type Maybe a { Just a | Nothing }
 
+fromMaybe : a (Maybe a) -- a
+          =: [
+    { case
+        | Just    -> dip(drop)
+        | Nothing ->
+    }
+]
+
 isJust : (Maybe a) -- Bool
        =: [
     { case
diff --git a/src/Kempe/Asm/Arm/ControlFlow.hs b/src/Kempe/Asm/Arm/ControlFlow.hs
--- a/src/Kempe/Asm/Arm/ControlFlow.hs
+++ b/src/Kempe/Asm/Arm/ControlFlow.hs
@@ -79,6 +79,12 @@
     ; l_i <- lookupLabel l
     ; pure (BranchLink (ControlAnn i [l_i] IS.empty IS.empty) l : nextAsms)
     }
+addControlFlow ((Branch _ l):asms) = do
+    { i <- getFresh
+    ; nextAsms <- addControlFlow asms
+    ; l_i <- lookupLabel l
+    ; pure (Branch (ControlAnn i [l_i] IS.empty IS.empty) l : nextAsms)
+    }
 addControlFlow (Ret{}:asms) = do
     { i <- getFresh
     ; nextAsms <- addControlFlow asms
diff --git a/src/Kempe/Check/Lint.hs b/src/Kempe/Check/Lint.hs
--- a/src/Kempe/Check/Lint.hs
+++ b/src/Kempe/Check/Lint.hs
@@ -8,6 +8,8 @@
 lint :: Declarations a b b -> Maybe (Warning b)
 lint = foldMapAlternative lintDecl
 
+-- TODO: lint for something like dip(0) -> replace with 0 swap
+
 lintDecl :: KempeDecl a b b -> Maybe (Warning b)
 lintDecl Export{}             = Nothing
 lintDecl TyDecl{}             = Nothing
diff --git a/src/Kempe/IR.hs b/src/Kempe/IR.hs
--- a/src/Kempe/IR.hs
+++ b/src/Kempe/IR.hs
@@ -254,6 +254,7 @@
             ret <- newLabel
             let meat' = (++ [Jump ret]) . toList <$> meat
             pure $ dataPointerDec decSz : concatMap toList switches ++ concat meat' ++ [Labeled ret]
+            -- TODO: why dataPointerDec decSz??
 
 zipWithM :: (Applicative m) => (a -> b -> m c) -> NonEmpty a -> NonEmpty b -> m (NonEmpty c)
 zipWithM f xs ys = sequenceA (NE.zipWith f xs ys)
@@ -268,13 +269,15 @@
 patternSwitch :: SizeEnv -> Pattern (ConsAnn MonoStackType) MonoStackType -> Label -> [Stmt]
 patternSwitch _ (PatternBool _ True) l                   = [MJump (Mem 1 (Reg DataPointer)) l]
 patternSwitch _ (PatternBool _ False) l                  = [MJump (EqByte (Mem 1 (Reg DataPointer)) (ConstTag 0)) l]
-patternSwitch _ (PatternWildcard _) l                    = [Jump l]
+patternSwitch _ (PatternWildcard _) l                    = [Jump l] -- FIXME: what about padding? when standing in for a constructor...
 patternSwitch _ (PatternInt _ i) l                       = [MJump (ExprIntRel IntEqIR (Mem 8 (Reg DataPointer)) (ConstInt $ fromInteger i)) l]
 patternSwitch env (PatternCons ann@(ConsAnn _ tag' _) _) l =
     let padAt = padBytes env ann + 1
         -- decrement by padAt bytes (to discard padding), then we need to access
         -- the tag at [datapointer+padAt] when we check
         in [ dataPointerDec padAt, MJump (EqByte (Mem 1 (ExprIntBinOp IntPlusIR (Reg DataPointer) (ConstInt padAt))) (ConstTag tag')) l]
+        -- FIXME: do we need dataPointerInc padAt at the end? not all
+        -- constructors will have the same padding, it will fall through...
 
 -- | Constructors may need to be padded, this computes the number of bytes of
 -- padding
diff --git a/src/Kempe/IR/Opt.hs b/src/Kempe/IR/Opt.hs
--- a/src/Kempe/IR/Opt.hs
+++ b/src/Kempe/IR/Opt.hs
@@ -43,12 +43,12 @@
     ((MovTemp DataPointer (ExprIntBinOp IntPlusIR (Reg DataPointer) (ConstInt i)))
         :(MovTemp DataPointer (ExprIntBinOp IntMinusIR (Reg DataPointer) (ConstInt i')))
         :ss) =
-            MovTemp DataPointer (ExprIntBinOp IntMinusIR (Reg DataPointer) (ConstInt $ i-i')) : successiveBumps ss
+            MovTemp DataPointer (ExprIntBinOp IntPlusIR (Reg DataPointer) (ConstInt $ i-i')) : successiveBumps ss
 successiveBumps
     ((MovTemp DataPointer (ExprIntBinOp IntMinusIR (Reg DataPointer) (ConstInt i)))
         :(MovTemp DataPointer (ExprIntBinOp IntPlusIR (Reg DataPointer) (ConstInt i')))
-        :ss) =
-            MovTemp DataPointer (ExprIntBinOp IntMinusIR (Reg DataPointer) (ConstInt $ i'-i)) : successiveBumps ss
+        :ss) = -- TODO: is this particular one right?
+            MovTemp DataPointer (ExprIntBinOp IntMinusIR (Reg DataPointer) (ConstInt $ i-i')) : successiveBumps ss
 successiveBumps
     (st@(MovMem e0 k (Mem 8 e1))
         :(MovMem e0' k' (Mem 8 e1'))
@@ -74,11 +74,18 @@
 liftOptE []                       = []
 liftOptE ((MovMem e0 sz e1) : ss) = MovMem (optE e0) sz (optE e1) : liftOptE ss
 liftOptE ((MovTemp t e) : ss)     = MovTemp t (optE e) : liftOptE ss
+liftOptE ((MJump e l) : ss)       = MJump (optE e) l : liftOptE ss
+liftOptE ((CJump e l0 l1) : ss)   = CJump (optE e) l0 l1 : liftOptE ss
 liftOptE (s:ss)                   = s : liftOptE ss
 
 optE :: Exp -> Exp
 optE (ExprIntBinOp IntPlusIR e (ConstInt 0))  = optE e
 optE (ExprIntBinOp IntMinusIR e (ConstInt 0)) = optE e
+optE (BoolBinOp op e e')                      = BoolBinOp op (optE e) (optE e')
+optE (Mem sz e)                               = Mem sz (optE e)
+optE (PopcountIR e)                           = PopcountIR (optE e)
+optE (IntNegIR e)                             = IntNegIR (optE e)
+optE (EqByte e e')                            = EqByte (optE e) (optE e')
 optE e                                        = e
 
 removeNop :: [Stmt] -> [Stmt]
diff --git a/src/Kempe/TyAssign.hs b/src/Kempe/TyAssign.hs
--- a/src/Kempe/TyAssign.hs
+++ b/src/Kempe/TyAssign.hs
@@ -492,7 +492,7 @@
 tyPattern :: Pattern b a -> TypeM () (StackType ())
 tyPattern PatternWildcard{} = do
     aN <- dummyName "a"
-    pure $ StackType (S.singleton aN) [TyVar () aN] []
+    pure $ StackType (S.singleton aN) [TyVar () aN] [] -- FIXME: this is wrong for constructors, could be a -- b c (for instance)
 tyPattern PatternInt{} = pure $ StackType S.empty [TyBuiltin () TyInt] []
 tyPattern PatternBool{} = pure $ StackType S.empty [TyBuiltin () TyBool] []
 tyPattern (PatternCons _ tn) = renameStack . flipStackType =<< consLookup (void tn)
diff --git a/test/Golden.hs b/test/Golden.hs
deleted file mode 100644
--- a/test/Golden.hs
+++ /dev/null
@@ -1,28 +0,0 @@
-module Main (main) where
-
-import           Data.Tuple.Extra (uncurry3)
-import           Harness
-import           System.Info      (arch)
-import           Test.Tasty
-
-main :: IO ()
-main = defaultMain $
-    testGroup "Golden output tests" $
-        fmap (uncurry3 goldenOutput) allGoldens ++ crossTests
-
--- These are redundant on arm
-crossTests :: [TestTree]
-crossTests = case arch of
-    "x86_64"  -> fmap (uncurry3 crossGolden) allGoldens
-    "aarch64" -> []
-    _         -> error "Test suite must be run on x86_64 or aarch64"
-
-allGoldens :: [(FilePath, FilePath, FilePath)]
-allGoldens =
-    [ ("examples/factorial.kmp", "test/harness/factorial.c", "test/golden/factorial.out")
-    , ("test/examples/splitmix.kmp", "test/harness/splitmix.c", "test/golden/splitmix.out")
-    , ("lib/numbertheory.kmp", "test/harness/numbertheory.c", "test/golden/numbertheory.out")
-    , ("test/examples/hamming.kmp", "test/harness/hamming.c", "test/golden/hamming.out")
-    , ("test/examples/bool.kmp", "test/harness/bool.c", "test/golden/bool.out")
-    , ("test/examples/const.kmp", "test/harness/const.c", "test/golden/const.out")
-    ]
diff --git a/test/Harness.hs b/test/Harness.hs
deleted file mode 100644
--- a/test/Harness.hs
+++ /dev/null
@@ -1,72 +0,0 @@
-module Harness ( goldenOutput
-               , crossGolden
-               ) where
-
-import qualified Data.ByteString.Lazy       as BSL
-import qualified Data.ByteString.Lazy.Char8 as ASCII
-import           Data.Functor               (void)
-import           Kempe.File
-import           System.FilePath            ((</>))
-import           System.IO.Temp
-import           System.Info                (arch)
-import           System.Process             (CreateProcess (env, std_err), StdStream (Inherit), proc, readCreateProcess)
-import           Test.Tasty
-import           Test.Tasty.Golden          (goldenVsString)
-import           Test.Tasty.HUnit           (assertBool, testCase)
-
-data CC = CC
-        | ArmCC
-
-instance Show CC where
-    show CC    = "cc"
-    show ArmCC = "aarch64-linux-gnu-gcc"
-
-runGcc :: CC
-       -> [FilePath]
-       -> FilePath
-       -> IO ()
-runGcc cc fps o =
-    void $ readCreateProcess ((proc (show cc) (fps ++ ["-o", o])) { std_err = Inherit }) ""
-
-compileOutput :: FilePath
-              -> FilePath
-              -> IO BSL.ByteString
-compileOutput fp harness =
-    withSystemTempDirectory "kmp" $ \dir -> do
-        let oFile = dir </> "kempe.o"
-            exe = dir </> "kempe"
-            compiler = case arch of
-                "x86_64"  -> compile
-                "aarch64" -> armCompile
-                _         -> error "Internal error in test suite! Must run on either x86_64 or aarch64"
-        compiler fp oFile False
-        runGcc CC [oFile, harness] exe
-        readExe exe
-    where readExe fp' = ASCII.pack <$> readCreateProcess ((proc fp' []) { std_err = Inherit }) ""
-
-crossCompileOutput :: FilePath
-                   -> FilePath
-                   -> IO BSL.ByteString
-crossCompileOutput fp harness =
-    withSystemTempDirectory "kmp" $ \dir -> do
-        let oFile = dir </> "kempe.o"
-            exe = dir </> "kempe"
-        armCompile fp oFile False
-        runGcc ArmCC [oFile, harness] exe
-        readExe exe
-    where readExe fp' = ASCII.pack <$> readCreateProcess ((proc "qemu-aarch64-static" [fp']) { std_err = Inherit, env = qemuEnv }) ""
-          qemuEnv = Just [("QEMU_LD_PREFIX", "/usr/aarch64-linux-gnu/")]
-
-goldenOutput :: FilePath -- ^ Kempe file
-             -> FilePath -- ^ C test harness
-             -> FilePath -- ^ Golden file path
-             -> TestTree
-goldenOutput kFp cFp golden =
-    goldenVsString kFp golden (compileOutput kFp cFp)
-
-crossGolden :: FilePath -- ^ Kempe file
-            -> FilePath -- ^ C test harness
-            -> FilePath -- ^ Golden file path
-            -> TestTree
-crossGolden kFp cFp golden =
-    goldenVsString kFp golden (crossCompileOutput kFp cFp)
diff --git a/test/Type.hs b/test/Type.hs
--- a/test/Type.hs
+++ b/test/Type.hs
@@ -27,6 +27,7 @@
         , tyInfer "lib/gaussian.kmp"
         , tyInfer "test/data/transitive.kmp"
         , tyInfer "lib/tuple.kmp"
+        , tyInfer "test/data/type.kmp"
         , badType "test/err/merge.kmp" "Type a_5 -- Int a_4 is not as general as type a_3 -- a_3 a_3"
         , badType "test/err/kind.kmp" "Ill-kinded type: '(Maybe_1 Maybe_1)'. Note that type variables have kind \11089 in Kempe."
         , badType "test/err/patternMatch.kmp" "Inexhaustive pattern match."
diff --git a/test/data/badCodegen.kmp b/test/data/badCodegen.kmp
new file mode 100644
--- /dev/null
+++ b/test/data/badCodegen.kmp
@@ -0,0 +1,15 @@
+import "lib/maybe.kmp"
+
+id0 : Int -- Int
+      =: [ Just dip(0) fromMaybe ]
+
+id1 : Int -- Int
+     =: [ Just {case | Nothing -> 0 | Just ->} ]
+
+id2 : Int -- Int
+    =: [ Just 0 swap {case | Just -> dip(drop) | Nothing ->} ]
+    ; Just 0 swap drop swap works
+
+%foreign cabi id0
+%foreign cabi id1
+%foreign cabi id2
diff --git a/test/data/diamond/a.kmp b/test/data/diamond/a.kmp
new file mode 100644
--- /dev/null
+++ b/test/data/diamond/a.kmp
@@ -0,0 +1,7 @@
+import "test/data/diamond/c.kmp"
+import "test/data/diamond/b.kmp"
+
+forExport : -- Int
+          =: [ res 2 * ]
+
+%foreign cabi forExport
diff --git a/test/data/diamond/b.kmp b/test/data/diamond/b.kmp
new file mode 100644
--- /dev/null
+++ b/test/data/diamond/b.kmp
@@ -0,0 +1,2 @@
+rand : -- Int
+     =: $cfun"rand"
diff --git a/test/data/diamond/c.kmp b/test/data/diamond/c.kmp
new file mode 100644
--- /dev/null
+++ b/test/data/diamond/c.kmp
@@ -0,0 +1,4 @@
+import "test/data/diamond/d.kmp"
+
+res : -- Int
+    =: [ rand 1 + ]
diff --git a/test/data/diamond/d.kmp b/test/data/diamond/d.kmp
new file mode 100644
--- /dev/null
+++ b/test/data/diamond/d.kmp
@@ -0,0 +1,2 @@
+rand : -- Int
+     =: [ 17 ]
diff --git a/test/data/type.kmp b/test/data/type.kmp
new file mode 100644
--- /dev/null
+++ b/test/data/type.kmp
@@ -0,0 +1,4 @@
+import"lib/maybe.kmp"
+
+id1 : Int -- Int
+     =: [ Just {case | Nothing -> 0 | _ ->} ]
diff --git a/test/golden/gaussian.ir b/test/golden/gaussian.ir
--- a/test/golden/gaussian.ir
+++ b/test/golden/gaussian.ir
@@ -6,7 +6,7 @@
 (movmem (+ (reg datapointer) (int 16)) (mem [1] (+ (reg datapointer) (int 33))))
 (movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 24))))
 (movmem (- (reg datapointer) (int 24)) (mem [8] (- (reg datapointer) (int 16))))
-(movmem (- (reg datapointer) (int 16)) (mem [8] (- (reg datapointer) (int 0))))
+(movmem (- (reg datapointer) (int 16)) (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 8)))
 (movtemp t_1 (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 8)))
@@ -31,7 +31,6 @@
 (movmem (- (reg datapointer) (int 17)) (mem [8] (- (reg datapointer) (int 34))))
 (movmem (- (reg datapointer) (int 9)) (mem [8] (- (reg datapointer) (int 26))))
 (movmem (- (reg datapointer) (int 1)) (mem [1] (- (reg datapointer) (int 18))))
-(movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 0))))
 (movtemp datapointer (+ (reg datapointer) (int 17)))
 (movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 34))))
 (movmem (+ (reg datapointer) (int 8)) (mem [8] (- (reg datapointer) (int 26))))
@@ -39,7 +38,7 @@
 (movmem (- (reg datapointer) (int 34)) (mem [8] (- (reg datapointer) (int 17))))
 (movmem (- (reg datapointer) (int 26)) (mem [8] (- (reg datapointer) (int 9))))
 (movmem (- (reg datapointer) (int 18)) (mem [1] (- (reg datapointer) (int 1))))
-(movmem (- (reg datapointer) (int 17)) (mem [8] (- (reg datapointer) (int 0))))
+(movmem (- (reg datapointer) (int 17)) (mem [8] (reg datapointer)))
 (movmem (- (reg datapointer) (int 9)) (mem [8] (+ (reg datapointer) (int 8))))
 (movmem (- (reg datapointer) (int 1)) (mem [1] (+ (reg datapointer) (int 16))))
 (movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 17))))
@@ -48,7 +47,6 @@
 (movmem (- (reg datapointer) (int 17)) (mem [8] (- (reg datapointer) (int 34))))
 (movmem (- (reg datapointer) (int 9)) (mem [8] (- (reg datapointer) (int 26))))
 (movmem (- (reg datapointer) (int 1)) (mem [1] (- (reg datapointer) (int 18))))
-(movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 0))))
 (movtemp datapointer (+ (reg datapointer) (int 17)))
 (movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 34))))
 (movmem (+ (reg datapointer) (int 8)) (mem [8] (- (reg datapointer) (int 26))))
@@ -56,7 +54,7 @@
 (movmem (- (reg datapointer) (int 34)) (mem [8] (- (reg datapointer) (int 17))))
 (movmem (- (reg datapointer) (int 26)) (mem [8] (- (reg datapointer) (int 9))))
 (movmem (- (reg datapointer) (int 18)) (mem [1] (- (reg datapointer) (int 1))))
-(movmem (- (reg datapointer) (int 17)) (mem [8] (- (reg datapointer) (int 0))))
+(movmem (- (reg datapointer) (int 17)) (mem [8] (reg datapointer)))
 (movmem (- (reg datapointer) (int 9)) (mem [8] (+ (reg datapointer) (int 8))))
 (movmem (- (reg datapointer) (int 1)) (mem [1] (+ (reg datapointer) (int 16))))
 (movtemp datapointer (- (reg datapointer) (int 34)))
@@ -73,7 +71,7 @@
 (movtemp datapointer (+ (reg datapointer) (int 8)))
 (movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 16))))
 (movmem (- (reg datapointer) (int 16)) (mem [8] (- (reg datapointer) (int 8))))
-(movmem (- (reg datapointer) (int 8)) (mem [8] (- (reg datapointer) (int 0))))
+(movmem (- (reg datapointer) (int 8)) (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 16)))
 (movtemp t_7 (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 8)))
@@ -85,17 +83,16 @@
 (movtemp datapointer (- (reg datapointer) (int 8)))
 (movtemp t_10 (mem [8] (reg datapointer)))
 (movmem (reg datapointer) (+ (reg t_10) (reg t_9)))
-(movtemp datapointer (- (reg datapointer) (int 0)))
+(movtemp datapointer (+ (reg datapointer) (int -34)))
 (movmem (reg datapointer) (mem [8] (+ (reg datapointer) (int 25))))
 (movmem (+ (reg datapointer) (int 8)) (mem [8] (+ (reg datapointer) (int 33))))
 (movmem (+ (reg datapointer) (int 16)) (mem [8] (+ (reg datapointer) (int 41))))
 (movmem (+ (reg datapointer) (int 24)) (mem [1] (+ (reg datapointer) (int 49))))
-(movtemp datapointer (- (reg datapointer) (int 34)))
 (movmem (reg datapointer) (mem [8] (+ (reg datapointer) (int 8))))
 (movtemp datapointer (+ (reg datapointer) (int 8)))
 (movmem (reg datapointer) (mem [8] (- (reg datapointer) (int 32))))
 (movmem (- (reg datapointer) (int 32)) (mem [8] (- (reg datapointer) (int 24))))
-(movmem (- (reg datapointer) (int 24)) (mem [8] (- (reg datapointer) (int 0))))
+(movmem (- (reg datapointer) (int 24)) (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 16)))
 (movtemp t_11 (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 8)))
@@ -103,7 +100,7 @@
 (movmem (reg datapointer) (* (reg t_12) (reg t_11)))
 (movtemp datapointer (+ (reg datapointer) (int 8)))
 (movmem (reg datapointer) (mem [8] (+ (reg datapointer) (int 8))))
-(movtemp datapointer (- (reg datapointer) (int 0)))
+(movtemp datapointer (+ (reg datapointer) (int -16)))
 (movtemp t_13 (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 8)))
 (movtemp t_14 (mem [8] (reg datapointer)))
@@ -111,7 +108,6 @@
 (movtemp datapointer (+ (reg datapointer) (int 8)))
 (movmem (reg datapointer) (mem [8] (+ (reg datapointer) (int 16))))
 (movmem (+ (reg datapointer) (int 8)) (mem [8] (+ (reg datapointer) (int 24))))
-(movtemp datapointer (- (reg datapointer) (int 16)))
 (movtemp t_15 (mem [8] (reg datapointer)))
 (movtemp datapointer (- (reg datapointer) (int 8)))
 (movtemp t_16 (mem [8] (reg datapointer)))
diff --git a/test/golden/id.out b/test/golden/id.out
new file mode 100644
--- /dev/null
+++ b/test/golden/id.out
@@ -0,0 +1,3 @@
+4
+4
+4
diff --git a/test/harness/id.c b/test/harness/id.c
new file mode 100644
--- /dev/null
+++ b/test/harness/id.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+extern int id0(int);
+extern int id1(int);
+extern int id2(int);
+
+int main(int argc, char *argv[]) {
+    printf("%d\n", id0(4));
+    printf("%d\n", id1(4));
+    printf("%d", id2(4));
+}
