Skip to content

Commit 8c440f4

Browse files
Fix icsharpcode#2166: Unnecessary uint casts/conversions for certain bitwise operations
1 parent ac0ef8a commit 8c440f4

File tree

5 files changed

+58
-56
lines changed

5 files changed

+58
-56
lines changed

ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ public class Program
44
{
55
public static long fnWorks(int x, int y)
66
{
7-
return (long)(((ulong)y & 0xFFFFFFuL) << 24) | ((long)x & 0xFFFFFFL);
7+
return (long)((((ulong)y & 0xFFFFFFuL) << 24) | ((ulong)x & 0xFFFFFFuL));
88
}
99

1010
public static long fnFails(int x, int y)

ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,8 +2943,8 @@ public static void UintRightShiftTest(uint p, CustomClass c, CustomStruct2 s)
29432943
public static void UintBitAndTest(uint p, CustomClass c, CustomStruct2 s)
29442944
{
29452945
uint num = 0u;
2946-
p &= 5u;
2947-
num &= 5u;
2946+
p &= 5;
2947+
num &= 5;
29482948
Use(ref num);
29492949
uintField &= 5u;
29502950
UintProp &= 5u;
@@ -2970,8 +2970,8 @@ public static void UintBitAndTest(uint p, CustomClass c, CustomStruct2 s)
29702970
public static void UintBitOrTest(uint p, CustomClass c, CustomStruct2 s)
29712971
{
29722972
uint num = 0u;
2973-
p |= 5u;
2974-
num |= 5u;
2973+
p |= 5;
2974+
num |= 5;
29752975
Use(ref num);
29762976
uintField |= 5u;
29772977
UintProp |= 5u;
@@ -2997,8 +2997,8 @@ public static void UintBitOrTest(uint p, CustomClass c, CustomStruct2 s)
29972997
public static void UintBitXorTest(uint p, CustomClass c, CustomStruct2 s)
29982998
{
29992999
uint num = 0u;
3000-
p ^= 5u;
3001-
num ^= 5u;
3000+
p ^= 5;
3001+
num ^= 5;
30023002
Use(ref num);
30033003
uintField ^= 5u;
30043004
UintProp ^= 5u;

ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void BitwiseAndWithConstantUInt64(ulong a)
8383
ExpectUInt64(a & 7);
8484
ExpectUInt64(a & 0x7FFFFFFF);
8585
ExpectUInt64(a & 0xFFFFFFFFu);
86-
ExpectUInt64(a & 0x7FFFFFFFFFFFFFFFuL);
86+
ExpectUInt64(a & 0x7FFFFFFFFFFFFFFFL);
8787
ExpectUInt64(a & 0xFFFFFFFFFFFFFFFFuL);
8888
}
8989

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

9898
public void BitwiseAndWithConstantUInt32(uint a)
9999
{
100-
ExpectUInt32(a & 7u);
101-
ExpectUInt32(a & 0x7FFFFFFFu);
100+
ExpectUInt32(a & 7);
101+
ExpectUInt32(a & 0x7FFFFFFF);
102102
ExpectUInt32(a & 0xFFFFFFFFu);
103103
}
104104

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

111111
public void BitwiseAndWithConstantUInt16(ushort a)
112112
{
113-
ExpectUInt16((ushort)(a & 7u));
114-
ExpectUInt16((ushort)(a & 0x7FFFu));
115-
ExpectUInt16((ushort)(a & 0xFFFFu));
113+
ExpectUInt16((ushort)(a & 7));
114+
ExpectUInt16((ushort)(a & 0x7FFF));
115+
ExpectUInt16((ushort)(a & 0xFFFF));
116116
}
117117

118118
public void BitwiseAndWithConstantInt16(short a)
@@ -123,9 +123,9 @@ public void BitwiseAndWithConstantInt16(short a)
123123

124124
public void BitwiseAndWithConstantUInt8(byte a)
125125
{
126-
ExpectUInt8((byte)(a & 7u));
127-
ExpectUInt8((byte)(a & 0x7Fu));
128-
ExpectUInt8((byte)(a & 0xFFu));
126+
ExpectUInt8((byte)(a & 7));
127+
ExpectUInt8((byte)(a & 0x7F));
128+
ExpectUInt8((byte)(a & 0xFF));
129129
}
130130

131131
public void BitwiseAndWithConstantInt8(sbyte a)
@@ -139,7 +139,7 @@ public void BitwiseOrWithConstantUInt64(ulong a)
139139
ExpectUInt64(a | 7);
140140
ExpectUInt64(a | 0x7FFFFFFF);
141141
ExpectUInt64(a | 0xFFFFFFFFu);
142-
ExpectUInt64(a | 0x7FFFFFFFFFFFFFFFuL);
142+
ExpectUInt64(a | 0x7FFFFFFFFFFFFFFFL);
143143
ExpectUInt64(a | 0xFFFFFFFFFFFFFFFFuL);
144144
}
145145

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

154154
public void BitwiseOrWithConstantUInt32(uint a)
155155
{
156-
ExpectUInt32(a | 7u);
157-
ExpectUInt32(a | 0x7FFFFFFFu);
156+
ExpectUInt32(a | 7);
157+
ExpectUInt32(a | 0x7FFFFFFF);
158158
ExpectUInt32(a | 0xFFFFFFFFu);
159159
}
160160

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

167167
public void BitwiseOrWithConstantUInt16(ushort a)
168168
{
169-
ExpectUInt16((ushort)(a | 7u));
170-
ExpectUInt16((ushort)(a | 0x7FFFu));
171-
ExpectUInt16((ushort)(a | 0xFFFFu));
169+
ExpectUInt16((ushort)(a | 7));
170+
ExpectUInt16((ushort)(a | 0x7FFF));
171+
ExpectUInt16((ushort)(a | 0xFFFF));
172172
}
173173

174174
public void BitwiseOrWithConstantInt16(short a)
@@ -179,9 +179,9 @@ public void BitwiseOrWithConstantInt16(short a)
179179

180180
public void BitwiseOrWithConstantUInt8(byte a)
181181
{
182-
ExpectUInt8((byte)(a | 7u));
183-
ExpectUInt8((byte)(a | 0x7Fu));
184-
ExpectUInt8((byte)(a | 0xFFu));
182+
ExpectUInt8((byte)(a | 7));
183+
ExpectUInt8((byte)(a | 0x7F));
184+
ExpectUInt8((byte)(a | 0xFF));
185185
}
186186

187187
public void BitwiseOrWithConstantInt8(sbyte a)
@@ -195,7 +195,7 @@ public void BitwiseXorWithConstantUInt64(ulong a)
195195
ExpectUInt64(a ^ 7);
196196
ExpectUInt64(a ^ 0x7FFFFFFF);
197197
ExpectUInt64(a ^ 0xFFFFFFFFu);
198-
ExpectUInt64(a ^ 0x7FFFFFFFFFFFFFFFuL);
198+
ExpectUInt64(a ^ 0x7FFFFFFFFFFFFFFFL);
199199
ExpectUInt64(a ^ 0xFFFFFFFFFFFFFFFFuL);
200200
}
201201

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

210210
public void BitwiseXorWithConstantUInt32(uint a)
211211
{
212-
ExpectUInt32(a ^ 7u);
213-
ExpectUInt32(a ^ 0x7FFFFFFFu);
212+
ExpectUInt32(a ^ 7);
213+
ExpectUInt32(a ^ 0x7FFFFFFF);
214214
ExpectUInt32(a ^ 0xFFFFFFFFu);
215215
}
216216

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

223223
public void BitwiseXorWithConstantUInt16(ushort a)
224224
{
225-
ExpectUInt16((ushort)(a ^ 7u));
226-
ExpectUInt16((ushort)(a ^ 0x7FFFu));
227-
ExpectUInt16((ushort)(a ^ 0xFFFFu));
225+
ExpectUInt16((ushort)(a ^ 7));
226+
ExpectUInt16((ushort)(a ^ 0x7FFF));
227+
ExpectUInt16((ushort)(a ^ 0xFFFF));
228228
}
229229

230230
public void BitwiseXorWithConstantInt16(short a)
@@ -235,9 +235,9 @@ public void BitwiseXorWithConstantInt16(short a)
235235

236236
public void BitwiseXorWithConstantUInt8(byte a)
237237
{
238-
ExpectUInt8((byte)(a ^ 7u));
239-
ExpectUInt8((byte)(a ^ 0x7Fu));
240-
ExpectUInt8((byte)(a ^ 0xFFu));
238+
ExpectUInt8((byte)(a ^ 7));
239+
ExpectUInt8((byte)(a ^ 0x7F));
240+
ExpectUInt8((byte)(a ^ 0xFF));
241241
}
242242

243243
public void BitwiseXorWithConstantInt8(sbyte a)
@@ -246,6 +246,20 @@ public void BitwiseXorWithConstantInt8(sbyte a)
246246
ExpectInt8((sbyte)(a ^ 0x7F));
247247
}
248248

249+
public int Issue2166a(int x)
250+
{
251+
if ((x & 0x10) != 0)
252+
{
253+
return 1;
254+
}
255+
return 0;
256+
}
257+
258+
public byte Issue2166b(int x)
259+
{
260+
return (byte)(x & 0x10);
261+
}
262+
249263
private void ExpectUInt64(ulong _)
250264
{
251265

ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public ushort Issue1796b {
4444
return (ushort)((uint64Field & 0xFFFF000000000000uL) >> 48);
4545
}
4646
set {
47-
uint64Field = (uint64Field & 0xFFFFFFFFFFFFuL) | ((ulong)value << 48);
47+
uint64Field = (uint64Field & 0xFFFFFFFFFFFFL) | ((ulong)value << 48);
4848
}
4949
}
5050

ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,7 @@ protected internal override TranslatedExpression VisitLdcI4(LdcI4 inst, Translat
541541
rr = AdjustConstantToType(rr, context.TypeHint);
542542
return ConvertConstantValue(
543543
rr,
544-
allowImplicitConversion: true,
545-
ShouldDisplayAsHex(inst.Value, rr.Type, inst.Parent)
544+
allowImplicitConversion: true
546545
).WithILInstruction(inst);
547546
}
548547

@@ -566,29 +565,17 @@ protected internal override TranslatedExpression VisitLdcI8(LdcI8 inst, Translat
566565
rr = AdjustConstantToType(rr, context.TypeHint);
567566
return ConvertConstantValue(
568567
rr,
569-
allowImplicitConversion: true,
570-
ShouldDisplayAsHex(inst.Value, rr.Type, inst.Parent)
568+
allowImplicitConversion: true
571569
).WithILInstruction(inst);
572570
}
573571

574-
private bool ShouldDisplayAsHex(long value, IType type, ILInstruction parent)
572+
private bool ShouldDisplayAsHex(long value, IType type)
575573
{
576-
if (parent is Conv conv)
577-
parent = conv.Parent;
578574
if (value >= 0 && value <= 9)
579575
return false;
580576
if (value < 0 && type.GetSign() == Sign.Signed)
581577
return false;
582-
switch (parent)
583-
{
584-
case BinaryNumericInstruction bni:
585-
if (bni.Operator == BinaryNumericOperator.BitAnd
586-
|| bni.Operator == BinaryNumericOperator.BitOr
587-
|| bni.Operator == BinaryNumericOperator.BitXor)
588-
return true;
589-
break;
590-
}
591-
return false;
578+
return true;
592579
}
593580

594581
protected internal override TranslatedExpression VisitLdcF4(LdcF4 inst, TranslationContext context)
@@ -1525,8 +1512,9 @@ bool IsMatchingPointerType(IType type)
15251512
TranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOperatorType op, TranslationContext context)
15261513
{
15271514
var resolverWithOverflowCheck = resolver.WithCheckForOverflow(inst.CheckForOverflow);
1528-
var left = Translate(inst.Left, op.IsBitwise() ? context.TypeHint : null);
1529-
var right = Translate(inst.Right, op.IsBitwise() ? context.TypeHint : null);
1515+
bool propagateTypeHint = op.IsBitwise() && inst.LeftInputType != inst.RightInputType;
1516+
var left = Translate(inst.Left, propagateTypeHint ? context.TypeHint : null);
1517+
var right = Translate(inst.Right, propagateTypeHint ? context.TypeHint : null);
15301518

15311519
if (inst.UnderlyingResultType == StackType.Ref)
15321520
{
@@ -1613,7 +1601,7 @@ TranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOp
16131601
left = ConvertConstantValue(
16141602
left.ResolveResult,
16151603
allowImplicitConversion: false,
1616-
ShouldDisplayAsHex(value, left.Type, inst)
1604+
ShouldDisplayAsHex(value, left.Type)
16171605
).WithILInstruction(left.ILInstructions);
16181606
}
16191607
if (right.ResolveResult.ConstantValue != null)
@@ -1623,7 +1611,7 @@ TranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOp
16231611
right = ConvertConstantValue(
16241612
right.ResolveResult,
16251613
allowImplicitConversion: false,
1626-
ShouldDisplayAsHex(value, right.Type, inst)
1614+
ShouldDisplayAsHex(value, right.Type)
16271615
).WithILInstruction(right.ILInstructions);
16281616
}
16291617
}

0 commit comments

Comments
 (0)