Brian Cain 4fffee0375
[Hexagon] Fix 64-bit funnel shift miscompilation with register shift amounts (#183669)
64-bit regpair shift amounts are treated as signed 7-bits, so a
complement
shift amount of 64 (when the primary amount is 0) is sign-extended to
-64,
reversing the shift direction and producing incorrect results. This
affected
any 64-bit rotate or funnel shift where the runtime shift amount could
be 0
(making the complement 64) or >= 64.
    
Fix by masking the shift amount to [0, 63] and computing the complement
as
(m - 64), which is always in [-64, -1]. Using lsl/lsr (logical shift)
instructions with this negative amount causes the hardware to reverse
the
shift direction while zero-filling vacated positions:
    
fshl(a, b, amt) = (a << m) | lsl(b, m - 64) // lsl reverses to lsr
fshr(a, b, amt) = (b >> m) | lsr(a, m - 64) // lsr reverses to lsl
    
where m = amt & 63. The logical shift instructions (lsl/lsr) are used
instead of arithmetic (asl) because asl with a negative amount performs
an
arithmetic right shift that sign-extends, which would corrupt the result
for negative source values.
    
When m = 0, the complement amount is -64 (magnitude 64), which shifts
all
64 bits out and produces zero, so the complement term vanishes as
required.
2026-03-10 09:16:46 -05:00
..
2025-10-20 15:59:03 -05:00
2025-10-20 15:59:03 -05:00