[llvm] [X86] Allow rotate to be affected by modulo shift (PR #156684)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 07:43:11 PDT 2025
https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/156684
The rotate uses the bottom 5 bits, so we can apply the same modulo we have here too.
>From 2fa6595fe4bb8894ea352ad971ee61e5ee51b51f Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Wed, 3 Sep 2025 10:35:51 -0400
Subject: [PATCH 1/2] Pre-commit tests (NFC)
---
llvm/test/CodeGen/X86/not-shift.ll | 518 ++++++++++++++++++++++
llvm/test/CodeGen/X86/shift-amount-mod.ll | 205 +++++++++
2 files changed, 723 insertions(+)
diff --git a/llvm/test/CodeGen/X86/not-shift.ll b/llvm/test/CodeGen/X86/not-shift.ll
index 1d2fd19cff6eb..64b361f123239 100644
--- a/llvm/test/CodeGen/X86/not-shift.ll
+++ b/llvm/test/CodeGen/X86/not-shift.ll
@@ -704,3 +704,521 @@ define i32 @invalid_add31(i32 %val, i32 %cnt) nounwind {
%result = shl i32 %val, %adjcnt
ret i32 %result
}
+
+;==============================================================================;
+; Rotate tests (via funnel shifts) matching the shift-count transforms theme
+;==============================================================================;
+
+declare i64 @llvm.fshl.i64(i64, i64, i64)
+declare i64 @llvm.fshr.i64(i64, i64, i64)
+declare i32 @llvm.fshl.i32(i32, i32, i32)
+declare i32 @llvm.fshr.i32(i32, i32, i32)
+
+; 64-bit rotates with xor 63 (Size*N-1)
+; CHECK-LABEL: rotl64_xor63
+define i64 @rotl64_xor63(i64 %val, i64 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotl64_xor63:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: pushl %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notl %ecx
+; X86-NOBMI2-NEXT: testb $32, %cl
+; X86-NOBMI2-NEXT: jne .LBB16_1
+; X86-NOBMI2-NEXT: # %bb.2:
+; X86-NOBMI2-NEXT: movl %eax, %edx
+; X86-NOBMI2-NEXT: jmp .LBB16_3
+; X86-NOBMI2-NEXT: .LBB16_1:
+; X86-NOBMI2-NEXT: movl %esi, %edx
+; X86-NOBMI2-NEXT: movl %eax, %esi
+; X86-NOBMI2-NEXT: .LBB16_3:
+; X86-NOBMI2-NEXT: movl %esi, %eax
+; X86-NOBMI2-NEXT: shldl %cl, %edx, %eax
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: shldl %cl, %esi, %edx
+; X86-NOBMI2-NEXT: popl %esi
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotl64_xor63:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: pushl %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: notl %ecx
+; X86-BMI2-NEXT: testb $32, %cl
+; X86-BMI2-NEXT: jne .LBB16_1
+; X86-BMI2-NEXT: # %bb.2:
+; X86-BMI2-NEXT: movl %eax, %edx
+; X86-BMI2-NEXT: jmp .LBB16_3
+; X86-BMI2-NEXT: .LBB16_1:
+; X86-BMI2-NEXT: movl %esi, %edx
+; X86-BMI2-NEXT: movl %eax, %esi
+; X86-BMI2-NEXT: .LBB16_3:
+; X86-BMI2-NEXT: movl %esi, %eax
+; X86-BMI2-NEXT: shldl %cl, %edx, %eax
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: shldl %cl, %esi, %edx
+; X86-BMI2-NEXT: popl %esi
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotl64_xor63:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rsi, %rcx
+; X64-NOBMI2-NEXT: movq %rdi, %rax
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-NOBMI2-NEXT: rolq %cl, %rax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotl64_xor63:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rsi, %rcx
+; X64-BMI2-NEXT: movq %rdi, %rax
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-BMI2-NEXT: rolq %cl, %rax
+; X64-BMI2-NEXT: retq
+ %adj = xor i64 %cnt, 63
+ %r = call i64 @llvm.fshl.i64(i64 %val, i64 %val, i64 %adj)
+ ret i64 %r
+}
+
+; CHECK-LABEL: rotr64_xor63
+define i64 @rotr64_xor63(i64 %val, i64 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotr64_xor63:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: pushl %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notl %ecx
+; X86-NOBMI2-NEXT: testb $32, %cl
+; X86-NOBMI2-NEXT: je .LBB17_1
+; X86-NOBMI2-NEXT: # %bb.2:
+; X86-NOBMI2-NEXT: movl %eax, %edx
+; X86-NOBMI2-NEXT: jmp .LBB17_3
+; X86-NOBMI2-NEXT: .LBB17_1:
+; X86-NOBMI2-NEXT: movl %esi, %edx
+; X86-NOBMI2-NEXT: movl %eax, %esi
+; X86-NOBMI2-NEXT: .LBB17_3:
+; X86-NOBMI2-NEXT: movl %esi, %eax
+; X86-NOBMI2-NEXT: shrdl %cl, %edx, %eax
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: shrdl %cl, %esi, %edx
+; X86-NOBMI2-NEXT: popl %esi
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotr64_xor63:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: pushl %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: notl %ecx
+; X86-BMI2-NEXT: testb $32, %cl
+; X86-BMI2-NEXT: je .LBB17_1
+; X86-BMI2-NEXT: # %bb.2:
+; X86-BMI2-NEXT: movl %eax, %edx
+; X86-BMI2-NEXT: jmp .LBB17_3
+; X86-BMI2-NEXT: .LBB17_1:
+; X86-BMI2-NEXT: movl %esi, %edx
+; X86-BMI2-NEXT: movl %eax, %esi
+; X86-BMI2-NEXT: .LBB17_3:
+; X86-BMI2-NEXT: movl %esi, %eax
+; X86-BMI2-NEXT: shrdl %cl, %edx, %eax
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: shrdl %cl, %esi, %edx
+; X86-BMI2-NEXT: popl %esi
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotr64_xor63:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rsi, %rcx
+; X64-NOBMI2-NEXT: movq %rdi, %rax
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-NOBMI2-NEXT: rorq %cl, %rax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotr64_xor63:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rsi, %rcx
+; X64-BMI2-NEXT: movq %rdi, %rax
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-BMI2-NEXT: rorq %cl, %rax
+; X64-BMI2-NEXT: retq
+ %adj = xor i64 %cnt, 63
+ %r = call i64 @llvm.fshr.i64(i64 %val, i64 %val, i64 %adj)
+ ret i64 %r
+}
+
+; 64-bit rotates with xor 127 (Size*N-1)
+; CHECK-LABEL: rotl64_xor127
+define i64 @rotl64_xor127(i64 %val, i64 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotl64_xor127:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: pushl %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notl %ecx
+; X86-NOBMI2-NEXT: testb $32, %cl
+; X86-NOBMI2-NEXT: jne .LBB18_1
+; X86-NOBMI2-NEXT: # %bb.2:
+; X86-NOBMI2-NEXT: movl %eax, %edx
+; X86-NOBMI2-NEXT: jmp .LBB18_3
+; X86-NOBMI2-NEXT: .LBB18_1:
+; X86-NOBMI2-NEXT: movl %esi, %edx
+; X86-NOBMI2-NEXT: movl %eax, %esi
+; X86-NOBMI2-NEXT: .LBB18_3:
+; X86-NOBMI2-NEXT: movl %esi, %eax
+; X86-NOBMI2-NEXT: shldl %cl, %edx, %eax
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: shldl %cl, %esi, %edx
+; X86-NOBMI2-NEXT: popl %esi
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotl64_xor127:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: pushl %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: notl %ecx
+; X86-BMI2-NEXT: testb $32, %cl
+; X86-BMI2-NEXT: jne .LBB18_1
+; X86-BMI2-NEXT: # %bb.2:
+; X86-BMI2-NEXT: movl %eax, %edx
+; X86-BMI2-NEXT: jmp .LBB18_3
+; X86-BMI2-NEXT: .LBB18_1:
+; X86-BMI2-NEXT: movl %esi, %edx
+; X86-BMI2-NEXT: movl %eax, %esi
+; X86-BMI2-NEXT: .LBB18_3:
+; X86-BMI2-NEXT: movl %esi, %eax
+; X86-BMI2-NEXT: shldl %cl, %edx, %eax
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: shldl %cl, %esi, %edx
+; X86-BMI2-NEXT: popl %esi
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotl64_xor127:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rsi, %rcx
+; X64-NOBMI2-NEXT: movq %rdi, %rax
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-NOBMI2-NEXT: rolq %cl, %rax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotl64_xor127:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rsi, %rcx
+; X64-BMI2-NEXT: movq %rdi, %rax
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-BMI2-NEXT: rolq %cl, %rax
+; X64-BMI2-NEXT: retq
+ %adj = xor i64 %cnt, 127
+ %r = call i64 @llvm.fshl.i64(i64 %val, i64 %val, i64 %adj)
+ ret i64 %r
+}
+
+; CHECK-LABEL: rotr64_xor127
+define i64 @rotr64_xor127(i64 %val, i64 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotr64_xor127:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: pushl %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notl %ecx
+; X86-NOBMI2-NEXT: testb $32, %cl
+; X86-NOBMI2-NEXT: je .LBB19_1
+; X86-NOBMI2-NEXT: # %bb.2:
+; X86-NOBMI2-NEXT: movl %eax, %edx
+; X86-NOBMI2-NEXT: jmp .LBB19_3
+; X86-NOBMI2-NEXT: .LBB19_1:
+; X86-NOBMI2-NEXT: movl %esi, %edx
+; X86-NOBMI2-NEXT: movl %eax, %esi
+; X86-NOBMI2-NEXT: .LBB19_3:
+; X86-NOBMI2-NEXT: movl %esi, %eax
+; X86-NOBMI2-NEXT: shrdl %cl, %edx, %eax
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: shrdl %cl, %esi, %edx
+; X86-NOBMI2-NEXT: popl %esi
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotr64_xor127:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: pushl %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: notl %ecx
+; X86-BMI2-NEXT: testb $32, %cl
+; X86-BMI2-NEXT: je .LBB19_1
+; X86-BMI2-NEXT: # %bb.2:
+; X86-BMI2-NEXT: movl %eax, %edx
+; X86-BMI2-NEXT: jmp .LBB19_3
+; X86-BMI2-NEXT: .LBB19_1:
+; X86-BMI2-NEXT: movl %esi, %edx
+; X86-BMI2-NEXT: movl %eax, %esi
+; X86-BMI2-NEXT: .LBB19_3:
+; X86-BMI2-NEXT: movl %esi, %eax
+; X86-BMI2-NEXT: shrdl %cl, %edx, %eax
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: shrdl %cl, %esi, %edx
+; X86-BMI2-NEXT: popl %esi
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotr64_xor127:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rsi, %rcx
+; X64-NOBMI2-NEXT: movq %rdi, %rax
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-NOBMI2-NEXT: rorq %cl, %rax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotr64_xor127:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rsi, %rcx
+; X64-BMI2-NEXT: movq %rdi, %rax
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $rcx
+; X64-BMI2-NEXT: rorq %cl, %rax
+; X64-BMI2-NEXT: retq
+ %adj = xor i64 %cnt, 127
+ %r = call i64 @llvm.fshr.i64(i64 %val, i64 %val, i64 %adj)
+ ret i64 %r
+}
+
+; 64-bit rotates with sub 63 (negation within mask)
+; CHECK-LABEL: rotl64_sub63
+define i64 @rotl64_sub63(i64 %val, i64 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotl64_sub63:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: pushl %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl $63, %ecx
+; X86-NOBMI2-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: testb $32, %cl
+; X86-NOBMI2-NEXT: jne .LBB20_1
+; X86-NOBMI2-NEXT: # %bb.2:
+; X86-NOBMI2-NEXT: movl %eax, %edx
+; X86-NOBMI2-NEXT: jmp .LBB20_3
+; X86-NOBMI2-NEXT: .LBB20_1:
+; X86-NOBMI2-NEXT: movl %esi, %edx
+; X86-NOBMI2-NEXT: movl %eax, %esi
+; X86-NOBMI2-NEXT: .LBB20_3:
+; X86-NOBMI2-NEXT: movl %esi, %eax
+; X86-NOBMI2-NEXT: shldl %cl, %edx, %eax
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: shldl %cl, %esi, %edx
+; X86-NOBMI2-NEXT: popl %esi
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotl64_sub63:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: pushl %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl $63, %ecx
+; X86-BMI2-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: testb $32, %cl
+; X86-BMI2-NEXT: jne .LBB20_1
+; X86-BMI2-NEXT: # %bb.2:
+; X86-BMI2-NEXT: movl %eax, %edx
+; X86-BMI2-NEXT: jmp .LBB20_3
+; X86-BMI2-NEXT: .LBB20_1:
+; X86-BMI2-NEXT: movl %esi, %edx
+; X86-BMI2-NEXT: movl %eax, %esi
+; X86-BMI2-NEXT: .LBB20_3:
+; X86-BMI2-NEXT: movl %esi, %eax
+; X86-BMI2-NEXT: shldl %cl, %edx, %eax
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: shldl %cl, %esi, %edx
+; X86-BMI2-NEXT: popl %esi
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotl64_sub63:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rdi, %rax
+; X64-NOBMI2-NEXT: movl $63, %ecx
+; X64-NOBMI2-NEXT: subl %esi, %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI2-NEXT: rolq %cl, %rax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotl64_sub63:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rdi, %rax
+; X64-BMI2-NEXT: movl $63, %ecx
+; X64-BMI2-NEXT: subl %esi, %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-BMI2-NEXT: rolq %cl, %rax
+; X64-BMI2-NEXT: retq
+ %adj = sub i64 63, %cnt
+ %r = call i64 @llvm.fshl.i64(i64 %val, i64 %val, i64 %adj)
+ ret i64 %r
+}
+
+; CHECK-LABEL: rotr64_sub63
+define i64 @rotr64_sub63(i64 %val, i64 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotr64_sub63:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: pushl %esi
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NOBMI2-NEXT: movl $63, %ecx
+; X86-NOBMI2-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: testb $32, %cl
+; X86-NOBMI2-NEXT: je .LBB21_1
+; X86-NOBMI2-NEXT: # %bb.2:
+; X86-NOBMI2-NEXT: movl %eax, %edx
+; X86-NOBMI2-NEXT: jmp .LBB21_3
+; X86-NOBMI2-NEXT: .LBB21_1:
+; X86-NOBMI2-NEXT: movl %esi, %edx
+; X86-NOBMI2-NEXT: movl %eax, %esi
+; X86-NOBMI2-NEXT: .LBB21_3:
+; X86-NOBMI2-NEXT: movl %esi, %eax
+; X86-NOBMI2-NEXT: shrdl %cl, %edx, %eax
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: shrdl %cl, %esi, %edx
+; X86-NOBMI2-NEXT: popl %esi
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotr64_sub63:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: pushl %esi
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-BMI2-NEXT: movl $63, %ecx
+; X86-BMI2-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: testb $32, %cl
+; X86-BMI2-NEXT: je .LBB21_1
+; X86-BMI2-NEXT: # %bb.2:
+; X86-BMI2-NEXT: movl %eax, %edx
+; X86-BMI2-NEXT: jmp .LBB21_3
+; X86-BMI2-NEXT: .LBB21_1:
+; X86-BMI2-NEXT: movl %esi, %edx
+; X86-BMI2-NEXT: movl %eax, %esi
+; X86-BMI2-NEXT: .LBB21_3:
+; X86-BMI2-NEXT: movl %esi, %eax
+; X86-BMI2-NEXT: shrdl %cl, %edx, %eax
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: shrdl %cl, %esi, %edx
+; X86-BMI2-NEXT: popl %esi
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotr64_sub63:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rdi, %rax
+; X64-NOBMI2-NEXT: movl $63, %ecx
+; X64-NOBMI2-NEXT: subl %esi, %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI2-NEXT: rorq %cl, %rax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotr64_sub63:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rdi, %rax
+; X64-BMI2-NEXT: movl $63, %ecx
+; X64-BMI2-NEXT: subl %esi, %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-BMI2-NEXT: rorq %cl, %rax
+; X64-BMI2-NEXT: retq
+ %adj = sub i64 63, %cnt
+ %r = call i64 @llvm.fshr.i64(i64 %val, i64 %val, i64 %adj)
+ ret i64 %r
+}
+
+; 32-bit rotates with xor 31
+; CHECK-LABEL: rotl32_xor31
+define i32 @rotl32_xor31(i32 %val, i32 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotl32_xor31:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notl %ecx
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: roll %cl, %eax
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotl32_xor31:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: notl %ecx
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: roll %cl, %eax
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotl32_xor31:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movl %esi, %ecx
+; X64-NOBMI2-NEXT: movl %edi, %eax
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI2-NEXT: roll %cl, %eax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotl32_xor31:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movl %esi, %ecx
+; X64-BMI2-NEXT: movl %edi, %eax
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-BMI2-NEXT: roll %cl, %eax
+; X64-BMI2-NEXT: retq
+ %adj = xor i32 %cnt, 31
+ %r = call i32 @llvm.fshl.i32(i32 %val, i32 %val, i32 %adj)
+ ret i32 %r
+}
+
+; CHECK-LABEL: rotr32_xor31
+define i32 @rotr32_xor31(i32 %val, i32 %cnt) nounwind {
+; X86-NOBMI2-LABEL: rotr32_xor31:
+; X86-NOBMI2: # %bb.0:
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notl %ecx
+; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NOBMI2-NEXT: rorl %cl, %eax
+; X86-NOBMI2-NEXT: retl
+;
+; X86-BMI2-LABEL: rotr32_xor31:
+; X86-BMI2: # %bb.0:
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-BMI2-NEXT: notl %ecx
+; X86-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-BMI2-NEXT: rorl %cl, %eax
+; X86-BMI2-NEXT: retl
+;
+; X64-NOBMI2-LABEL: rotr32_xor31:
+; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movl %esi, %ecx
+; X64-NOBMI2-NEXT: movl %edi, %eax
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI2-NEXT: rorl %cl, %eax
+; X64-NOBMI2-NEXT: retq
+;
+; X64-BMI2-LABEL: rotr32_xor31:
+; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movl %esi, %ecx
+; X64-BMI2-NEXT: movl %edi, %eax
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-BMI2-NEXT: rorl %cl, %eax
+; X64-BMI2-NEXT: retq
+ %adj = xor i32 %cnt, 31
+ %r = call i32 @llvm.fshr.i32(i32 %val, i32 %val, i32 %adj)
+ ret i32 %r
+}
+
diff --git a/llvm/test/CodeGen/X86/shift-amount-mod.ll b/llvm/test/CodeGen/X86/shift-amount-mod.ll
index 9f7ac748c47e1..26abba6c2ae53 100644
--- a/llvm/test/CodeGen/X86/shift-amount-mod.ll
+++ b/llvm/test/CodeGen/X86/shift-amount-mod.ll
@@ -1574,3 +1574,208 @@ define i16 @sh_trunc_sh(i64 %x) {
%r = lshr i16 %t, 12
ret i16 %r
}
+
+;==============================================================================;
+; Funnel shift (FSHL/FSHR) count canonicalizations
+; - Test that the same shift-amount transforms (negation, add/sub by bitwidth)
+; are applied to funnel shifts on X86.
+;==============================================================================;
+
+declare i32 @llvm.fshl.i32(i32, i32, i32)
+declare i64 @llvm.fshl.i64(i64, i64, i64)
+declare i32 @llvm.fshr.i32(i32, i32, i32)
+declare i64 @llvm.fshr.i64(i64, i64, i64)
+
+; CHECK-LABEL: fshl32_by_negated:
+define i32 @fshl32_by_negated(i32 %x, i32 %shamt) {
+; X86-LABEL: fshl32_by_negated:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl $32, %ecx
+; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NEXT: roll %cl, %eax
+; X86-NEXT: retl
+;
+; X64-LABEL: fshl32_by_negated:
+; X64: # %bb.0:
+; X64-NEXT: movl %edi, %eax
+; X64-NEXT: movl $32, %ecx
+; X64-NEXT: subl %esi, %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: roll %cl, %eax
+; X64-NEXT: retq
+ %neg = sub i32 32, %shamt
+ %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %neg)
+ ret i32 %r
+}
+
+; CHECK-LABEL: fshr32_by_negated:
+define i32 @fshr32_by_negated(i32 %x, i32 %shamt) {
+; X86-LABEL: fshr32_by_negated:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl $32, %ecx
+; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NEXT: rorl %cl, %eax
+; X86-NEXT: retl
+;
+; X64-LABEL: fshr32_by_negated:
+; X64: # %bb.0:
+; X64-NEXT: movl %edi, %eax
+; X64-NEXT: movl $32, %ecx
+; X64-NEXT: subl %esi, %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: rorl %cl, %eax
+; X64-NEXT: retq
+ %neg = sub i32 32, %shamt
+ %r = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %neg)
+ ret i32 %r
+}
+
+; CHECK-LABEL: fshl64_by_negated:
+define i64 @fshl64_by_negated(i64 %x, i64 %shamt) {
+; X86-LABEL: fshl64_by_negated:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl $64, %ecx
+; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: testb $32, %cl
+; X86-NEXT: jne .LBB53_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: movl %eax, %edx
+; X86-NEXT: jmp .LBB53_3
+; X86-NEXT: .LBB53_1:
+; X86-NEXT: movl %esi, %edx
+; X86-NEXT: movl %eax, %esi
+; X86-NEXT: .LBB53_3:
+; X86-NEXT: movl %esi, %eax
+; X86-NEXT: shldl %cl, %edx, %eax
+; X86-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NEXT: shldl %cl, %esi, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
+;
+; X64-LABEL: fshl64_by_negated:
+; X64: # %bb.0:
+; X64-NEXT: movq %rdi, %rax
+; X64-NEXT: movl $64, %ecx
+; X64-NEXT: subl %esi, %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: rolq %cl, %rax
+; X64-NEXT: retq
+ %neg = sub i64 64, %shamt
+ %r = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %neg)
+ ret i64 %r
+}
+
+; CHECK-LABEL: fshr64_by_negated:
+define i64 @fshr64_by_negated(i64 %x, i64 %shamt) {
+; X86-LABEL: fshr64_by_negated:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl $64, %ecx
+; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: testb $32, %cl
+; X86-NEXT: je .LBB54_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: movl %eax, %edx
+; X86-NEXT: jmp .LBB54_3
+; X86-NEXT: .LBB54_1:
+; X86-NEXT: movl %esi, %edx
+; X86-NEXT: movl %eax, %esi
+; X86-NEXT: .LBB54_3:
+; X86-NEXT: movl %esi, %eax
+; X86-NEXT: shrdl %cl, %edx, %eax
+; X86-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NEXT: shrdl %cl, %esi, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
+;
+; X64-LABEL: fshr64_by_negated:
+; X64: # %bb.0:
+; X64-NEXT: movq %rdi, %rax
+; X64-NEXT: movl $64, %ecx
+; X64-NEXT: subl %esi, %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: rorq %cl, %rax
+; X64-NEXT: retq
+ %neg = sub i64 64, %shamt
+ %r = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %neg)
+ ret i64 %r
+}
+
+; CHECK-LABEL: fshl32_add_k:
+define i32 @fshl32_add_k(i32 %x, i32 %shamt) {
+; X86-LABEL: fshl32_add_k:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: addl $32, %ecx
+; X86-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NEXT: roll %cl, %eax
+; X86-NEXT: retl
+;
+; X64-LABEL: fshl32_add_k:
+; X64: # %bb.0:
+; X64-NEXT: # kill: def $esi killed $esi def $rsi
+; X64-NEXT: movl %edi, %eax
+; X64-NEXT: leal 32(%rsi), %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: roll %cl, %eax
+; X64-NEXT: retq
+ %k = add i32 %shamt, 32
+ %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %k)
+ ret i32 %r
+}
+
+; CHECK-LABEL: fshr64_sub_k:
+define i64 @fshr64_sub_k(i64 %x, i64 %shamt) {
+; X86-LABEL: fshr64_sub_k:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: addl $-64, %ecx
+; X86-NEXT: testb $32, %cl
+; X86-NEXT: je .LBB56_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: movl %eax, %edx
+; X86-NEXT: jmp .LBB56_3
+; X86-NEXT: .LBB56_1:
+; X86-NEXT: movl %esi, %edx
+; X86-NEXT: movl %eax, %esi
+; X86-NEXT: .LBB56_3:
+; X86-NEXT: movl %esi, %eax
+; X86-NEXT: shrdl %cl, %edx, %eax
+; X86-NEXT: # kill: def $cl killed $cl killed $ecx
+; X86-NEXT: shrdl %cl, %esi, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
+;
+; X64-LABEL: fshr64_sub_k:
+; X64: # %bb.0:
+; X64-NEXT: movq %rdi, %rax
+; X64-NEXT: leal -64(%rsi), %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: rorq %cl, %rax
+; X64-NEXT: retq
+ %k = sub i64 %shamt, 64
+ %r = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %k)
+ ret i64 %r
+}
>From 16f712cb9cff67009c1e7608932d272cb0304fde Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Wed, 3 Sep 2025 10:39:35 -0400
Subject: [PATCH 2/2] [X86] Allow rotate to be affected by shifts too.
The rotate uses the bottom 5 bits, so we can apply the same modulo we have here too.
---
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 2 ++
llvm/test/CodeGen/X86/not-shift.ll | 24 ++++++++---------
llvm/test/CodeGen/X86/shift-amount-mod.ll | 32 +++++++++++------------
3 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 62073ec125e8f..36774b93e9a61 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -5464,6 +5464,8 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
[[fallthrough]];
case ISD::SRA:
case ISD::SHL:
+ case ISD::ROTR:
+ case ISD::ROTL:
if (tryShiftAmountMod(Node))
return;
break;
diff --git a/llvm/test/CodeGen/X86/not-shift.ll b/llvm/test/CodeGen/X86/not-shift.ll
index 64b361f123239..0173058449071 100644
--- a/llvm/test/CodeGen/X86/not-shift.ll
+++ b/llvm/test/CodeGen/X86/not-shift.ll
@@ -1047,19 +1047,19 @@ define i64 @rotl64_sub63(i64 %val, i64 %cnt) nounwind {
;
; X64-NOBMI2-LABEL: rotl64_sub63:
; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rsi, %rcx
; X64-NOBMI2-NEXT: movq %rdi, %rax
-; X64-NOBMI2-NEXT: movl $63, %ecx
-; X64-NOBMI2-NEXT: subl %esi, %ecx
-; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NOBMI2-NEXT: rolq %cl, %rax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: rotl64_sub63:
; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rsi, %rcx
; X64-BMI2-NEXT: movq %rdi, %rax
-; X64-BMI2-NEXT: movl $63, %ecx
-; X64-BMI2-NEXT: subl %esi, %ecx
-; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-BMI2-NEXT: rolq %cl, %rax
; X64-BMI2-NEXT: retq
%adj = sub i64 63, %cnt
@@ -1117,19 +1117,19 @@ define i64 @rotr64_sub63(i64 %val, i64 %cnt) nounwind {
;
; X64-NOBMI2-LABEL: rotr64_sub63:
; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rsi, %rcx
; X64-NOBMI2-NEXT: movq %rdi, %rax
-; X64-NOBMI2-NEXT: movl $63, %ecx
-; X64-NOBMI2-NEXT: subl %esi, %ecx
-; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI2-NEXT: notl %ecx
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NOBMI2-NEXT: rorq %cl, %rax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: rotr64_sub63:
; X64-BMI2: # %bb.0:
+; X64-BMI2-NEXT: movq %rsi, %rcx
; X64-BMI2-NEXT: movq %rdi, %rax
-; X64-BMI2-NEXT: movl $63, %ecx
-; X64-BMI2-NEXT: subl %esi, %ecx
-; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-BMI2-NEXT: notl %ecx
+; X64-BMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-BMI2-NEXT: rorq %cl, %rax
; X64-BMI2-NEXT: retq
%adj = sub i64 63, %cnt
diff --git a/llvm/test/CodeGen/X86/shift-amount-mod.ll b/llvm/test/CodeGen/X86/shift-amount-mod.ll
index 26abba6c2ae53..34954c65aa299 100644
--- a/llvm/test/CodeGen/X86/shift-amount-mod.ll
+++ b/llvm/test/CodeGen/X86/shift-amount-mod.ll
@@ -1591,7 +1591,7 @@ define i32 @fshl32_by_negated(i32 %x, i32 %shamt) {
; X86-LABEL: fshl32_by_negated:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl $32, %ecx
+; X86-NEXT: xorl %ecx, %ecx
; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: # kill: def $cl killed $cl killed $ecx
; X86-NEXT: roll %cl, %eax
@@ -1599,9 +1599,9 @@ define i32 @fshl32_by_negated(i32 %x, i32 %shamt) {
;
; X64-LABEL: fshl32_by_negated:
; X64: # %bb.0:
+; X64-NEXT: movl %esi, %ecx
; X64-NEXT: movl %edi, %eax
-; X64-NEXT: movl $32, %ecx
-; X64-NEXT: subl %esi, %ecx
+; X64-NEXT: negl %ecx
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: roll %cl, %eax
; X64-NEXT: retq
@@ -1615,7 +1615,7 @@ define i32 @fshr32_by_negated(i32 %x, i32 %shamt) {
; X86-LABEL: fshr32_by_negated:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl $32, %ecx
+; X86-NEXT: xorl %ecx, %ecx
; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: # kill: def $cl killed $cl killed $ecx
; X86-NEXT: rorl %cl, %eax
@@ -1623,9 +1623,9 @@ define i32 @fshr32_by_negated(i32 %x, i32 %shamt) {
;
; X64-LABEL: fshr32_by_negated:
; X64: # %bb.0:
+; X64-NEXT: movl %esi, %ecx
; X64-NEXT: movl %edi, %eax
-; X64-NEXT: movl $32, %ecx
-; X64-NEXT: subl %esi, %ecx
+; X64-NEXT: negl %ecx
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: rorl %cl, %eax
; X64-NEXT: retq
@@ -1664,10 +1664,10 @@ define i64 @fshl64_by_negated(i64 %x, i64 %shamt) {
;
; X64-LABEL: fshl64_by_negated:
; X64: # %bb.0:
+; X64-NEXT: movq %rsi, %rcx
; X64-NEXT: movq %rdi, %rax
-; X64-NEXT: movl $64, %ecx
-; X64-NEXT: subl %esi, %ecx
-; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: negl %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NEXT: rolq %cl, %rax
; X64-NEXT: retq
%neg = sub i64 64, %shamt
@@ -1705,10 +1705,10 @@ define i64 @fshr64_by_negated(i64 %x, i64 %shamt) {
;
; X64-LABEL: fshr64_by_negated:
; X64: # %bb.0:
+; X64-NEXT: movq %rsi, %rcx
; X64-NEXT: movq %rdi, %rax
-; X64-NEXT: movl $64, %ecx
-; X64-NEXT: subl %esi, %ecx
-; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: negl %ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NEXT: rorq %cl, %rax
; X64-NEXT: retq
%neg = sub i64 64, %shamt
@@ -1722,16 +1722,14 @@ define i32 @fshl32_add_k(i32 %x, i32 %shamt) {
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: addl $32, %ecx
; X86-NEXT: # kill: def $cl killed $cl killed $ecx
; X86-NEXT: roll %cl, %eax
; X86-NEXT: retl
;
; X64-LABEL: fshl32_add_k:
; X64: # %bb.0:
-; X64-NEXT: # kill: def $esi killed $esi def $rsi
+; X64-NEXT: movl %esi, %ecx
; X64-NEXT: movl %edi, %eax
-; X64-NEXT: leal 32(%rsi), %ecx
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: roll %cl, %eax
; X64-NEXT: retq
@@ -1770,9 +1768,9 @@ define i64 @fshr64_sub_k(i64 %x, i64 %shamt) {
;
; X64-LABEL: fshr64_sub_k:
; X64: # %bb.0:
+; X64-NEXT: movq %rsi, %rcx
; X64-NEXT: movq %rdi, %rax
-; X64-NEXT: leal -64(%rsi), %ecx
-; X64-NEXT: # kill: def $cl killed $cl killed $ecx
+; X64-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NEXT: rorq %cl, %rax
; X64-NEXT: retq
%k = sub i64 %shamt, 64
More information about the llvm-commits
mailing list