Skip to content

Commit

Permalink
Fix propagation optimization bug (#1023)
Browse files Browse the repository at this point in the history
* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - WIP

* - Fixed x86 virtual register propagation bug

* - Fixed x86 virtual register propagation bug

* - Fixed x86 optimization bug with 64bit subtraction
  • Loading branch information
tgiphil committed Feb 21, 2023
1 parent 8840278 commit 7ec3412
Show file tree
Hide file tree
Showing 84 changed files with 3,080 additions and 537 deletions.
3 changes: 3 additions & 0 deletions Demos/Run-Demo.TestWorld.x86-test.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cd %~dp0
cd ..\bin
Mosa.Tool.Launcher.exe -autostart -o1 -inline-explicit -inline-level 15 -output-asm -output-debug -threading-off -output-hash Mosa.Demo.TestWorld.x86.dll
36 changes: 36 additions & 0 deletions Source/Data/IR-Instructions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1493,11 +1493,47 @@
"ResultCount": 1,
"OperandCount": 1
},
{
"Name": "ThrowOverflow",
"FamilyName": "IR",
"ResultCount": 0,
"OperandCount": 0
},
{
"Name": "ThrowIndexOutOfRange",
"FamilyName": "IR",
"ResultCount": 0,
"OperandCount": 0
},
{
"Name": "ThrowDivideByZero",
"FamilyName": "IR",
"ResultCount": 0,
"OperandCount": 0
},
{
"Name": "CheckArrayBounds",
"FamilyName": "IR",
"ResultCount": 2,
"OperandCount": 0
},
{
"Name": "CheckThrowOverflow",
"FamilyName": "IR",
"ResultCount": 0,
"OperandCount": 1
},
{
"Name": "CheckThrowIndexOutOfRange",
"FamilyName": "IR",
"ResultCount": 0,
"OperandCount": 1
},
{
"Name": "CheckThrowDivideByZero",
"FamilyName": "IR",
"ResultCount": 0,
"OperandCount": 1
}
]
}
52 changes: 42 additions & 10 deletions Source/Mosa.Compiler.Common/IntegerTwiddling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ namespace Mosa.Compiler.Common;

public static class IntegerTwiddling
{
public static bool IsAddOverflow(ulong a, ulong b)
public static bool IsAddUnsignedCarry(ulong a, ulong b)
{
return (b > 0) && (a > (ulong.MaxValue - b));
}

public static bool IsAddOverflow(uint a, uint b)
public static bool IsAddUnsignedCarry(uint a, uint b)
{
return (b > 0) && (a > (uint.MaxValue - b));
}

public static bool IsAddOverflow(int a, int b)
public static bool IsAddSignedOverflow(int a, int b)
{
if (a > 0 && b > 0)
if (b > (int.MaxValue - a))
Expand All @@ -27,7 +27,7 @@ public static bool IsAddOverflow(int a, int b)
return false;
}

public static bool IsAddOverflow(long a, long b)
public static bool IsAddSignedOverflow(long a, long b)
{
if (a > 0 && b > 0)
if (b > (long.MaxValue - a))
Expand All @@ -40,9 +40,9 @@ public static bool IsAddOverflow(long a, long b)
return false;
}

public static bool IsAddOverflow(uint a, uint b, bool carry)
public static bool IsAddUnsignedCarry(uint a, uint b, bool carry)
{
if (IsAddOverflow(a, b))
if (IsAddUnsignedCarry(a, b))
return true;

if (carry & (a + b) == uint.MaxValue)
Expand All @@ -51,28 +51,60 @@ public static bool IsAddOverflow(uint a, uint b, bool carry)
return false;
}

public static bool IsMultiplyOverflow(uint a, uint b)
public static bool IsSubSignedOverflow(int a, int b)
{
if ((b < 0) && (a < int.MinValue - b))
return true;

if ((b > 0) && (a > int.MaxValue - b))
return true;

return false;
}

public static bool IsSubSignedOverflow(long a, long b)
{
if ((b < 0) && (a < long.MinValue - b))
return true;

if ((b > 0) && (a > long.MaxValue - b))
return true;

return false;
}

public static bool IsSubUnsignedCarry(uint a, uint b)
{
return b > a;
}

public static bool IsSubUnsignedCarry(ulong a, ulong b)
{
return b > a;
}

public static bool IsMultiplyUnsignedCarry(uint a, uint b)
{
var r = a * (ulong)b;

return r > uint.MaxValue;
}

public static bool IsMultiplyOverflow(int a, int b)
public static bool IsMultiplySignedOverflow(int a, int b)
{
var z = a * b;
return (b < 0 && a == int.MinValue) | (b != 0 && z / b != a);
}

public static bool IsMultiplyOverflow(ulong a, ulong b)
public static bool IsMultiplyUnsignedCarry(ulong a, ulong b)
{
if (a == 0 | b == 0)
return false;

return ulong.MaxValue / a < b;
}

public static bool IsMultiplyOverflow(long a, long b)
public static bool IsMultiplySignedOverflow(long a, long b)
{
var z = a * b;
return (b < 0 && a == long.MinValue) | (b != 0 && z / b != a);
Expand Down
25 changes: 17 additions & 8 deletions Source/Mosa.Compiler.Framework.xUnit/IntegerTwiddlingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,27 @@ namespace Mosa.Compiler.Framework.xUnit;
public class IntegerTwiddlingTests
{
[Fact]
public void SignedIntegerOverflow()
public void IsAddSignedOverflow()
{
Debug.Assert(IntegerTwiddling.IsAddOverflow(2147483640, 10));
Debug.Assert(!IntegerTwiddling.IsAddOverflow(0, 0));
Debug.Assert(IntegerTwiddling.IsAddSignedOverflow(2147483640, 10));
Debug.Assert(!IntegerTwiddling.IsAddSignedOverflow(0, 0));
}

[Fact]
public void UnsignedIntegerOverflow()
public void IsAddUnsignedCarry()
{
Debug.Assert(IntegerTwiddling.IsAddOverflow(ulong.MaxValue, 1ul));
Debug.Assert(!IntegerTwiddling.IsAddOverflow(ulong.MaxValue, 0ul));
Debug.Assert(!IntegerTwiddling.IsAddOverflow(0ul, 0ul));
Debug.Assert(!IntegerTwiddling.IsAddOverflow(0ul, ulong.MaxValue));
Debug.Assert(IntegerTwiddling.IsAddUnsignedCarry(ulong.MaxValue, 1ul));
Debug.Assert(!IntegerTwiddling.IsAddUnsignedCarry(ulong.MaxValue, 0ul));
Debug.Assert(!IntegerTwiddling.IsAddUnsignedCarry(0ul, 0ul));
Debug.Assert(!IntegerTwiddling.IsAddUnsignedCarry(0ul, ulong.MaxValue));
}

[Fact]
public void IsSubUnsignedCarry()
{
Debug.Assert(!IntegerTwiddling.IsSubUnsignedCarry(ulong.MaxValue, 1ul));
Debug.Assert(!IntegerTwiddling.IsSubUnsignedCarry(ulong.MaxValue, 0ul));
Debug.Assert(!IntegerTwiddling.IsSubUnsignedCarry(0ul, 0ul));
Debug.Assert(IntegerTwiddling.IsSubUnsignedCarry(0ul, ulong.MaxValue));
}
}
2 changes: 1 addition & 1 deletion Source/Mosa.Compiler.Framework/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private static List<BaseMethodCompilerStage> GetDefaultMethodPipeline(CompilerSe
compilerSettings.Devirtualization ? new DevirtualizeCallStage() : null,
new PlugStage(),
new RuntimeCallStage(),
new ArrayStage(),
new IRStage(),
(compilerSettings.InlineMethods || compilerSettings.InlineExplicit) ? new InlineStage() : null,
new PromoteTemporaryVariables(),
new StaticLoadOptimizationStage(),
Expand Down
17 changes: 17 additions & 0 deletions Source/Mosa.Compiler.Framework/IR/CheckThrowDivideByZero.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

// This code was generated by an automated template.

namespace Mosa.Compiler.Framework.IR;

/// <summary>
/// CheckThrowDivideByZero
/// </summary>
/// <seealso cref="Mosa.Compiler.Framework.IR.BaseIRInstruction" />
public sealed class CheckThrowDivideByZero : BaseIRInstruction
{
public CheckThrowDivideByZero()
: base(1, 0)
{
}
}
17 changes: 17 additions & 0 deletions Source/Mosa.Compiler.Framework/IR/CheckThrowIndexOutOfRange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

// This code was generated by an automated template.

namespace Mosa.Compiler.Framework.IR;

/// <summary>
/// CheckThrowIndexOutOfRange
/// </summary>
/// <seealso cref="Mosa.Compiler.Framework.IR.BaseIRInstruction" />
public sealed class CheckThrowIndexOutOfRange : BaseIRInstruction
{
public CheckThrowIndexOutOfRange()
: base(1, 0)
{
}
}
17 changes: 17 additions & 0 deletions Source/Mosa.Compiler.Framework/IR/CheckThrowOverflow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

// This code was generated by an automated template.

namespace Mosa.Compiler.Framework.IR;

/// <summary>
/// CheckThrowOverflow
/// </summary>
/// <seealso cref="Mosa.Compiler.Framework.IR.BaseIRInstruction" />
public sealed class CheckThrowOverflow : BaseIRInstruction
{
public CheckThrowOverflow()
: base(1, 0)
{
}
}
17 changes: 17 additions & 0 deletions Source/Mosa.Compiler.Framework/IR/ThrowDivideByZero.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

// This code was generated by an automated template.

namespace Mosa.Compiler.Framework.IR;

/// <summary>
/// ThrowDivideByZero
/// </summary>
/// <seealso cref="Mosa.Compiler.Framework.IR.BaseIRInstruction" />
public sealed class ThrowDivideByZero : BaseIRInstruction
{
public ThrowDivideByZero()
: base(0, 0)
{
}
}
17 changes: 17 additions & 0 deletions Source/Mosa.Compiler.Framework/IR/ThrowIndexOutOfRange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

// This code was generated by an automated template.

namespace Mosa.Compiler.Framework.IR;

/// <summary>
/// ThrowIndexOutOfRange
/// </summary>
/// <seealso cref="Mosa.Compiler.Framework.IR.BaseIRInstruction" />
public sealed class ThrowIndexOutOfRange : BaseIRInstruction
{
public ThrowIndexOutOfRange()
: base(0, 0)
{
}
}
17 changes: 17 additions & 0 deletions Source/Mosa.Compiler.Framework/IR/ThrowOverflow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

// This code was generated by an automated template.

namespace Mosa.Compiler.Framework.IR;

/// <summary>
/// ThrowOverflow
/// </summary>
/// <seealso cref="Mosa.Compiler.Framework.IR.BaseIRInstruction" />
public sealed class ThrowOverflow : BaseIRInstruction
{
public ThrowOverflow()
: base(0, 0)
{
}
}
6 changes: 6 additions & 0 deletions Source/Mosa.Compiler.Framework/IRInstruction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,11 @@ public static class IRInstruction
public static readonly BitCopyR8To64 BitCopyR8To64 = new BitCopyR8To64();
public static readonly BitCopy32ToR4 BitCopy32ToR4 = new BitCopy32ToR4();
public static readonly BitCopy64ToR8 BitCopy64ToR8 = new BitCopy64ToR8();
public static readonly ThrowOverflow ThrowOverflow = new ThrowOverflow();
public static readonly ThrowIndexOutOfRange ThrowIndexOutOfRange = new ThrowIndexOutOfRange();
public static readonly ThrowDivideByZero ThrowDivideByZero = new ThrowDivideByZero();
public static readonly CheckArrayBounds CheckArrayBounds = new CheckArrayBounds();
public static readonly CheckThrowOverflow CheckThrowOverflow = new CheckThrowOverflow();
public static readonly CheckThrowIndexOutOfRange CheckThrowIndexOutOfRange = new CheckThrowIndexOutOfRange();
public static readonly CheckThrowDivideByZero CheckThrowDivideByZero = new CheckThrowDivideByZero();
}
6 changes: 6 additions & 0 deletions Source/Mosa.Compiler.Framework/IRInstructions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,12 @@ public static class IRInstructions
IRInstruction.BitCopyR8To64,
IRInstruction.BitCopy32ToR4,
IRInstruction.BitCopy64ToR8,
IRInstruction.ThrowOverflow,
IRInstruction.ThrowIndexOutOfRange,
IRInstruction.ThrowDivideByZero,
IRInstruction.CheckArrayBounds,
IRInstruction.CheckThrowOverflow,
IRInstruction.CheckThrowIndexOutOfRange,
IRInstruction.CheckThrowDivideByZero,
};
}

0 comments on commit 7ec3412

Please sign in to comment.