Skip to content

Commit

Permalink
Fix #2166: Unnecessary uint casts/conversions for certain bitwise ope…
Browse files Browse the repository at this point in the history
…rations
  • Loading branch information
siegfriedpammer committed Oct 19, 2024
1 parent ac0ef8a commit 8c440f4
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public class Program
{
public static long fnWorks(int x, int y)
{
return (long)(((ulong)y & 0xFFFFFFuL) << 24) | ((long)x & 0xFFFFFFL);
return (long)((((ulong)y & 0xFFFFFFuL) << 24) | ((ulong)x & 0xFFFFFFuL));
}

public static long fnFails(int x, int y)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2943,8 +2943,8 @@ public static void UintRightShiftTest(uint p, CustomClass c, CustomStruct2 s)
public static void UintBitAndTest(uint p, CustomClass c, CustomStruct2 s)
{
uint num = 0u;
p &= 5u;
num &= 5u;
p &= 5;
num &= 5;
Use(ref num);
uintField &= 5u;
UintProp &= 5u;
Expand All @@ -2970,8 +2970,8 @@ public static void UintBitAndTest(uint p, CustomClass c, CustomStruct2 s)
public static void UintBitOrTest(uint p, CustomClass c, CustomStruct2 s)
{
uint num = 0u;
p |= 5u;
num |= 5u;
p |= 5;
num |= 5;
Use(ref num);
uintField |= 5u;
UintProp |= 5u;
Expand All @@ -2997,8 +2997,8 @@ public static void UintBitOrTest(uint p, CustomClass c, CustomStruct2 s)
public static void UintBitXorTest(uint p, CustomClass c, CustomStruct2 s)
{
uint num = 0u;
p ^= 5u;
num ^= 5u;
p ^= 5;
num ^= 5;
Use(ref num);
uintField ^= 5u;
UintProp ^= 5u;
Expand Down
68 changes: 41 additions & 27 deletions ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public void BitwiseAndWithConstantUInt64(ulong a)
ExpectUInt64(a & 7);
ExpectUInt64(a & 0x7FFFFFFF);
ExpectUInt64(a & 0xFFFFFFFFu);
ExpectUInt64(a & 0x7FFFFFFFFFFFFFFFuL);
ExpectUInt64(a & 0x7FFFFFFFFFFFFFFFL);
ExpectUInt64(a & 0xFFFFFFFFFFFFFFFFuL);
}

Expand All @@ -97,8 +97,8 @@ public void BitwiseAndWithConstantInt64(long a)

public void BitwiseAndWithConstantUInt32(uint a)
{
ExpectUInt32(a & 7u);
ExpectUInt32(a & 0x7FFFFFFFu);
ExpectUInt32(a & 7);
ExpectUInt32(a & 0x7FFFFFFF);
ExpectUInt32(a & 0xFFFFFFFFu);
}

Expand All @@ -110,9 +110,9 @@ public void BitwiseAndWithConstantInt32(int a)

public void BitwiseAndWithConstantUInt16(ushort a)
{
ExpectUInt16((ushort)(a & 7u));
ExpectUInt16((ushort)(a & 0x7FFFu));
ExpectUInt16((ushort)(a & 0xFFFFu));
ExpectUInt16((ushort)(a & 7));
ExpectUInt16((ushort)(a & 0x7FFF));
ExpectUInt16((ushort)(a & 0xFFFF));
}

public void BitwiseAndWithConstantInt16(short a)
Expand All @@ -123,9 +123,9 @@ public void BitwiseAndWithConstantInt16(short a)

public void BitwiseAndWithConstantUInt8(byte a)
{
ExpectUInt8((byte)(a & 7u));
ExpectUInt8((byte)(a & 0x7Fu));
ExpectUInt8((byte)(a & 0xFFu));
ExpectUInt8((byte)(a & 7));
ExpectUInt8((byte)(a & 0x7F));
ExpectUInt8((byte)(a & 0xFF));
}

public void BitwiseAndWithConstantInt8(sbyte a)
Expand All @@ -139,7 +139,7 @@ public void BitwiseOrWithConstantUInt64(ulong a)
ExpectUInt64(a | 7);
ExpectUInt64(a | 0x7FFFFFFF);
ExpectUInt64(a | 0xFFFFFFFFu);
ExpectUInt64(a | 0x7FFFFFFFFFFFFFFFuL);
ExpectUInt64(a | 0x7FFFFFFFFFFFFFFFL);
ExpectUInt64(a | 0xFFFFFFFFFFFFFFFFuL);
}

Expand All @@ -153,8 +153,8 @@ public void BitwiseOrWithConstantInt64(long a)

public void BitwiseOrWithConstantUInt32(uint a)
{
ExpectUInt32(a | 7u);
ExpectUInt32(a | 0x7FFFFFFFu);
ExpectUInt32(a | 7);
ExpectUInt32(a | 0x7FFFFFFF);
ExpectUInt32(a | 0xFFFFFFFFu);
}

Expand All @@ -166,9 +166,9 @@ public void BitwiseOrWithConstantInt32(int a)

public void BitwiseOrWithConstantUInt16(ushort a)
{
ExpectUInt16((ushort)(a | 7u));
ExpectUInt16((ushort)(a | 0x7FFFu));
ExpectUInt16((ushort)(a | 0xFFFFu));
ExpectUInt16((ushort)(a | 7));
ExpectUInt16((ushort)(a | 0x7FFF));
ExpectUInt16((ushort)(a | 0xFFFF));
}

public void BitwiseOrWithConstantInt16(short a)
Expand All @@ -179,9 +179,9 @@ public void BitwiseOrWithConstantInt16(short a)

public void BitwiseOrWithConstantUInt8(byte a)
{
ExpectUInt8((byte)(a | 7u));
ExpectUInt8((byte)(a | 0x7Fu));
ExpectUInt8((byte)(a | 0xFFu));
ExpectUInt8((byte)(a | 7));
ExpectUInt8((byte)(a | 0x7F));
ExpectUInt8((byte)(a | 0xFF));
}

public void BitwiseOrWithConstantInt8(sbyte a)
Expand All @@ -195,7 +195,7 @@ public void BitwiseXorWithConstantUInt64(ulong a)
ExpectUInt64(a ^ 7);
ExpectUInt64(a ^ 0x7FFFFFFF);
ExpectUInt64(a ^ 0xFFFFFFFFu);
ExpectUInt64(a ^ 0x7FFFFFFFFFFFFFFFuL);
ExpectUInt64(a ^ 0x7FFFFFFFFFFFFFFFL);
ExpectUInt64(a ^ 0xFFFFFFFFFFFFFFFFuL);
}

Expand All @@ -209,8 +209,8 @@ public void BitwiseXorWithConstantInt64(long a)

public void BitwiseXorWithConstantUInt32(uint a)
{
ExpectUInt32(a ^ 7u);
ExpectUInt32(a ^ 0x7FFFFFFFu);
ExpectUInt32(a ^ 7);
ExpectUInt32(a ^ 0x7FFFFFFF);
ExpectUInt32(a ^ 0xFFFFFFFFu);
}

Expand All @@ -222,9 +222,9 @@ public void BitwiseXorWithConstantInt32(int a)

public void BitwiseXorWithConstantUInt16(ushort a)
{
ExpectUInt16((ushort)(a ^ 7u));
ExpectUInt16((ushort)(a ^ 0x7FFFu));
ExpectUInt16((ushort)(a ^ 0xFFFFu));
ExpectUInt16((ushort)(a ^ 7));
ExpectUInt16((ushort)(a ^ 0x7FFF));
ExpectUInt16((ushort)(a ^ 0xFFFF));
}

public void BitwiseXorWithConstantInt16(short a)
Expand All @@ -235,9 +235,9 @@ public void BitwiseXorWithConstantInt16(short a)

public void BitwiseXorWithConstantUInt8(byte a)
{
ExpectUInt8((byte)(a ^ 7u));
ExpectUInt8((byte)(a ^ 0x7Fu));
ExpectUInt8((byte)(a ^ 0xFFu));
ExpectUInt8((byte)(a ^ 7));
ExpectUInt8((byte)(a ^ 0x7F));
ExpectUInt8((byte)(a ^ 0xFF));
}

public void BitwiseXorWithConstantInt8(sbyte a)
Expand All @@ -246,6 +246,20 @@ public void BitwiseXorWithConstantInt8(sbyte a)
ExpectInt8((sbyte)(a ^ 0x7F));
}

public int Issue2166a(int x)
{
if ((x & 0x10) != 0)
{
return 1;
}
return 0;
}

public byte Issue2166b(int x)
{
return (byte)(x & 0x10);
}

private void ExpectUInt64(ulong _)
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public ushort Issue1796b {
return (ushort)((uint64Field & 0xFFFF000000000000uL) >> 48);
}
set {
uint64Field = (uint64Field & 0xFFFFFFFFFFFFuL) | ((ulong)value << 48);
uint64Field = (uint64Field & 0xFFFFFFFFFFFFL) | ((ulong)value << 48);
}
}

Expand Down
30 changes: 9 additions & 21 deletions ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,7 @@ protected internal override TranslatedExpression VisitLdcI4(LdcI4 inst, Translat
rr = AdjustConstantToType(rr, context.TypeHint);
return ConvertConstantValue(
rr,
allowImplicitConversion: true,
ShouldDisplayAsHex(inst.Value, rr.Type, inst.Parent)
allowImplicitConversion: true
).WithILInstruction(inst);
}

Expand All @@ -566,29 +565,17 @@ protected internal override TranslatedExpression VisitLdcI8(LdcI8 inst, Translat
rr = AdjustConstantToType(rr, context.TypeHint);
return ConvertConstantValue(
rr,
allowImplicitConversion: true,
ShouldDisplayAsHex(inst.Value, rr.Type, inst.Parent)
allowImplicitConversion: true
).WithILInstruction(inst);
}

private bool ShouldDisplayAsHex(long value, IType type, ILInstruction parent)
private bool ShouldDisplayAsHex(long value, IType type)
{
if (parent is Conv conv)
parent = conv.Parent;
if (value >= 0 && value <= 9)
return false;
if (value < 0 && type.GetSign() == Sign.Signed)
return false;
switch (parent)
{
case BinaryNumericInstruction bni:
if (bni.Operator == BinaryNumericOperator.BitAnd
|| bni.Operator == BinaryNumericOperator.BitOr
|| bni.Operator == BinaryNumericOperator.BitXor)
return true;
break;
}
return false;
return true;
}

protected internal override TranslatedExpression VisitLdcF4(LdcF4 inst, TranslationContext context)
Expand Down Expand Up @@ -1525,8 +1512,9 @@ bool IsMatchingPointerType(IType type)
TranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOperatorType op, TranslationContext context)
{
var resolverWithOverflowCheck = resolver.WithCheckForOverflow(inst.CheckForOverflow);
var left = Translate(inst.Left, op.IsBitwise() ? context.TypeHint : null);
var right = Translate(inst.Right, op.IsBitwise() ? context.TypeHint : null);
bool propagateTypeHint = op.IsBitwise() && inst.LeftInputType != inst.RightInputType;
var left = Translate(inst.Left, propagateTypeHint ? context.TypeHint : null);
var right = Translate(inst.Right, propagateTypeHint ? context.TypeHint : null);

if (inst.UnderlyingResultType == StackType.Ref)
{
Expand Down Expand Up @@ -1613,7 +1601,7 @@ TranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOp
left = ConvertConstantValue(
left.ResolveResult,
allowImplicitConversion: false,
ShouldDisplayAsHex(value, left.Type, inst)
ShouldDisplayAsHex(value, left.Type)
).WithILInstruction(left.ILInstructions);
}
if (right.ResolveResult.ConstantValue != null)
Expand All @@ -1623,7 +1611,7 @@ TranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOp
right = ConvertConstantValue(
right.ResolveResult,
allowImplicitConversion: false,
ShouldDisplayAsHex(value, right.Type, inst)
ShouldDisplayAsHex(value, right.Type)
).WithILInstruction(right.ILInstructions);
}
}
Expand Down

0 comments on commit 8c440f4

Please sign in to comment.