On ia64, 32-bit rotates are implemented by copying the lower 32 bits of a register into the upper half, then performing a right shift. However, depending on the bit pattern in question, this can leave the upper 32 bits as non-zero, despite being only a 32-bit unsigned result. Therefore add an extra zero_extract to mask these out.
gcc/ PR rtl-optimization/83565 * gcc/config/ia64/ia64.md ("*rotrsi3_internal"): Mask out higher 32 bits from the shift result. ("*rotlsi3_internal"): Likewise --- [Resent because git send-email messed about with the headers, adding a second From: with a different email address, presumably since I ran git send-email from a directory with .git/config containing a user.email setting...] gcc/config/ia64/ia64.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index b7cd52b..8198b54 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -3329,7 +3329,10 @@ (ior:DI (zero_extend:DI (match_dup 1)) (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) (set (match_dup 3) - (lshiftrt:DI (match_dup 3) (match_dup 2)))] + (lshiftrt:DI (match_dup 3) (match_dup 2))) + (set (match_dup 3) + (zero_extract:DI (match_dup 3) + (const_int 32) (const_int 0)))] "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));") (define_expand "rotlsi3" @@ -3358,7 +3361,10 @@ (ior:DI (zero_extend:DI (match_dup 1)) (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) (set (match_dup 3) - (lshiftrt:DI (match_dup 3) (match_dup 2)))] + (lshiftrt:DI (match_dup 3) (match_dup 2))) + (set (match_dup 3) + (zero_extract:DI (match_dup 3) + (const_int 32) (const_int 0)))] { operands[3] = gen_rtx_REG (DImode, REGNO (operands[0])); operands[2] = GEN_INT (32 - INTVAL (operands[2])); -- 1.7.10.4