Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support built-in unsigned right shift operators. #60560

Conversation

AlekseyTs
Copy link
Contributor

@AlekseyTs AlekseyTs commented Apr 4, 2022

@AlekseyTs
Copy link
Contributor Author

@333fred, @jcouv, @dotnet/roslyn-compiler Please review.

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done review pass (commit 1)

// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable
Copy link
Member

@333fred 333fred Apr 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did I miss a langver test in here? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did I miss a langver test in here?

I haven't touched the lang version part yet.

LiftedULongUnsignedRightShift = Lifted | ULong | UnsignedRightShift,
LiftedNIntUnsignedRightShift = Lifted | NInt | UnsignedRightShift,
LiftedNUIntUnsignedRightShift = Lifted | NUInt | UnsignedRightShift,
LiftedUserDefinedUnsignedRightShift = Lifted | UserDefined | UnsignedRightShift,
Copy link
Member

@333fred 333fred Apr 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't seem like this was tested, should it also be commented out with a prototype for now? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't seem like this was tested, should it also be commented out with a prototype for now?

I do not think it is strictly necessary. Working on user-defined operators now (for the next PR)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright. I don't have a problem with it, was just curious since you commented out the non-lifted variant.

@jcouv jcouv self-assigned this Apr 5, 2022
@AlekseyTs
Copy link
Contributor Author

@jcouv, @dotnet/roslyn-compiler For the second review

3 similar comments
@AlekseyTs
Copy link
Contributor Author

@jcouv, @dotnet/roslyn-compiler For the second review

@AlekseyTs
Copy link
Contributor Author

@jcouv, @dotnet/roslyn-compiler For the second review

@AlekseyTs
Copy link
Contributor Author

@jcouv, @dotnet/roslyn-compiler For the second review

@@ -225,6 +225,10 @@ private void EmitBinaryOperatorInstruction(BoundBinaryOperator expression)
}
break;

case BinaryOperatorKind.UnsignedRightShift:
Copy link
Member

@jcouv jcouv Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding an assertion in IsUnsignedBinaryOperator that it's not meant to be used on an unsigned right shift. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding an assertion in IsUnsignedBinaryOperator that it's not meant to be used on an unsigned right shift.

Will add in one of the next PRs

case BinaryOperatorKind.IntUnsignedRightShift:
return (int)(((uint)valueLeft.Int32Value) >> valueRight.Int32Value); // Switch to `valueLeft.Int32Value >>> valueRight.Int32Value` once >>> becomes available
case BinaryOperatorKind.NIntUnsignedRightShift:
return (valueLeft.Int32Value >= 0) ? valueLeft.Int32Value >> valueRight.Int32Value : null;
Copy link
Member

@jcouv jcouv Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand why we can't compute the constant result when valueLeft.Int32Value < 0 #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand why we can't compute the constant result when valueLeft.Int32Value < 0

Binary representation of negative values depends on the actual size of the type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worked it out on paper. Makes sense

@@ -1951,12 +1951,21 @@ internal static SpecialType GetEnumPromotedType(SpecialType underlyingType)
case BinaryOperatorKind.IntRightShift:
case BinaryOperatorKind.NIntRightShift:
return valueLeft.Int32Value >> valueRight.Int32Value;
case BinaryOperatorKind.IntUnsignedRightShift:
return (int)(((uint)valueLeft.Int32Value) >> valueRight.Int32Value); // Switch to `valueLeft.Int32Value >>> valueRight.Int32Value` once >>> becomes available
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Consider opening a tracking issue, otherwise we'll likely forget

@@ -414,6 +414,32 @@ void M(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int
VerifyOperationTreeAndDiagnosticsForTest<InvocationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}

[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TestBinaryOperators_UnsignedRightShift()
Copy link
Member

@jcouv jcouv Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also have IOp tests with >>>=, or will that be a later PR? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also have IOp tests with >>>=, or will that be a later PR?

Yes we should have those. I will add them in a later PR.

[InlineData("decimal", "nuint")]
[InlineData("decimal", "float")]
[InlineData("decimal", "double")]
[InlineData("decimal", "decimal")]
Copy link
Member

@jcouv jcouv Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using CombinatorialData (more compact, less tedious to type/review). This applies to other tests as well #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using CombinatorialData (more compact, less tedious to type/review). This applies to other tests as well

Will simplify in one of the next PRs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I do not think CombinatorialData is going to work. We are not testing cross product of two type sets.

}
";
var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll,
parseOptions: TestOptions.RegularPreview);
Copy link
Member

@jcouv jcouv Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: all these tests don't need TestOptions.RegularPreview (that's the default) #WontFix

Assert.Equal("x >>> y", unsignedShift.ToString());
Assert.Equal("x >> y", shift.ToString());

var unsignedShiftSymbol = (IMethodSymbol)model.GetSymbolInfo(unsignedShift).Symbol;
Copy link
Member

@jcouv jcouv Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider verifying GetTypeInfo too, or adding to test plan #WontFix

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider verifying GetTypeInfo too, or adding to test plan

I do not find this particularly interesting. Completeness is the only reason to have them. I am not adding new bound nodes, there is nothing new there in terms of calculating type info. Symbol info is interesting because we are supposed to synthesize operator symbols for intrinsic operators.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks (iteration 1), but reducing the verbosity of the InlineData sequences in the tests would be really appreciated. Also a couple of nits to consider

@AlekseyTs AlekseyTs merged commit c7b2b5a into dotnet:features/UnsignedRightShift Apr 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants