Made the logical shift / artihmetic shift not rely on signs of intigers#749
Open
FractalFir wants to merge 2 commits intorust-lang:masterfrom
Open
Made the logical shift / artihmetic shift not rely on signs of intigers#749FractalFir wants to merge 2 commits intorust-lang:masterfrom
FractalFir wants to merge 2 commits intorust-lang:masterfrom
Conversation
antoyo
reviewed
Aug 14, 2025
Contributor
antoyo
left a comment
There was a problem hiding this comment.
Thanks for making this PR!
| let b_size = b_type.get_size(); | ||
| match a_size.cmp(&b_size) { | ||
| std::cmp::Ordering::Less => { | ||
| let a = self.context.new_cast(self.location, a, b_type); |
Contributor
There was a problem hiding this comment.
Could you add a debug_assert!() that checks that the sign of a and b is the same here?
| } | ||
| std::cmp::Ordering::Equal => a >> b, | ||
| std::cmp::Ordering::Greater => { | ||
| let b = self.context.new_cast(self.location, b, a_type); |
Comment on lines
-86
to
+105
| std::cmp::Ordering::Less => { | ||
| let a = self.context.new_cast(self.location, a, b_type); | ||
| a >> b | ||
| } | ||
| std::cmp::Ordering::Equal => a >> b, | ||
| std::cmp::Ordering::Greater => { | ||
| let b = self.context.new_cast(self.location, b, a_type); | ||
| a >> b | ||
| } | ||
| let (a, a_type) = match (shift_kind, a_type.is_signed(self.cx)) { | ||
| (ShiftKind::Logical, true) => { | ||
| let a_type = a_type.to_unsigned(self.cx); | ||
| (self.gcc_int_cast(a, a_type), a_type) | ||
| } | ||
| (ShiftKind::Logical, false) => (a, a_type), | ||
| (ShiftKind::Arithmetic, true) => (a, a_type), | ||
| (ShiftKind::Arithmetic, false) => { | ||
| let a_type = a_type.to_signed(self.cx); | ||
| (self.gcc_int_cast(a, a_type), a_type) | ||
| } | ||
| }; | ||
| let (b, b_type) = match (shift_kind, b_type.is_signed(self.cx)) { | ||
| (ShiftKind::Logical, true) => { | ||
| let b_type = b_type.to_unsigned(self.cx); | ||
| (self.gcc_int_cast(b, b_type), b_type) | ||
| } | ||
| (ShiftKind::Logical, false) => (b, b_type), | ||
| (ShiftKind::Arithmetic, true) => (b, b_type), | ||
| (ShiftKind::Arithmetic, false) => { | ||
| let b_type = b_type.to_signed(self.cx); | ||
| (self.gcc_int_cast(b, b_type), b_type) | ||
| } | ||
| }; |
Contributor
There was a problem hiding this comment.
Could you please add a comment to explain that this casts to unsigned if needed to do a logical shift and to signed if needed to do an arithmetic shift?
| @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, Ty}; | |||
| use rustc_target::callconv::{ArgAbi, ArgAttributes, FnAbi, PassMode}; | |||
Contributor
There was a problem hiding this comment.
Would it be easy to add a test for this fix?
Co-authored-by: antoyo <antoyo@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Currently,
ashr&lshrshare the same implementation, and the shift type is guessed based on the sign of the type.This is incorrect W.R.T.
cg_ssasemantics(type don't have signs, operations do), and has caused silent miscompilations in the past(cg_ssarequested a logcal shift, butcg_gccinserted an arithmetic one). This bug was pretty rare, but was still a miscompilation.This PR fixes that bug, by introducing a new parameter(
ShiftKind) togcc_shr(renamed fromgcc_lshr). This allows both shift kinds to still share an implementation, while being very explicit about the requested shift.