blob: c705505bbbf2a659e10b544b4d10c852a467f3ce [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X64
define i32 @test_simple_rotl(i32 %x) {
; X86-LABEL: test_simple_rotl:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: roll $7, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_simple_rotl:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: roll $7, %eax
; X64-NEXT: retq
%shl = shl i32 %x, 7
%shr = lshr i32 %x, 25
%add = add i32 %shl, %shr
ret i32 %add
}
define i32 @test_simple_rotr(i32 %x) {
; X86-LABEL: test_simple_rotr:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: roll $25, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_simple_rotr:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: roll $25, %eax
; X64-NEXT: retq
%shr = lshr i32 %x, 7
%shl = shl i32 %x, 25
%add = add i32 %shr, %shl
ret i32 %add
}
define i32 @test_rotl_var(i32 %x, i32 %y) {
; X86-LABEL: test_rotl_var:
; X86: # %bb.0:
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: roll %cl, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_rotl_var:
; X64: # %bb.0:
; X64-NEXT: movl %esi, %ecx
; X64-NEXT: movl %edi, %eax
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: roll %cl, %eax
; X64-NEXT: retq
%shl = shl i32 %x, %y
%sub = sub i32 32, %y
%shr = lshr i32 %x, %sub
%add = add i32 %shl, %shr
ret i32 %add
}
define i32 @test_rotr_var(i32 %x, i32 %y) {
; X86-LABEL: test_rotr_var:
; X86: # %bb.0:
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: rorl %cl, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_rotr_var:
; X64: # %bb.0:
; X64-NEXT: movl %esi, %ecx
; X64-NEXT: movl %edi, %eax
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: rorl %cl, %eax
; X64-NEXT: retq
%shr = lshr i32 %x, %y
%sub = sub i32 32, %y
%shl = shl i32 %x, %sub
%add = add i32 %shr, %shl
ret i32 %add
}
define i32 @test_invalid_rotl_var_and(i32 %x, i32 %y) {
; X86-LABEL: test_invalid_rotl_var_and:
; X86: # %bb.0:
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: movl %eax, %edx
; X86-NEXT: shll %cl, %edx
; X86-NEXT: negb %cl
; X86-NEXT: shrl %cl, %eax
; X86-NEXT: addl %edx, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_invalid_rotl_var_and:
; X64: # %bb.0:
; X64-NEXT: movl %esi, %ecx
; X64-NEXT: movl %edi, %eax
; X64-NEXT: shll %cl, %eax
; X64-NEXT: negb %cl
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shrl %cl, %edi
; X64-NEXT: addl %edi, %eax
; X64-NEXT: retq
%shr = shl i32 %x, %y
%sub = sub nsw i32 0, %y
%and = and i32 %sub, 31
%shl = lshr i32 %x, %and
%add = add i32 %shl, %shr
ret i32 %add
}
define i32 @test_invalid_rotr_var_and(i32 %x, i32 %y) {
; X86-LABEL: test_invalid_rotr_var_and:
; X86: # %bb.0:
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: movl %eax, %edx
; X86-NEXT: shrl %cl, %edx
; X86-NEXT: negb %cl
; X86-NEXT: shll %cl, %eax
; X86-NEXT: addl %edx, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_invalid_rotr_var_and:
; X64: # %bb.0:
; X64-NEXT: movl %esi, %ecx
; X64-NEXT: movl %edi, %eax
; X64-NEXT: shrl %cl, %eax
; X64-NEXT: negb %cl
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shll %cl, %edi
; X64-NEXT: addl %edi, %eax
; X64-NEXT: retq
%shr = lshr i32 %x, %y
%sub = sub nsw i32 0, %y
%and = and i32 %sub, 31
%shl = shl i32 %x, %and
%add = add i32 %shr, %shl
ret i32 %add
}
define i32 @test_fshl_special_case(i32 %x0, i32 %x1, i32 %y) {
; X86-LABEL: test_fshl_special_case:
; X86: # %bb.0:
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: shldl %cl, %edx, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_fshl_special_case:
; X64: # %bb.0:
; X64-NEXT: movl %edx, %ecx
; X64-NEXT: movl %edi, %eax
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shldl %cl, %esi, %eax
; X64-NEXT: retq
%shl = shl i32 %x0, %y
%srli = lshr i32 %x1, 1
%x = xor i32 %y, 31
%srlo = lshr i32 %srli, %x
%o = add i32 %shl, %srlo
ret i32 %o
}
define i32 @test_fshr_special_case(i32 %x0, i32 %x1, i32 %y) {
; X86-LABEL: test_fshr_special_case:
; X86: # %bb.0:
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: shrdl %cl, %edx, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_fshr_special_case:
; X64: # %bb.0:
; X64-NEXT: movl %edx, %ecx
; X64-NEXT: movl %esi, %eax
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shrdl %cl, %edi, %eax
; X64-NEXT: retq
%shl = lshr i32 %x1, %y
%srli = shl i32 %x0, 1
%x = xor i32 %y, 31
%srlo = shl i32 %srli, %x
%o = add i32 %shl, %srlo
ret i32 %o
}
define i64 @test_rotl_udiv_special_case(i64 %i) {
; X86-LABEL: test_rotl_udiv_special_case:
; X86: # %bb.0:
; X86-NEXT: pushl %ebx
; X86-NEXT: .cfi_def_cfa_offset 8
; X86-NEXT: pushl %edi
; X86-NEXT: .cfi_def_cfa_offset 12
; X86-NEXT: pushl %esi
; X86-NEXT: .cfi_def_cfa_offset 16
; X86-NEXT: .cfi_offset %esi, -16
; X86-NEXT: .cfi_offset %edi, -12
; X86-NEXT: .cfi_offset %ebx, -8
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
; X86-NEXT: movl %ecx, %esi
; X86-NEXT: addl %edi, %esi
; X86-NEXT: adcl $0, %esi
; X86-NEXT: movl $-1431655765, %ebx # imm = 0xAAAAAAAB
; X86-NEXT: movl %esi, %eax
; X86-NEXT: mull %ebx
; X86-NEXT: shrl %edx
; X86-NEXT: leal (%edx,%edx,2), %eax
; X86-NEXT: subl %eax, %esi
; X86-NEXT: subl %esi, %ecx
; X86-NEXT: sbbl $0, %edi
; X86-NEXT: movl %ecx, %eax
; X86-NEXT: mull %ebx
; X86-NEXT: imull $-1431655766, %ecx, %ecx # imm = 0xAAAAAAAA
; X86-NEXT: addl %ecx, %edx
; X86-NEXT: imull $-1431655765, %edi, %ecx # imm = 0xAAAAAAAB
; X86-NEXT: addl %ecx, %edx
; X86-NEXT: movl %edx, %ecx
; X86-NEXT: shldl $28, %eax, %ecx
; X86-NEXT: shrdl $4, %eax, %edx
; X86-NEXT: movl %ecx, %eax
; X86-NEXT: popl %esi
; X86-NEXT: .cfi_def_cfa_offset 12
; X86-NEXT: popl %edi
; X86-NEXT: .cfi_def_cfa_offset 8
; X86-NEXT: popl %ebx
; X86-NEXT: .cfi_def_cfa_offset 4
; X86-NEXT: retl
;
; X64-LABEL: test_rotl_udiv_special_case:
; X64: # %bb.0:
; X64-NEXT: movq %rdi, %rax
; X64-NEXT: movabsq $-6148914691236517205, %rcx # imm = 0xAAAAAAAAAAAAAAAB
; X64-NEXT: mulq %rcx
; X64-NEXT: movq %rdx, %rax
; X64-NEXT: shrq %rax
; X64-NEXT: rolq $60, %rax
; X64-NEXT: retq
%lhs_div = udiv i64 %i, 3
%rhs_div = udiv i64 %i, 48
%lhs_shift = shl i64 %lhs_div, 60
%out = add i64 %lhs_shift, %rhs_div
ret i64 %out
}
define i32 @test_rotl_mul_special_case(i32 %i) {
; X86-LABEL: test_rotl_mul_special_case:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: leal (%eax,%eax,8), %eax
; X86-NEXT: roll $7, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_rotl_mul_special_case:
; X64: # %bb.0:
; X64-NEXT: # kill: def $edi killed $edi def $rdi
; X64-NEXT: leal (%rdi,%rdi,8), %eax
; X64-NEXT: roll $7, %eax
; X64-NEXT: retq
%lhs_mul = mul i32 %i, 9
%rhs_mul = mul i32 %i, 1152
%lhs_shift = lshr i32 %lhs_mul, 25
%out = add i32 %lhs_shift, %rhs_mul
ret i32 %out
}
define i64 @test_rotl_mul_with_mask_special_case(i64 %i) {
; X86-LABEL: test_rotl_mul_with_mask_special_case:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: leal (%eax,%eax,8), %ecx
; X86-NEXT: movl $9, %eax
; X86-NEXT: mull {{[0-9]+}}(%esp)
; X86-NEXT: addl %ecx, %edx
; X86-NEXT: shrdl $25, %eax, %edx
; X86-NEXT: movzbl %dl, %eax
; X86-NEXT: xorl %edx, %edx
; X86-NEXT: retl
;
; X64-LABEL: test_rotl_mul_with_mask_special_case:
; X64: # %bb.0:
; X64-NEXT: leaq (%rdi,%rdi,8), %rax
; X64-NEXT: # kill: def $edi killed $edi killed $rdi def $rdi
; X64-NEXT: shll $7, %edi
; X64-NEXT: leal (%rdi,%rdi,8), %ecx
; X64-NEXT: movzbl %cl, %ecx
; X64-NEXT: shrq $57, %rax
; X64-NEXT: orq %rcx, %rax
; X64-NEXT: retq
%lhs_mul = mul i64 %i, 1152
%rhs_mul = mul i64 %i, 9
%lhs_and = and i64 %lhs_mul, 160
%rhs_shift = lshr i64 %rhs_mul, 57
%out = add i64 %lhs_and, %rhs_shift
ret i64 %out
}
define i32 @test_fshl_with_mask_special_case(i32 %x) {
; X86-LABEL: test_fshl_with_mask_special_case:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl %ecx, %eax
; X86-NEXT: orl $1, %eax
; X86-NEXT: shldl $5, %ecx, %eax
; X86-NEXT: andl $-31, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_fshl_with_mask_special_case:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: orl $1, %eax
; X64-NEXT: shldl $5, %edi, %eax
; X64-NEXT: andl $-31, %eax
; X64-NEXT: retq
%or1 = or i32 %x, 1
%sh1 = shl i32 %or1, 5
%sh2 = lshr i32 %x, 27
%1 = and i32 %sh2, 1
%r = add i32 %sh1, %1
ret i32 %r
}