diff --git a/ARMeilleure/CodeGen/Optimizations/Optimizer.cs b/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
index 06118bfd6d..438010a2ee 100644
--- a/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
+++ b/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
@@ -2,6 +2,8 @@ using ARMeilleure.IntermediateRepresentation;
 using ARMeilleure.Translation;
 using System.Diagnostics;
 
+using static ARMeilleure.IntermediateRepresentation.OperandHelper;
+
 namespace ARMeilleure.CodeGen.Optimizations
 {
     static class Optimizer
@@ -42,13 +44,25 @@ namespace ARMeilleure.CodeGen.Optimizations
 
                         Simplification.RunPass(operation);
 
-                        if (DestIsLocalVar(operation) && IsPropagableCopy(operation))
-                        {
-                            PropagateCopy(operation);
+                        if (DestIsLocalVar(operation))
+                        {   
+                            if (IsPropagableCompare(operation))
+                            {
+                                modified |= PropagateCompare(operation);
 
-                            RemoveNode(block, node);
+                                if (modified && IsUnused(operation))
+                                {
+                                    RemoveNode(block, node);
+                                }
+                            }
+                            else if (IsPropagableCopy(operation))
+                            {
+                                PropagateCopy(operation);
 
-                            modified = true;
+                                RemoveNode(block, node);
+
+                                modified = true;
+                            }
                         }
 
                         node = nextNode;
@@ -88,6 +102,91 @@ namespace ARMeilleure.CodeGen.Optimizations
             while (modified);
         }
 
+        private static bool PropagateCompare(Operation compOp)
+        {
+            // Try to propagate Compare operations into their BranchIf uses, when these BranchIf uses are in the form
+            // of:
+            //
+            // - BranchIf %x, 0x0, Equal        ;; i.e BranchIfFalse %x
+            // - BranchIf %x, 0x0, NotEqual     ;; i.e BranchIfTrue %x
+            //
+            // The commutative property of Equal and NotEqual is taken into consideration as well.
+            //
+            // For example:
+            //
+            //  %x = Compare %a, %b, comp
+            //  BranchIf %x, 0x0, NotEqual
+            //
+            // =>
+            //
+            //  BranchIf %a, %b, comp
+
+            static bool IsZeroBranch(Operation operation, out Comparison compType)
+            {
+                compType = Comparison.Equal;
+
+                if (operation.Instruction != Instruction.BranchIf)
+                {
+                    return false;
+                }
+
+                Operand src1 = operation.GetSource(0);
+                Operand src2 = operation.GetSource(1);
+                Operand comp = operation.GetSource(2);
+
+                compType = (Comparison)comp.AsInt32();
+
+                return (src1.Kind == OperandKind.Constant && src1.Value == 0) ||
+                       (src2.Kind == OperandKind.Constant && src2.Value == 0);
+            }
+
+            bool modified = false;
+
+            Operand dest = compOp.Destination;
+            Operand src1 = compOp.GetSource(0);
+            Operand src2 = compOp.GetSource(1);
+            Operand comp = compOp.GetSource(2);
+
+            Comparison compType = (Comparison)comp.AsInt32();
+
+            Node[] uses = dest.Uses.ToArray();
+
+            foreach (Node use in uses)
+            {
+                if (!(use is Operation operation))
+                {
+                    continue;
+                }
+
+                // If operation is a BranchIf and has a constant value 0 in its RHS or LHS source operands.
+                if (IsZeroBranch(operation, out Comparison otherCompType))
+                {
+                    Comparison propCompType;
+
+                    if (otherCompType == Comparison.NotEqual)
+                    {
+                        propCompType = compType;
+                    }
+                    else if (otherCompType == Comparison.Equal)
+                    {
+                        propCompType = compType.Invert();
+                    }
+                    else
+                    {
+                        continue;
+                    }
+
+                    operation.SetSource(0, src1);
+                    operation.SetSource(1, src2);
+                    operation.SetSource(2, Const((int)propCompType));
+
+                    modified = true;
+                }
+            }
+
+            return modified;
+        }
+
         private static void PropagateCopy(Operation copyOp)
         {
             // Propagate copy source operand to all uses of the destination operand.
@@ -143,6 +242,11 @@ namespace ARMeilleure.CodeGen.Optimizations
                 || operation.Instruction == Instruction.CompareAndSwap8);
         }
 
+        private static bool IsPropagableCompare(Operation operation)
+        {
+            return operation.Instruction == Instruction.Compare;
+        }
+
         private static bool IsPropagableCopy(Operation operation)
         {
             if (operation.Instruction != Instruction.Copy)
diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
index f04be52dae..f2d4c46276 100644
--- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs
+++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
@@ -33,24 +33,14 @@ namespace ARMeilleure.CodeGen.X86
             Add(Instruction.BitwiseNot,              GenerateBitwiseNot);
             Add(Instruction.BitwiseOr,               GenerateBitwiseOr);
             Add(Instruction.Branch,                  GenerateBranch);
-            Add(Instruction.BranchIfFalse,           GenerateBranchIfFalse);
-            Add(Instruction.BranchIfTrue,            GenerateBranchIfTrue);
+            Add(Instruction.BranchIf,                GenerateBranchIf);
             Add(Instruction.ByteSwap,                GenerateByteSwap);
             Add(Instruction.Call,                    GenerateCall);
             Add(Instruction.Clobber,                 GenerateClobber);
+            Add(Instruction.Compare,                 GenerateCompare);
             Add(Instruction.CompareAndSwap,          GenerateCompareAndSwap);
             Add(Instruction.CompareAndSwap16,        GenerateCompareAndSwap16);
             Add(Instruction.CompareAndSwap8,         GenerateCompareAndSwap8);
-            Add(Instruction.CompareEqual,            GenerateCompareEqual);
-            Add(Instruction.CompareGreater,          GenerateCompareGreater);
-            Add(Instruction.CompareGreaterOrEqual,   GenerateCompareGreaterOrEqual);
-            Add(Instruction.CompareGreaterOrEqualUI, GenerateCompareGreaterOrEqualUI);
-            Add(Instruction.CompareGreaterUI,        GenerateCompareGreaterUI);
-            Add(Instruction.CompareLess,             GenerateCompareLess);
-            Add(Instruction.CompareLessOrEqual,      GenerateCompareLessOrEqual);
-            Add(Instruction.CompareLessOrEqualUI,    GenerateCompareLessOrEqualUI);
-            Add(Instruction.CompareLessUI,           GenerateCompareLessUI);
-            Add(Instruction.CompareNotEqual,         GenerateCompareNotEqual);
             Add(Instruction.ConditionalSelect,       GenerateConditionalSelect);
             Add(Instruction.ConvertI64ToI32,         GenerateConvertI64ToI32);
             Add(Instruction.ConvertToFP,             GenerateConvertToFP);
@@ -474,6 +464,8 @@ namespace ARMeilleure.CodeGen.X86
 
             Debug.Assert(dest.Type.IsInteger());
 
+            // Note: GenerateCompareCommon makes the assumption that BitwiseAnd will emit only a single `and`
+            // instruction.
             context.Assembler.And(dest, src2, dest.Type);
         }
 
@@ -525,22 +517,17 @@ namespace ARMeilleure.CodeGen.X86
             context.JumpTo(context.CurrBlock.Branch);
         }
 
-        private static void GenerateBranchIfFalse(CodeGenContext context, Operation operation)
+        private static void GenerateBranchIf(CodeGenContext context, Operation operation)
         {
-            Operand source = operation.GetSource(0);
+            Operand comp = operation.GetSource(2);
 
-            context.Assembler.Test(source, source, source.Type);
+            Debug.Assert(comp.Kind == OperandKind.Constant);
 
-            context.JumpTo(X86Condition.Equal, context.CurrBlock.Branch);
-        }
+            var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
 
-        private static void GenerateBranchIfTrue(CodeGenContext context, Operation operation)
-        {
-            Operand source = operation.GetSource(0);
+            GenerateCompareCommon(context, operation);
 
-            context.Assembler.Test(source, source, source.Type);
-
-            context.JumpTo(X86Condition.NotEqual, context.CurrBlock.Branch);
+            context.JumpTo(cond, context.CurrBlock.Branch);
         }
 
         private static void GenerateByteSwap(CodeGenContext context, Operation operation)
@@ -566,6 +553,60 @@ namespace ARMeilleure.CodeGen.X86
             // register allocator, we don't need to produce any code.
         }
 
+        private static void GenerateCompare(CodeGenContext context, Operation operation)
+        {
+            Operand dest = operation.Destination;
+            Operand comp = operation.GetSource(2);
+
+            Debug.Assert(dest.Type == OperandType.I32);
+            Debug.Assert(comp.Kind == OperandKind.Constant);
+
+            var cond = ((Comparison)comp.AsInt32()).ToX86Condition();
+
+            GenerateCompareCommon(context, operation);
+
+            context.Assembler.Setcc(dest, cond);
+            context.Assembler.Movzx8(dest, dest, OperandType.I32);
+        }
+
+        private static void GenerateCompareCommon(CodeGenContext context, Operation operation)
+        {
+            Operand src1 = operation.GetSource(0);
+            Operand src2 = operation.GetSource(1);
+
+            EnsureSameType(src1, src2);
+
+            Debug.Assert(src1.Type.IsInteger());
+
+            if (src2.Kind == OperandKind.Constant && src2.Value == 0)
+            {
+                if (MatchOperation(operation.ListPrevious, Instruction.BitwiseAnd, src1.Type, src1.GetRegister()))
+                {
+                    // Since the `test` and `and` instruction set the status flags in the same way, we can omit the
+                    // `test r,r` instruction when it is immediately preceded by an `and r,*` instruction.
+                    //
+                    // For example:
+                    //
+                    //  and eax, 0x3
+                    //  test eax, eax
+                    //  jz .L0
+                    //
+                    // =>
+                    //
+                    //  and eax, 0x3
+                    //  jz .L0
+                }
+                else
+                {
+                    context.Assembler.Test(src1, src1, src1.Type);
+                }
+            }
+            else
+            {
+                context.Assembler.Cmp(src1, src2, src1.Type);
+            }
+        }
+
         private static void GenerateCompareAndSwap(CodeGenContext context, Operation operation)
         {
             Operand src1 = operation.GetSource(0);
@@ -615,71 +656,6 @@ namespace ARMeilleure.CodeGen.X86
             context.Assembler.Cmpxchg8(memOp, src3);
         }
 
-        private static void GenerateCompareEqual(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.Equal);
-        }
-
-        private static void GenerateCompareGreater(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.Greater);
-        }
-
-        private static void GenerateCompareGreaterOrEqual(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.GreaterOrEqual);
-        }
-
-        private static void GenerateCompareGreaterOrEqualUI(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.AboveOrEqual);
-        }
-
-        private static void GenerateCompareGreaterUI(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.Above);
-        }
-
-        private static void GenerateCompareLess(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.Less);
-        }
-
-        private static void GenerateCompareLessOrEqual(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.LessOrEqual);
-        }
-
-        private static void GenerateCompareLessOrEqualUI(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.BelowOrEqual);
-        }
-
-        private static void GenerateCompareLessUI(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.Below);
-        }
-
-        private static void GenerateCompareNotEqual(CodeGenContext context, Operation operation)
-        {
-            GenerateCompare(context, operation, X86Condition.NotEqual);
-        }
-
-        private static void GenerateCompare(CodeGenContext context, Operation operation, X86Condition condition)
-        {
-            Operand dest = operation.Destination;
-            Operand src1 = operation.GetSource(0);
-            Operand src2 = operation.GetSource(1);
-
-            EnsureSameType(src1, src2);
-
-            Debug.Assert(dest.Type == OperandType.I32);
-
-            context.Assembler.Cmp(src1, src2, src1.Type);
-            context.Assembler.Setcc(dest, condition);
-            context.Assembler.Movzx8(dest, dest, OperandType.I32);
-        }
-
         private static void GenerateConditionalSelect(CodeGenContext context, Operation operation)
         {
             Operand dest = operation.Destination;
@@ -1561,6 +1537,25 @@ namespace ARMeilleure.CodeGen.X86
             context.Assembler.Pshufd(dest, dest, 0xfc);
         }
 
+        private static bool MatchOperation(Node node, Instruction inst, OperandType destType, Register destReg)
+        {
+            if (!(node is Operation operation) || node.DestinationsCount == 0)
+            {
+                return false;
+            }
+
+            if (operation.Instruction != inst)
+            {
+                return false;
+            }
+
+            Operand dest = operation.Destination;
+
+            return dest.Kind == OperandKind.Register &&
+                   dest.Type == destType &&
+                   dest.GetRegister() == destReg;
+        }
+
         [Conditional("DEBUG")]
         private static void ValidateUnOp(Operand dest, Operand source)
         {
diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs
index b76e941697..2f430b6fb5 100644
--- a/ARMeilleure/CodeGen/X86/PreAllocator.cs
+++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs
@@ -154,7 +154,7 @@ namespace ARMeilleure.CodeGen.X86
                     // -- Doing so may allow us to encode the constant as operand 2 and avoid a copy.
                     // - If the constant is on operand 2, we check if the instruction supports it,
                     // if not, we also add a copy. 64-bits constants are usually not supported.
-                    if (IsCommutative(inst))
+                    if (IsCommutative(operation))
                     {
                         src2 = operation.GetSource(1);
 
@@ -1348,16 +1348,8 @@ namespace ARMeilleure.CodeGen.X86
                 case Instruction.BitwiseAnd:
                 case Instruction.BitwiseExclusiveOr:
                 case Instruction.BitwiseOr:
-                case Instruction.CompareEqual:
-                case Instruction.CompareGreater:
-                case Instruction.CompareGreaterOrEqual:
-                case Instruction.CompareGreaterOrEqualUI:
-                case Instruction.CompareGreaterUI:
-                case Instruction.CompareLess:
-                case Instruction.CompareLessOrEqual:
-                case Instruction.CompareLessOrEqualUI:
-                case Instruction.CompareLessUI:
-                case Instruction.CompareNotEqual:
+                case Instruction.BranchIf:
+                case Instruction.Compare:
                 case Instruction.Multiply:
                 case Instruction.RotateRight:
                 case Instruction.ShiftLeft:
@@ -1376,18 +1368,28 @@ namespace ARMeilleure.CodeGen.X86
             return false;
         }
 
-        private static bool IsCommutative(Instruction inst)
+        private static bool IsCommutative(Operation operation)
         {
-            switch (inst)
+            switch (operation.Instruction)
             {
                 case Instruction.Add:
                 case Instruction.BitwiseAnd:
                 case Instruction.BitwiseExclusiveOr:
                 case Instruction.BitwiseOr:
-                case Instruction.CompareEqual:
-                case Instruction.CompareNotEqual:
                 case Instruction.Multiply:
                     return true;
+
+                case Instruction.BranchIf:
+                case Instruction.Compare:
+                {
+                    Operand comp = operation.GetSource(2);
+
+                    Debug.Assert(comp.Kind == OperandKind.Constant);
+
+                    var compType = (Comparison)comp.AsInt32();
+
+                    return compType == Comparison.Equal || compType == Comparison.NotEqual;
+                }
             }
 
             return false;
diff --git a/ARMeilleure/CodeGen/X86/X86Condition.cs b/ARMeilleure/CodeGen/X86/X86Condition.cs
index a17c6d6c58..c82cbdec59 100644
--- a/ARMeilleure/CodeGen/X86/X86Condition.cs
+++ b/ARMeilleure/CodeGen/X86/X86Condition.cs
@@ -1,3 +1,6 @@
+using ARMeilleure.IntermediateRepresentation;
+using System;
+
 namespace ARMeilleure.CodeGen.X86
 {
     enum X86Condition
@@ -19,4 +22,26 @@ namespace ARMeilleure.CodeGen.X86
         LessOrEqual    = 0xe,
         Greater        = 0xf
     }
+
+    static class ComparisonX86Extensions
+    {
+        public static X86Condition ToX86Condition(this Comparison comp)
+        {
+            return comp switch
+            {
+                Comparison.Equal            => X86Condition.Equal,
+                Comparison.NotEqual         => X86Condition.NotEqual,
+                Comparison.Greater          => X86Condition.Greater,
+                Comparison.LessOrEqual      => X86Condition.LessOrEqual,
+                Comparison.GreaterUI        => X86Condition.Above,
+                Comparison.LessOrEqualUI    => X86Condition.BelowOrEqual,
+                Comparison.GreaterOrEqual   => X86Condition.GreaterOrEqual,
+                Comparison.Less             => X86Condition.Less,
+                Comparison.GreaterOrEqualUI => X86Condition.AboveOrEqual,
+                Comparison.LessUI           => X86Condition.Below,
+
+                _ => throw new ArgumentException(null, nameof(comp))
+            };
+        }
+    }
 }
\ No newline at end of file
diff --git a/ARMeilleure/Diagnostics/IRDumper.cs b/ARMeilleure/Diagnostics/IRDumper.cs
index 7ff7607726..0f0d72c157 100644
--- a/ARMeilleure/Diagnostics/IRDumper.cs
+++ b/ARMeilleure/Diagnostics/IRDumper.cs
@@ -198,6 +198,8 @@ namespace ARMeilleure.Diagnostics
                     break;
 
                 case Operation operation:
+                    bool comparison = false;
+
                     _builder.Append(operation.Instruction);
 
                     if (operation.Instruction == Instruction.Extended)
@@ -206,17 +208,32 @@ namespace ARMeilleure.Diagnostics
 
                         _builder.Append('.').Append(intrinOp.Intrinsic);
                     }
+                    else if (operation.Instruction == Instruction.BranchIf ||
+                             operation.Instruction == Instruction.Compare)
+                    {
+                        comparison = true;
+                    }
 
                     _builder.Append(' ');
 
                     for (int index = 0; index < operation.SourcesCount; index++)
                     {
-                        DumpOperand(operation.GetSource(index));
+                        Operand source = operation.GetSource(index);
 
                         if (index < operation.SourcesCount - 1)
                         {
+                            DumpOperand(source);
+
                             _builder.Append(", ");
                         }
+                        else if (comparison)
+                        {
+                            _builder.Append((Comparison)source.AsInt32());
+                        }
+                        else
+                        {
+                            DumpOperand(source);
+                        }
                     }
                     break;
             }
diff --git a/ARMeilleure/Instructions/InstEmitFlowHelper.cs b/ARMeilleure/Instructions/InstEmitFlowHelper.cs
index 6906f78204..1ce0cdaa3d 100644
--- a/ARMeilleure/Instructions/InstEmitFlowHelper.cs
+++ b/ARMeilleure/Instructions/InstEmitFlowHelper.cs
@@ -163,17 +163,18 @@ namespace ARMeilleure.Instructions
 
                 context.LoadFromContext();
 
-                // Note: The return value of a translated function is always an Int64 with the
-                // address execution has returned to. We expect this address to be immediately after the
-                // current instruction, if it isn't we keep returning until we reach the dispatcher.
+                // Note: The return value of a translated function is always an Int64 with the address execution has
+                // returned to. We expect this address to be immediately after the current instruction, if it isn't we
+                // keep returning until we reach the dispatcher.
                 Operand nextAddr = Const((long)op.Address + op.OpCodeSizeInBytes);
 
                 // Try to continue within this block.
-                // If the return address isn't to our next instruction, we need to return so the JIT can figure out what to do.
+                // If the return address isn't to our next instruction, we need to return so the JIT can figure out
+                // what to do.
                 Operand lblContinue = context.GetLabel(nextAddr.Value);
 
                 // We need to clear out the call flag for the return address before comparing it.
-                context.BranchIfTrue(lblContinue, context.ICompareEqual(context.BitwiseAnd(returnAddress, Const(~CallFlag)), nextAddr));
+                context.BranchIf(lblContinue, context.BitwiseAnd(returnAddress, Const(~CallFlag)), nextAddr, Comparison.Equal);
 
                 context.Return(returnAddress);
             }
diff --git a/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs
index a22cd235fc..5b890dd395 100644
--- a/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs
+++ b/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs
@@ -92,7 +92,7 @@ namespace ARMeilleure.Instructions
                 Operand exAddr = context.Load(address.Type, exAddrPtr);
 
                 // STEP 1: Check if we have exclusive access to this memory region. If not, fail and skip store.
-                Operand maskedAddress = context.BitwiseAnd(address, Const(GetExclusiveAddressMask()));
+                Operand maskedAddress = context.BitwiseAnd(address, Const(address.Type, GetExclusiveAddressMask()));
 
                 Operand exFailed = context.ICompareNotEqual(exAddr, maskedAddress);
 
diff --git a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
index 1fe82b62ce..9b6476ddf1 100644
--- a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
+++ b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
@@ -403,7 +403,7 @@ namespace ARMeilleure.Instructions
 
             if (lblSlowPath != null)
             {
-                context.BranchIfTrue(lblSlowPath, context.ICompareLessOrEqual(pte, Const(0L)));
+                context.BranchIf(lblSlowPath, pte, Const(0L), Comparison.LessOrEqual);
             }
             else
             {
@@ -414,7 +414,7 @@ namespace ARMeilleure.Instructions
                     Operand lblNotWatched = Label();
 
                     // Is the page currently being monitored for modifications? If so we need to call MarkRegionAsModified.
-                    context.BranchIfTrue(lblNotWatched, context.ICompareGreaterOrEqual(pte, Const(0L)));
+                    context.BranchIf(lblNotWatched, pte, Const(0L), Comparison.GreaterOrEqual);
 
                     // Mark the region as modified. Size here doesn't matter as address is assumed to be size aligned here.
                     context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.MarkRegionAsModified)), address, Const(1UL));
diff --git a/ARMeilleure/IntermediateRepresentation/Comparison.cs b/ARMeilleure/IntermediateRepresentation/Comparison.cs
new file mode 100644
index 0000000000..628ce1051a
--- /dev/null
+++ b/ARMeilleure/IntermediateRepresentation/Comparison.cs
@@ -0,0 +1,24 @@
+namespace ARMeilleure.IntermediateRepresentation
+{
+    enum Comparison
+    {
+        Equal             = 0,
+        NotEqual          = 1,
+        Greater           = 2,
+        LessOrEqual       = 3,
+        GreaterUI         = 4,
+        LessOrEqualUI     = 5,
+        GreaterOrEqual    = 6,
+        Less              = 7,
+        GreaterOrEqualUI  = 8,
+        LessUI            = 9
+    }
+
+    static class ComparisonExtensions
+    {
+        public static Comparison Invert(this Comparison comp)
+        {
+            return (Comparison)((int)comp ^ 1);
+        }
+    }
+}
diff --git a/ARMeilleure/IntermediateRepresentation/Instruction.cs b/ARMeilleure/IntermediateRepresentation/Instruction.cs
index 8ffaf3dc91..c583a2f2b2 100644
--- a/ARMeilleure/IntermediateRepresentation/Instruction.cs
+++ b/ARMeilleure/IntermediateRepresentation/Instruction.cs
@@ -8,23 +8,13 @@ namespace ARMeilleure.IntermediateRepresentation
         BitwiseNot,
         BitwiseOr,
         Branch,
-        BranchIfFalse,
-        BranchIfTrue,
+        BranchIf,
         ByteSwap,
         Call,
+        Compare,
         CompareAndSwap,
         CompareAndSwap16,
         CompareAndSwap8,
-        CompareEqual,
-        CompareGreater,
-        CompareGreaterOrEqual,
-        CompareGreaterOrEqualUI,
-        CompareGreaterUI,
-        CompareLess,
-        CompareLessOrEqual,
-        CompareLessOrEqualUI,
-        CompareLessUI,
-        CompareNotEqual,
         ConditionalSelect,
         ConvertI64ToI32,
         ConvertToFP,
diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs
index 7abab9e144..a6cc55dfb9 100644
--- a/ARMeilleure/Translation/EmitterContext.cs
+++ b/ARMeilleure/Translation/EmitterContext.cs
@@ -62,18 +62,21 @@ namespace ARMeilleure.Translation
             BranchToLabel(label);
         }
 
-        public void BranchIfFalse(Operand label, Operand op1)
+        public void BranchIf(Operand label, Operand op1, Operand op2, Comparison comp)
         {
-            Add(Instruction.BranchIfFalse, null, op1);
+            Add(Instruction.BranchIf, null, op1, op2, Const((int)comp));
 
             BranchToLabel(label);
         }
 
+        public void BranchIfFalse(Operand label, Operand op1)
+        {
+            BranchIf(label, op1, Const(op1.Type, 0), Comparison.Equal);
+        }
+
         public void BranchIfTrue(Operand label, Operand op1)
         {
-            Add(Instruction.BranchIfTrue, null, op1);
-
-            BranchToLabel(label);
+            BranchIf(label, op1, Const(op1.Type, 0), Comparison.NotEqual);
         }
 
         public Operand ByteSwap(Operand op1)
@@ -243,54 +246,59 @@ namespace ARMeilleure.Translation
             return Add(Instruction.DivideUI, Local(op1.Type), op1, op2);
         }
 
+        public Operand ICompare(Operand op1, Operand op2, Comparison comp)
+        {
+            return Add(Instruction.Compare, Local(OperandType.I32), op1, op2, Const((int)comp));
+        }
+
         public Operand ICompareEqual(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareEqual, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.Equal);
         }
 
         public Operand ICompareGreater(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareGreater, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.Greater);
         }
 
         public Operand ICompareGreaterOrEqual(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareGreaterOrEqual, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.GreaterOrEqual);
         }
 
         public Operand ICompareGreaterOrEqualUI(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareGreaterOrEqualUI, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.GreaterOrEqualUI);
         }
 
         public Operand ICompareGreaterUI(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareGreaterUI, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.GreaterUI);
         }
 
         public Operand ICompareLess(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareLess, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.Less);
         }
 
         public Operand ICompareLessOrEqual(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareLessOrEqual, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.LessOrEqual);
         }
 
         public Operand ICompareLessOrEqualUI(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareLessOrEqualUI, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.LessOrEqualUI);
         }
 
         public Operand ICompareLessUI(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareLessUI, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.LessUI);
         }
 
         public Operand ICompareNotEqual(Operand op1, Operand op2)
         {
-            return Add(Instruction.CompareNotEqual, Local(OperandType.I32), op1, op2);
+            return ICompare(op1, op2, Comparison.NotEqual);
         }
 
         public Operand Load(OperandType type, Operand address)
diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs
index dfb9fe91eb..257af72201 100644
--- a/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/ARMeilleure/Translation/PTC/Ptc.cs
@@ -20,7 +20,7 @@ namespace ARMeilleure.Translation.PTC
     {
         private const string HeaderMagic = "PTChd";
 
-        private const int InternalVersion = 18; //! To be incremented manually for each change to the ARMeilleure project.
+        private const int InternalVersion = 19; //! To be incremented manually for each change to the ARMeilleure project.
 
         private const string BaseDir = "Ryujinx";