forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			1577 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			1577 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			LLVM
		
	
	
	
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 | 
						|
; RUN: llc < %s -mtriple=i686-unknown-unknown   | FileCheck %s --check-prefixes=ALL,X32
 | 
						|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=ALL,X64
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; the shift amount is negated (shiftbitwidth - shiftamt)
 | 
						|
;==============================================================================;
 | 
						|
 | 
						|
; shift left
 | 
						|
;------------------------------------------------------------------------------;
 | 
						|
 | 
						|
define i32 @reg32_shl_by_negated(i32 %val, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg32_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shll %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shll %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = shl i32 %val, %negshamt
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i32 @load32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: load32_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl (%eax), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shll %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: load32_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl (%rdi), %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shll %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i32, i32* %valptr
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = shl i32 %val, %negshamt
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define void @store32_shl_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: store32_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shll %cl, %edx
 | 
						|
; X32-NEXT:    movl %edx, (%eax)
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: store32_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %edx, %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shll %cl, %edi
 | 
						|
; X64-NEXT:    movl %edi, (%rsi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = shl i32 %val, %negshamt
 | 
						|
  store i32 %shifted, i32* %dstptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
define void @modify32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: modify32_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movb $32, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    shll %cl, (%eax)
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: modify32_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movb $32, %cl
 | 
						|
; X64-NEXT:    subb %sil, %cl
 | 
						|
; X64-NEXT:    shll %cl, (%rdi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i32, i32* %valptr
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = shl i32 %val, %negshamt
 | 
						|
  store i32 %shifted, i32* %valptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define i64 @reg64_shl_by_negated(i64 %val, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg64_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %esi, %eax
 | 
						|
; X32-NEXT:    shll %cl, %eax
 | 
						|
; X32-NEXT:    shldl %cl, %esi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB4_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %eax, %edx
 | 
						|
; X32-NEXT:    xorl %eax, %eax
 | 
						|
; X32-NEXT:  .LBB4_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shlq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = shl i64 %val, %negshamt
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
define i64 @load64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: load64_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl (%eax), %esi
 | 
						|
; X32-NEXT:    movl 4(%eax), %edx
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %esi, %eax
 | 
						|
; X32-NEXT:    shll %cl, %eax
 | 
						|
; X32-NEXT:    shldl %cl, %esi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB5_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %eax, %edx
 | 
						|
; X32-NEXT:    xorl %eax, %eax
 | 
						|
; X32-NEXT:  .LBB5_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: load64_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq (%rdi), %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shlq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i64, i64* %valptr
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = shl i64 %val, %negshamt
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
define void @store64_shl_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: store64_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %edi
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:    shll %cl, %esi
 | 
						|
; X32-NEXT:    shldl %cl, %edi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB6_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    xorl %esi, %esi
 | 
						|
; X32-NEXT:  .LBB6_2:
 | 
						|
; X32-NEXT:    movl %edx, 4(%eax)
 | 
						|
; X32-NEXT:    movl %esi, (%eax)
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    popl %edi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: store64_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdx, %rcx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shlq %cl, %rdi
 | 
						|
; X64-NEXT:    movq %rdi, (%rsi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = shl i64 %val, %negshamt
 | 
						|
  store i64 %shifted, i64* %dstptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
define void @modify64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: modify64_shl_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %edi
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl (%eax), %edi
 | 
						|
; X32-NEXT:    movl 4(%eax), %edx
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:    shll %cl, %esi
 | 
						|
; X32-NEXT:    shldl %cl, %edi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB7_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    xorl %esi, %esi
 | 
						|
; X32-NEXT:  .LBB7_2:
 | 
						|
; X32-NEXT:    movl %esi, (%eax)
 | 
						|
; X32-NEXT:    movl %edx, 4(%eax)
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    popl %edi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: modify64_shl_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movb $64, %cl
 | 
						|
; X64-NEXT:    subb %sil, %cl
 | 
						|
; X64-NEXT:    shlq %cl, (%rdi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i64, i64* %valptr
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = shl i64 %val, %negshamt
 | 
						|
  store i64 %shifted, i64* %valptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; logical shift right
 | 
						|
;------------------------------------------------------------------------------;
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_negated(i32 %val, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = lshr i32 %val, %negshamt
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i32 @load32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: load32_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl (%eax), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: load32_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl (%rdi), %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i32, i32* %valptr
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = lshr i32 %val, %negshamt
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define void @store32_lshr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: store32_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    movl %edx, (%eax)
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: store32_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %edx, %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %edi
 | 
						|
; X64-NEXT:    movl %edi, (%rsi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = lshr i32 %val, %negshamt
 | 
						|
  store i32 %shifted, i32* %dstptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
define void @modify32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: modify32_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movb $32, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    shrl %cl, (%eax)
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: modify32_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movb $32, %cl
 | 
						|
; X64-NEXT:    subb %sil, %cl
 | 
						|
; X64-NEXT:    shrl %cl, (%rdi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i32, i32* %valptr
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = lshr i32 %val, %negshamt
 | 
						|
  store i32 %shifted, i32* %valptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define i64 @reg64_lshr_by_negated(i64 %val, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB12_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB12_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = lshr i64 %val, %negshamt
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
define i64 @load64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: load64_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    movl (%ecx), %eax
 | 
						|
; X32-NEXT:    movl 4(%ecx), %esi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB13_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB13_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: load64_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq (%rdi), %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i64, i64* %valptr
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = lshr i64 %val, %negshamt
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
define void @store64_lshr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: store64_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %edi
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:    shrl %cl, %esi
 | 
						|
; X32-NEXT:    shrdl %cl, %edi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB14_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    xorl %esi, %esi
 | 
						|
; X32-NEXT:  .LBB14_2:
 | 
						|
; X32-NEXT:    movl %esi, 4(%eax)
 | 
						|
; X32-NEXT:    movl %edx, (%eax)
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    popl %edi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: store64_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdx, %rcx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rdi
 | 
						|
; X64-NEXT:    movq %rdi, (%rsi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = lshr i64 %val, %negshamt
 | 
						|
  store i64 %shifted, i64* %dstptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
define void @modify64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: modify64_lshr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %edi
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl (%eax), %edx
 | 
						|
; X32-NEXT:    movl 4(%eax), %edi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:    shrl %cl, %esi
 | 
						|
; X32-NEXT:    shrdl %cl, %edi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB15_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    xorl %esi, %esi
 | 
						|
; X32-NEXT:  .LBB15_2:
 | 
						|
; X32-NEXT:    movl %edx, (%eax)
 | 
						|
; X32-NEXT:    movl %esi, 4(%eax)
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    popl %edi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: modify64_lshr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movb $64, %cl
 | 
						|
; X64-NEXT:    subb %sil, %cl
 | 
						|
; X64-NEXT:    shrq %cl, (%rdi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i64, i64* %valptr
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = lshr i64 %val, %negshamt
 | 
						|
  store i64 %shifted, i64* %valptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; arithmetic shift right
 | 
						|
;------------------------------------------------------------------------------;
 | 
						|
 | 
						|
define i32 @reg32_ashr_by_negated(i32 %val, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg32_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    sarl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    sarl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = ashr i32 %val, %negshamt
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i32 @load32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: load32_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl (%eax), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    sarl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: load32_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl (%rdi), %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    sarl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i32, i32* %valptr
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = ashr i32 %val, %negshamt
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define void @store32_ashr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: store32_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    sarl %cl, %edx
 | 
						|
; X32-NEXT:    movl %edx, (%eax)
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: store32_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %edx, %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    sarl %cl, %edi
 | 
						|
; X64-NEXT:    movl %edi, (%rsi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = ashr i32 %val, %negshamt
 | 
						|
  store i32 %shifted, i32* %dstptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
define void @modify32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: modify32_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movb $32, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    sarl %cl, (%eax)
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: modify32_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movb $32, %cl
 | 
						|
; X64-NEXT:    subb %sil, %cl
 | 
						|
; X64-NEXT:    sarl %cl, (%rdi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i32, i32* %valptr
 | 
						|
  %negshamt = sub i32 32, %shamt
 | 
						|
  %shifted = ashr i32 %val, %negshamt
 | 
						|
  store i32 %shifted, i32* %valptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define i64 @reg64_ashr_by_negated(i64 %val, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg64_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    sarl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB20_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    sarl $31, %esi
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:  .LBB20_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    sarq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = ashr i64 %val, %negshamt
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
define i64 @load64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: load64_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    movl (%ecx), %eax
 | 
						|
; X32-NEXT:    movl 4(%ecx), %esi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    sarl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB21_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    sarl $31, %esi
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:  .LBB21_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: load64_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq (%rdi), %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    sarq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i64, i64* %valptr
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = ashr i64 %val, %negshamt
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
define void @store64_ashr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: store64_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %edi
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:    sarl %cl, %esi
 | 
						|
; X32-NEXT:    shrdl %cl, %edi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB22_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    sarl $31, %edi
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:  .LBB22_2:
 | 
						|
; X32-NEXT:    movl %esi, 4(%eax)
 | 
						|
; X32-NEXT:    movl %edx, (%eax)
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    popl %edi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: store64_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdx, %rcx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    sarq %cl, %rdi
 | 
						|
; X64-NEXT:    movq %rdi, (%rsi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = ashr i64 %val, %negshamt
 | 
						|
  store i64 %shifted, i64* %dstptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
define void @modify64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: modify64_ashr_by_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %edi
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl (%eax), %edx
 | 
						|
; X32-NEXT:    movl 4(%eax), %edi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:    sarl %cl, %esi
 | 
						|
; X32-NEXT:    shrdl %cl, %edi, %edx
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB23_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    sarl $31, %edi
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    movl %edi, %esi
 | 
						|
; X32-NEXT:  .LBB23_2:
 | 
						|
; X32-NEXT:    movl %edx, (%eax)
 | 
						|
; X32-NEXT:    movl %esi, 4(%eax)
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    popl %edi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: modify64_ashr_by_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movb $64, %cl
 | 
						|
; X64-NEXT:    subb %sil, %cl
 | 
						|
; X64-NEXT:    sarq %cl, (%rdi)
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %val = load i64, i64* %valptr
 | 
						|
  %negshamt = sub i64 64, %shamt
 | 
						|
  %shifted = ashr i64 %val, %negshamt
 | 
						|
  store i64 %shifted, i64* %valptr
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
 | 
						|
; next let's only test simple reg pattern, and only lshr.
 | 
						|
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; subtraction from negated shift amount
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_sub_from_negated(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_sub_from_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    negb %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_sub_from_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 | 
						|
; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    leal (%rsi,%rdx), %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 32, %a
 | 
						|
  %negasubb = sub i32 %nega, %b
 | 
						|
  %shifted = lshr i32 %val, %negasubb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_sub_from_negated(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_sub_from_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb %dl, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB25_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB25_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_sub_from_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    leal (%rdx,%rsi), %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 64, %a
 | 
						|
  %negasubb = sub i64 %nega, %b
 | 
						|
  %shifted = lshr i64 %val, %negasubb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; subtraction of negated shift amount
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_sub_of_negated(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_sub_of_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_sub_of_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 | 
						|
; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    leal (%rsi,%rdx), %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 32, %a
 | 
						|
  %negasubb = sub i32 %b, %nega
 | 
						|
  %shifted = lshr i32 %val, %negasubb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_sub_of_negated(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_sub_of_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addb $-64, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB27_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB27_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_sub_of_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    leal (%rdx,%rsi), %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 64, %a
 | 
						|
  %negasubb = sub i64 %b, %nega
 | 
						|
  %shifted = lshr i64 %val, %negasubb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; add to negated shift amount
 | 
						|
;
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_add_to_negated(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_add_to_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_add_to_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %edx, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 32, %a
 | 
						|
  %negasubb = add i32 %nega, %b
 | 
						|
  %shifted = lshr i32 %val, %negasubb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_add_to_negated(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_add_to_negated:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addb $64, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB29_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB29_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_add_to_negated:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdx, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 64, %a
 | 
						|
  %negasubb = add i64 %nega, %b
 | 
						|
  %shifted = lshr i64 %val, %negasubb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; subtraction of negated shift amounts
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_sub_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_sub_of_negated_amts:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_sub_of_negated_amts:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %edx, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 32, %a
 | 
						|
  %negb = sub i32 32, %b
 | 
						|
  %negasubnegb = sub i32 %nega, %negb
 | 
						|
  %shifted = lshr i32 %val, %negasubnegb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_sub_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_sub_of_negated_amts:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB31_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB31_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_sub_of_negated_amts:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdx, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 64, %a
 | 
						|
  %negb = sub i64 64, %b
 | 
						|
  %negasubnegb = sub i64 %nega, %negb
 | 
						|
  %shifted = lshr i64 %val, %negasubnegb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; addition of negated shift amounts
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_add_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_add_of_negated_amts:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    negb %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_add_of_negated_amts:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 | 
						|
; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    leal (%rsi,%rdx), %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 32, %a
 | 
						|
  %negb = sub i32 32, %b
 | 
						|
  %negasubnegb = add i32 %nega, %negb
 | 
						|
  %shifted = lshr i32 %val, %negasubnegb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_add_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_add_of_negated_amts:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    movb $-128, %cl
 | 
						|
; X32-NEXT:    subb %dl, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB33_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB33_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_add_of_negated_amts:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    leal (%rdx,%rsi), %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 64, %a
 | 
						|
  %negb = sub i64 64, %b
 | 
						|
  %negasubnegb = add i64 %nega, %negb
 | 
						|
  %shifted = lshr i64 %val, %negasubnegb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; and patterns with an actual negation+addition
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_negated_unfolded(i32 %val, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 0, %shamt
 | 
						|
  %negaaddbitwidth = add i32 %negshamt, 32
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidth
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_negated_unfolded(i64 %val, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB35_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB35_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 0, %shamt
 | 
						|
  %negaaddbitwidth = add i64 %negshamt, 64
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidth
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    negb %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 | 
						|
; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    leal (%rsi,%rdx), %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 0, %a
 | 
						|
  %negaaddbitwidth = add i32 %nega, 32
 | 
						|
  %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidthsubb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    movb $64, %cl
 | 
						|
; X32-NEXT:    subb %dl, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB37_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB37_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    leal (%rdx,%rsi), %ecx
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 0, %a
 | 
						|
  %negaaddbitwidth = add i64 %nega, 64
 | 
						|
  %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidthsubb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_b_sub_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_b_sub_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 | 
						|
; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    leal (%rsi,%rdx), %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 0, %a
 | 
						|
  %negaaddbitwidth = add i32 %nega, 32
 | 
						|
  %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidthsubb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_b_sub_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addb $-64, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB39_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB39_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_b_sub_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    leal (%rdx,%rsi), %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 0, %a
 | 
						|
  %negaaddbitwidth = add i64 %nega, 64
 | 
						|
  %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidthsubb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_negated_unfolded_add_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_negated_unfolded_add_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %edx, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 0, %a
 | 
						|
  %negaaddbitwidth = add i32 %nega, 32
 | 
						|
  %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidthaddb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_negated_unfolded_add_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    addb $64, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB41_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB41_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_negated_unfolded_add_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdx, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 0, %a
 | 
						|
  %negaaddbitwidth = add i64 %nega, 64
 | 
						|
  %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidthaddb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
;==============================================================================;
 | 
						|
; and patterns with an actual negation+mask
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_masked_negated_unfolded(i32 %val, i32 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_masked_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_masked_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i32 0, %shamt
 | 
						|
  %negaaddbitwidth = and i32 %negshamt, 31
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidth
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_masked_negated_unfolded(i64 %val, i64 %shamt) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_masked_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    movb {{[0-9]+}}(%esp), %dl
 | 
						|
; X32-NEXT:    subb %dl, %cl
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB43_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB43_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_masked_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negb %cl
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %negshamt = sub i64 0, %shamt
 | 
						|
  %negaaddbitwidth = and i64 %negshamt, 63
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidth
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_masked_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    andl $31, %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %esi, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negl %ecx
 | 
						|
; X64-NEXT:    andl $31, %ecx
 | 
						|
; X64-NEXT:    subl %edx, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 0, %a
 | 
						|
  %negaaddbitwidth = and i32 %nega, 31
 | 
						|
  %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidthsubb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_masked_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    andl $63, %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB45_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB45_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rsi, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negl %ecx
 | 
						|
; X64-NEXT:    andl $63, %ecx
 | 
						|
; X64-NEXT:    subl %edx, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 0, %a
 | 
						|
  %negaaddbitwidth = and i64 %nega, 63
 | 
						|
  %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidthsubb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_masked_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    andl $31, %edx
 | 
						|
; X32-NEXT:    subl %edx, %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movl %edx, %ecx
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negl %esi
 | 
						|
; X64-NEXT:    andl $31, %esi
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 0, %a
 | 
						|
  %negaaddbitwidth = and i32 %nega, 31
 | 
						|
  %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidthsubb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_masked_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx
 | 
						|
; X32-NEXT:    andl $63, %edx
 | 
						|
; X32-NEXT:    subl %edx, %ecx
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB47_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB47_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdx, %rcx
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negl %esi
 | 
						|
; X64-NEXT:    andl $63, %esi
 | 
						|
; X64-NEXT:    subl %esi, %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 0, %a
 | 
						|
  %negaaddbitwidth = and i64 %nega, 63
 | 
						|
  %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidthsubb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
define i32 @reg32_lshr_by_masked_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
 | 
						|
; X32-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    andl $31, %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X32-NEXT:    shrl %cl, %eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    # kill: def $edx killed $edx def $rdx
 | 
						|
; X64-NEXT:    # kill: def $esi killed $esi def $rsi
 | 
						|
; X64-NEXT:    movl %edi, %eax
 | 
						|
; X64-NEXT:    negl %esi
 | 
						|
; X64-NEXT:    andl $31, %esi
 | 
						|
; X64-NEXT:    leal (%rsi,%rdx), %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrl %cl, %eax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i32 0, %a
 | 
						|
  %negaaddbitwidth = and i32 %nega, 31
 | 
						|
  %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i32 %val, %negaaddbitwidthaddb
 | 
						|
  ret i32 %shifted
 | 
						|
}
 | 
						|
define i64 @reg64_lshr_by_masked_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
 | 
						|
; X32-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    pushl %esi
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 | 
						|
; X32-NEXT:    xorl %ecx, %ecx
 | 
						|
; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    andl $63, %ecx
 | 
						|
; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
 | 
						|
; X32-NEXT:    movl %esi, %edx
 | 
						|
; X32-NEXT:    shrl %cl, %edx
 | 
						|
; X32-NEXT:    shrdl %cl, %esi, %eax
 | 
						|
; X32-NEXT:    testb $32, %cl
 | 
						|
; X32-NEXT:    je .LBB49_2
 | 
						|
; X32-NEXT:  # %bb.1:
 | 
						|
; X32-NEXT:    movl %edx, %eax
 | 
						|
; X32-NEXT:    xorl %edx, %edx
 | 
						|
; X32-NEXT:  .LBB49_2:
 | 
						|
; X32-NEXT:    popl %esi
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    negl %esi
 | 
						|
; X64-NEXT:    andl $63, %esi
 | 
						|
; X64-NEXT:    leal (%rdx,%rsi), %ecx
 | 
						|
; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 | 
						|
; X64-NEXT:    shrq %cl, %rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %nega = sub i64 0, %a
 | 
						|
  %negaaddbitwidth = and i64 %nega, 63
 | 
						|
  %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
 | 
						|
  %shifted = lshr i64 %val, %negaaddbitwidthaddb
 | 
						|
  ret i64 %shifted
 | 
						|
}
 | 
						|
 | 
						|
define i16 @sh_trunc_sh(i64 %x) {
 | 
						|
; X32-LABEL: sh_trunc_sh:
 | 
						|
; X32:       # %bb.0:
 | 
						|
; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 | 
						|
; X32-NEXT:    shrl $4, %eax
 | 
						|
; X32-NEXT:    andl $15, %eax
 | 
						|
; X32-NEXT:    # kill: def $ax killed $ax killed $eax
 | 
						|
; X32-NEXT:    retl
 | 
						|
;
 | 
						|
; X64-LABEL: sh_trunc_sh:
 | 
						|
; X64:       # %bb.0:
 | 
						|
; X64-NEXT:    movq %rdi, %rax
 | 
						|
; X64-NEXT:    shrq $36, %rax
 | 
						|
; X64-NEXT:    andl $15, %eax
 | 
						|
; X64-NEXT:    # kill: def $ax killed $ax killed $rax
 | 
						|
; X64-NEXT:    retq
 | 
						|
  %s = lshr i64 %x, 24
 | 
						|
  %t = trunc i64 %s to i16
 | 
						|
  %r = lshr i16 %t, 12
 | 
						|
  ret i16 %r
 | 
						|
}
 |