diff --git a/Source/Data/IR-Optimizations-BitValue.json b/Source/Data/IR-Optimizations-BitValue.json
index 7669828254..772f4918f6 100644
--- a/Source/Data/IR-Optimizations-BitValue.json
+++ b/Source/Data/IR-Optimizations-BitValue.json
@@ -64,6 +64,46 @@
"Priority": "20",
"Variations": "No",
"Log": "No"
+ },
+ {
+ "Type": "BitValue",
+ "Name": "Compare##x32SignedLess",
+ "SubName": "SignedLessAdd##",
+ "Expression": "IR.Compare##x32 {<} (IR.Add## a c1) c2",
+ "Filter": "IsResolvedConstant(c1) && IsResolvedConstant(c2) && !IsAddOverflow##(BitValueMax##(a), BitValueMax##(c1))",
+ "Result": "(IR.Compare##x32 {<} a (IR.Sub## c2 c1))",
+ "Variations": "No",
+ "Log": "Yes"
+ },
+ {
+ "Type": "BitValue",
+ "Name": "Compare##x64SignedLess",
+ "SubName": "Add##",
+ "Expression": "IR.Compare##x64 {<} (IR.Add## a c1) c2",
+ "Filter": "IsResolvedConstant(c1) && IsResolvedConstant(c2) && !IsAddOverflow##(BitValueMax##(a), BitValueMax##(c1))",
+ "Result": "(IR.Compare##x64 {<} a (IR.Sub## c2 c1))",
+ "Variations": "No",
+ "Log": "Yes"
+ },
+ {
+ "Type": "BitValue",
+ "Name": "Compare##x32UnsignedLess",
+ "SubName": "Add##",
+ "Expression": "IR.Compare##x32 {< u} (IR.Add## a c1) c2",
+ "Filter": "IsResolvedConstant(c1) && IsResolvedConstant(c2) && !IsAddOverflow##(BitValueMax##(a), BitValueMax##(c1))",
+ "Result": "(IR.Compare##x32 {<} a (IR.Sub## c2 c1))",
+ "Variations": "No",
+ "Log": "Yes"
+ },
+ {
+ "Type": "BitValue",
+ "Name": "Compare##x64UnsignedLess",
+ "SubName": "Add##",
+ "Expression": "IR.Compare##x64 {< u} (IR.Add## a c1) c2",
+ "Filter": "IsResolvedConstant(c1) && IsResolvedConstant(c2) && !IsAddOverflow##(BitValueMax##(a), BitValueMax##(c1))",
+ "Result": "(IR.Compare##x64 {<} a (IR.Sub## c2 c1))",
+ "Variations": "No",
+ "Log": "Yes"
}
]
}
diff --git a/Source/Mosa.Compiler.Framework/BaseTransform.cs b/Source/Mosa.Compiler.Framework/BaseTransform.cs
index 9ca6ca1290..58a8f6b01b 100644
--- a/Source/Mosa.Compiler.Framework/BaseTransform.cs
+++ b/Source/Mosa.Compiler.Framework/BaseTransform.cs
@@ -1,5 +1,6 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.
+using System.Diagnostics;
using Mosa.Compiler.Common;
using Mosa.Compiler.Common.Exceptions;
@@ -716,6 +717,36 @@ protected static uint UseCount(Operand operand)
return (uint)operand.Uses.Count;
}
+ protected static bool IsAddSignedOverflow32(int a, int b)
+ {
+ return IntegerTwiddling.IsAddSignedOverflow(a, b);
+ }
+
+ protected static bool IsAddSignedOverflow64(long a, long b)
+ {
+ return IntegerTwiddling.IsAddSignedOverflow(a, b);
+ }
+
+ protected static bool IsAddUnsignedOverflow32(uint a, uint b)
+ {
+ return IntegerTwiddling.IsAddUnsignedCarry(a, b);
+ }
+
+ protected static bool IsAddUnsignedOverflow64(ulong a, ulong b)
+ {
+ return IntegerTwiddling.IsAddUnsignedCarry(a, b);
+ }
+
+ protected static bool IsAddOverflow32(ulong a, ulong b)
+ {
+ return IsAddSignedOverflow32((int)a, (int)b) || IsAddUnsignedOverflow32((uint)a, (uint)b);
+ }
+
+ protected static bool IsAddOverflow64(ulong a, ulong b)
+ {
+ return IsAddSignedOverflow64((long)a, (long)b) || IsAddUnsignedOverflow64(a, b);
+ }
+
#endregion Expression Methods
#region SignExtend Helpers
@@ -850,14 +881,34 @@ public static TriState AreStatusFlagsUsed(Node node, bool checkZero, bool checkC
#region BitTracker Helpers
- protected static bool IsBitValueSignBitCleared32(Operand operand1)
+ protected static uint BitValueMax32(Operand operand)
+ {
+ return (uint)operand.BitValue.MaxValue;
+ }
+
+ protected static ulong BitValueMax64(Operand operand)
+ {
+ return (ulong)operand.BitValue.MaxValue;
+ }
+
+ protected static uint BitValueMin32(Operand operand)
+ {
+ return (uint)operand.BitValue.MinValue;
+ }
+
+ protected static ulong BitValueMin64(Operand operand)
+ {
+ return (ulong)operand.BitValue.MinValue;
+ }
+
+ protected static bool IsBitValueSignBitCleared32(Operand operand)
{
- return operand1.BitValue.IsSignBitClear32;
+ return operand.BitValue.IsSignBitClear32;
}
- protected static bool IsBitValueSignBitCleared64(Operand operand1)
+ protected static bool IsBitValueSignBitCleared64(Operand operand)
{
- return operand1.BitValue.IsSignBitClear64;
+ return operand.BitValue.IsSignBitClear64;
}
protected static bool? EvaluateCompare(Operand operand1, Operand operand2, ConditionCode condition)
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs
index f66771ed80..1eda2b2664 100644
--- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs
@@ -924,5 +924,13 @@ public static class AutoTransforms
new BitValue.RemSigned64NotSigned(),
new BitValue.ArithShiftRight32NotSigned(),
new BitValue.ArithShiftRight64NotSigned(),
+ new BitValue.Compare32x32SignedLessSignedLessAdd32(),
+ new BitValue.Compare64x32SignedLessSignedLessAdd64(),
+ new BitValue.Compare32x64SignedLessAdd32(),
+ new BitValue.Compare64x64SignedLessAdd64(),
+ new BitValue.Compare32x32UnsignedLessAdd32(),
+ new BitValue.Compare64x32UnsignedLessAdd64(),
+ new BitValue.Compare32x64UnsignedLessAdd32(),
+ new BitValue.Compare64x64UnsignedLessAdd64(),
};
}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x32SignedLessSignedLessAdd32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x32SignedLessSignedLessAdd32.cs
new file mode 100644
index 0000000000..d928b74fdc
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x32SignedLessSignedLessAdd32.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare32x32SignedLessSignedLessAdd32
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare32x32SignedLessSignedLessAdd32 : BaseTransform
+{
+ public Compare32x32SignedLessSignedLessAdd32() : base(IRInstruction.Compare32x32, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.Less)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add32)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow32(BitValueMax32(context.Operand1.Definitions[0].Operand1), BitValueMax32(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate32();
+
+ context.SetInstruction(IRInstruction.Sub32, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare32x32, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x32UnsignedLessAdd32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x32UnsignedLessAdd32.cs
new file mode 100644
index 0000000000..119f9382ca
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x32UnsignedLessAdd32.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare32x32UnsignedLessAdd32
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare32x32UnsignedLessAdd32 : BaseTransform
+{
+ public Compare32x32UnsignedLessAdd32() : base(IRInstruction.Compare32x32, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.UnsignedLess)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add32)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow32(BitValueMax32(context.Operand1.Definitions[0].Operand1), BitValueMax32(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate32();
+
+ context.SetInstruction(IRInstruction.Sub32, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare32x32, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x64SignedLessAdd32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x64SignedLessAdd32.cs
new file mode 100644
index 0000000000..bebe2879dd
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x64SignedLessAdd32.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare32x64SignedLessAdd32
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare32x64SignedLessAdd32 : BaseTransform
+{
+ public Compare32x64SignedLessAdd32() : base(IRInstruction.Compare32x64, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.Less)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add32)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow32(BitValueMax32(context.Operand1.Definitions[0].Operand1), BitValueMax32(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate32();
+
+ context.SetInstruction(IRInstruction.Sub32, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare32x64, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x64UnsignedLessAdd32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x64UnsignedLessAdd32.cs
new file mode 100644
index 0000000000..d24ec5f9a9
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare32x64UnsignedLessAdd32.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare32x64UnsignedLessAdd32
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare32x64UnsignedLessAdd32 : BaseTransform
+{
+ public Compare32x64UnsignedLessAdd32() : base(IRInstruction.Compare32x64, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.UnsignedLess)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add32)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow32(BitValueMax32(context.Operand1.Definitions[0].Operand1), BitValueMax32(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate32();
+
+ context.SetInstruction(IRInstruction.Sub32, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare32x64, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x32SignedLessSignedLessAdd64.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x32SignedLessSignedLessAdd64.cs
new file mode 100644
index 0000000000..f356c976c1
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x32SignedLessSignedLessAdd64.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare64x32SignedLessSignedLessAdd64
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare64x32SignedLessSignedLessAdd64 : BaseTransform
+{
+ public Compare64x32SignedLessSignedLessAdd64() : base(IRInstruction.Compare64x32, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.Less)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add64)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow64(BitValueMax64(context.Operand1.Definitions[0].Operand1), BitValueMax64(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate64();
+
+ context.SetInstruction(IRInstruction.Sub64, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare64x32, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x32UnsignedLessAdd64.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x32UnsignedLessAdd64.cs
new file mode 100644
index 0000000000..48d0cd2f88
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x32UnsignedLessAdd64.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare64x32UnsignedLessAdd64
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare64x32UnsignedLessAdd64 : BaseTransform
+{
+ public Compare64x32UnsignedLessAdd64() : base(IRInstruction.Compare64x32, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.UnsignedLess)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add64)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow64(BitValueMax64(context.Operand1.Definitions[0].Operand1), BitValueMax64(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate64();
+
+ context.SetInstruction(IRInstruction.Sub64, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare64x32, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x64SignedLessAdd64.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x64SignedLessAdd64.cs
new file mode 100644
index 0000000000..8ae7ce046d
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x64SignedLessAdd64.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare64x64SignedLessAdd64
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare64x64SignedLessAdd64 : BaseTransform
+{
+ public Compare64x64SignedLessAdd64() : base(IRInstruction.Compare64x64, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.Less)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add64)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow64(BitValueMax64(context.Operand1.Definitions[0].Operand1), BitValueMax64(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate64();
+
+ context.SetInstruction(IRInstruction.Sub64, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare64x64, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x64UnsignedLessAdd64.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x64UnsignedLessAdd64.cs
new file mode 100644
index 0000000000..4b4323f5f8
--- /dev/null
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/BitValue/Compare64x64UnsignedLessAdd64.cs
@@ -0,0 +1,56 @@
+// Copyright (c) MOSA Project. Licensed under the New BSD License.
+
+// This code was generated by an automated template.
+
+namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.BitValue;
+
+///
+/// Compare64x64UnsignedLessAdd64
+///
+[Transform("IR.Optimizations.Auto.BitValue")]
+public sealed class Compare64x64UnsignedLessAdd64 : BaseTransform
+{
+ public Compare64x64UnsignedLessAdd64() : base(IRInstruction.Compare64x64, TransformType.Auto | TransformType.Optimization, true)
+ {
+ }
+
+ public override bool Match(Context context, Transform transform)
+ {
+ if (context.ConditionCode != ConditionCode.UnsignedLess)
+ return false;
+
+ if (!context.Operand1.IsVirtualRegister)
+ return false;
+
+ if (!context.Operand1.IsDefinedOnce)
+ return false;
+
+ if (context.Operand1.Definitions[0].Instruction != IRInstruction.Add64)
+ return false;
+
+ if (!IsResolvedConstant(context.Operand1.Definitions[0].Operand2))
+ return false;
+
+ if (!IsResolvedConstant(context.Operand2))
+ return false;
+
+ if (IsAddOverflow64(BitValueMax64(context.Operand1.Definitions[0].Operand1), BitValueMax64(context.Operand1.Definitions[0].Operand2)))
+ return false;
+
+ return true;
+ }
+
+ public override void Transform(Context context, Transform transform)
+ {
+ var result = context.Result;
+
+ var t1 = context.Operand1.Definitions[0].Operand1;
+ var t2 = context.Operand1.Definitions[0].Operand2;
+ var t3 = context.Operand2;
+
+ var v1 = transform.VirtualRegisters.Allocate64();
+
+ context.SetInstruction(IRInstruction.Sub64, v1, t3, t2);
+ context.AppendInstruction(IRInstruction.Compare64x64, ConditionCode.Less, result, t1, v1);
+ }
+}
diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/ManualTransforms.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/ManualTransforms.cs
index c028f9d5f5..e8668c6d07 100644
--- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/ManualTransforms.cs
+++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/ManualTransforms.cs
@@ -319,5 +319,7 @@ public static class ManualTransforms
new BitValue.Branch64(),
new BitValue.BranchManagedPointer(),
new BitValue.BranchObject(),
- };
+
+ //new BitValue.Compare32x32Add32Rewrite()
+};
}
diff --git a/Source/Mosa.UnitTests/Optimization/SpecificTests.cs b/Source/Mosa.UnitTests/Optimization/SpecificTests.cs
index 44cc6074ca..9e9a40e790 100644
--- a/Source/Mosa.UnitTests/Optimization/SpecificTests.cs
+++ b/Source/Mosa.UnitTests/Optimization/SpecificTests.cs
@@ -165,4 +165,44 @@ public static long Or64And64And64ByI4(long x, long y)
[MosaUnitTest(Series = "I8")]
public static long ShiftRightI8By64(long x) => x >> 64;
+
+ [MosaUnitTest(Series = "U4")]
+ public static bool CompareAddU4(uint v)
+ {
+ var a = v & 0xFFFF;
+ var c1 = 10;
+ var v2 = 100;
+
+ return a + c1 < v2;
+ }
+
+ [MosaUnitTest(Series = "I4")]
+ public static bool CompareAddI4(int v)
+ {
+ var a = v & 0xFFFF;
+ var c1 = 10;
+ var v2 = 100;
+
+ return a + c1 < v2;
+ }
+
+ [MosaUnitTest(Series = "U8")]
+ public static bool CompareAddU8(ulong v)
+ {
+ var a = v & 0xFFFF;
+ var c1 = 10ul;
+ var v2 = 100ul;
+
+ return a + c1 < v2;
+ }
+
+ [MosaUnitTest(Series = "I8")]
+ public static bool CompareAddU8(long v)
+ {
+ var a = v & 0xFFFF;
+ var c1 = 10l;
+ var v2 = 100l;
+
+ return a + c1 < v2;
+ }
}
diff --git a/Source/Mosa.sln b/Source/Mosa.sln
index 4aae18fc17..2e913ea110 100644
--- a/Source/Mosa.sln
+++ b/Source/Mosa.sln
@@ -132,7 +132,6 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Transforms", "Transforms", "{F84EFA2E-4B38-410F-A7DE-385DB71BB37F}"
ProjectSection(SolutionItems) = preProject
Data\IR-Optimizations-Algebraic.json = Data\IR-Optimizations-Algebraic.json
- Data\IR-Optimizations-BitTracker.json = Data\IR-Optimizations-BitTracker.json
Data\IR-Optimizations-BitValue.json = Data\IR-Optimizations-BitValue.json
Data\IR-Optimizations-ConstantFolding-Expression.json = Data\IR-Optimizations-ConstantFolding-Expression.json
Data\IR-Optimizations-ConstantFolding-MemoryAccess.json = Data\IR-Optimizations-ConstantFolding-MemoryAccess.json