Browse Source

Adjust comp.unsigned(ldlen array > ldc.i4 0) transforms to explicit i4->i conversions.

pull/728/head
Daniel Grunwald 9 years ago
parent
commit
e1930e9170
  1. 2
      ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs
  2. 7
      ICSharpCode.Decompiler/IL/Instructions/Conv.cs
  3. 6
      ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs
  4. 9
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  5. 2
      ICSharpCode.Decompiler/Tests/RoundtripAssembly.cs

2
ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs

@ -174,7 +174,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -174,7 +174,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
Block notNullAndNotEmptyBlock;
return block.Instructions.Count == 2
&& block.Instructions[0].MatchIfInstruction(out condition, out trueInst)
&& condition.UnwrapConv().MatchLdLen(StackType.I, out array)
&& condition.UnwrapConv(ConversionKind.Truncate).MatchLdLen(StackType.I, out array)
&& array.MatchLdLoc(v)
&& trueInst.MatchBranch(out notNullAndNotEmptyBlock)
&& notNullAndNotEmptyBlock.Parent == block.Parent

7
ICSharpCode.Decompiler/IL/Instructions/Conv.cs

@ -241,9 +241,12 @@ namespace ICSharpCode.Decompiler.IL @@ -241,9 +241,12 @@ namespace ICSharpCode.Decompiler.IL
return flags;
}
public override ILInstruction UnwrapConv()
public override ILInstruction UnwrapConv(ConversionKind kind)
{
return Argument.UnwrapConv();
if (this.Kind == kind)
return Argument.UnwrapConv(kind);
else
return this;
}
}
}

6
ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs

@ -154,7 +154,11 @@ namespace ICSharpCode.Decompiler.IL @@ -154,7 +154,11 @@ namespace ICSharpCode.Decompiler.IL
return false;
}
public virtual ILInstruction UnwrapConv()
/// <summary>
/// If this instruction is a conversion of the specified kind, return its argument.
/// Otherwise, return the instruction itself.
/// </summary>
public virtual ILInstruction UnwrapConv(ConversionKind kind)
{
return this;
}

9
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -63,16 +63,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -63,16 +63,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms
inst.Kind = ComparisonKind.Equality;
}
if (inst.Right.MatchLdcI4(0) && inst.Sign == Sign.Unsigned
&& (inst.Kind == ComparisonKind.GreaterThan || inst.Kind == ComparisonKind.LessThan))
var rightWithoutConv = inst.Right.UnwrapConv(ConversionKind.SignExtend).UnwrapConv(ConversionKind.ZeroExtend);
if (rightWithoutConv.MatchLdcI4(0)
&& inst.Sign == Sign.Unsigned
&& (inst.Kind == ComparisonKind.GreaterThan || inst.Kind == ComparisonKind.LessThanOrEqual))
{
ILInstruction array;
if (inst.Left.MatchLdLen(StackType.I, out array)) {
// comp.unsigned(ldlen array > ldc.i4 0)
// comp.unsigned(ldlen array > conv i4->i(ldc.i4 0))
// => comp(ldlen.i4 array > ldc.i4 0)
// This is a special case where the C# compiler doesn't generate conv.i4 after ldlen.
inst.Left.ReplaceWith(new LdLen(StackType.I4, array) { ILRange = inst.Left.ILRange });
inst.InputType = StackType.I4;
inst.Right = rightWithoutConv;
}
// comp.unsigned(left > ldc.i4 0) => comp(left != ldc.i4 0)
// comp.unsigned(left <= ldc.i4 0) => comp(left == ldc.i4 0)

2
ICSharpCode.Decompiler/Tests/RoundtripAssembly.cs

@ -86,7 +86,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -86,7 +86,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void Random_Tests_TestCases()
public void Random_TestCase_1()
{
try {
RunWithOutput("Random Tests\\TestCases", "TestCase-1.exe");

Loading…
Cancel
Save