mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-22 20:43:44 +02:00
3a4f22c55f
Emit SHRQ/SHLQ instead of ANDQ with a 64 bit constant mask if the result is unused and the mask has only higher/lower bits set. For example, with this patch LLVM emits shrq $41, %rdi je instead of movabsq $0xFFFFFE0000000000, %rcx testq %rcx, %rdi je This reduces number of instructions, code size and register pressure. The transformation is applied only for cases where the mask cannot be encoded as an immediate value within TESTQ instruction. Differential Revision: https://reviews.llvm.org/D28198 llvm-svn: 291806
79 lines
2.3 KiB
LLVM
79 lines
2.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; Check that 64-bit division is bypassed correctly.
|
|
; RUN: llc < %s -mattr=+idivq-to-divl -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
|
|
|
; Additional tests for 64-bit divide bypass
|
|
|
|
define i64 @Test_get_quotient(i64 %a, i64 %b) nounwind {
|
|
; CHECK-LABEL: Test_get_quotient:
|
|
; CHECK: # BB#0:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: orq %rsi, %rax
|
|
; CHECK-NEXT: shrq $32, %rax
|
|
; CHECK-NEXT: je .LBB0_1
|
|
; CHECK-NEXT: # BB#2:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: cqto
|
|
; CHECK-NEXT: idivq %rsi
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB0_1:
|
|
; CHECK-NEXT: xorl %edx, %edx
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: divl %esi
|
|
; CHECK-NEXT: # kill: %EAX<def> %EAX<kill> %RAX<def>
|
|
; CHECK-NEXT: retq
|
|
%result = sdiv i64 %a, %b
|
|
ret i64 %result
|
|
}
|
|
|
|
define i64 @Test_get_remainder(i64 %a, i64 %b) nounwind {
|
|
; CHECK-LABEL: Test_get_remainder:
|
|
; CHECK: # BB#0:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: orq %rsi, %rax
|
|
; CHECK-NEXT: shrq $32, %rax
|
|
; CHECK-NEXT: je .LBB1_1
|
|
; CHECK-NEXT: # BB#2:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: cqto
|
|
; CHECK-NEXT: idivq %rsi
|
|
; CHECK-NEXT: movq %rdx, %rax
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB1_1:
|
|
; CHECK-NEXT: xorl %edx, %edx
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: divl %esi
|
|
; CHECK-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def>
|
|
; CHECK-NEXT: movq %rdx, %rax
|
|
; CHECK-NEXT: retq
|
|
%result = srem i64 %a, %b
|
|
ret i64 %result
|
|
}
|
|
|
|
define i64 @Test_get_quotient_and_remainder(i64 %a, i64 %b) nounwind {
|
|
; CHECK-LABEL: Test_get_quotient_and_remainder:
|
|
; CHECK: # BB#0:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: orq %rsi, %rax
|
|
; CHECK-NEXT: shrq $32, %rax
|
|
; CHECK-NEXT: je .LBB2_1
|
|
; CHECK-NEXT: # BB#2:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: cqto
|
|
; CHECK-NEXT: idivq %rsi
|
|
; CHECK-NEXT: addq %rdx, %rax
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB2_1:
|
|
; CHECK-NEXT: xorl %edx, %edx
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: divl %esi
|
|
; CHECK-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def>
|
|
; CHECK-NEXT: # kill: %EAX<def> %EAX<kill> %RAX<def>
|
|
; CHECK-NEXT: addq %rdx, %rax
|
|
; CHECK-NEXT: retq
|
|
%resultdiv = sdiv i64 %a, %b
|
|
%resultrem = srem i64 %a, %b
|
|
%result = add i64 %resultdiv, %resultrem
|
|
ret i64 %result
|
|
}
|