mirror of
https://github.com/RPCS3/llvm.git
synced 2026-08-28 05:10:05 -04:00
ee18eb90ff
We've had several bugs(PR32256, PR32241) recently that resulted from usages of AH/BH/CH/DH either before or after a copy to/from a mask register. This ultimately occurs because we create COPY_TO_REGCLASS with VK1 and GR8. Then in CopyToFromAsymmetricReg in X86InstrInfo we find a 32-bit super register for the GR8 to emit the KMOV with. But as these tests are demonstrating, its possible for the GR8 register to be a high register and we end up doing an accidental extra or insert from bits 15:8. I think the best way forward is to stop making copies directly between mask registers and GR8/GR16. Instead I think we should restrict to only copies between mask registers and GR32/GR64 and use EXTRACT_SUBREG/INSERT_SUBREG to handle the conversion from GR32 to GR16/8 or vice versa. Unfortunately, this complicates fastisel a bit more now to create the subreg extracts where we used to create GR8 copies. We can probably make a helper function to bring down the repitition. This does result in KMOVD being used for copies when BWI is available because we don't know the original mask register size. This caused a lot of deltas on tests because we have to split the checks for KMOVD vs KMOVW based on BWI. Differential Revision: https://reviews.llvm.org/D30968 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298928 91177308-0d34-0410-b5e6-96231b3b80d8
77 lines
2.3 KiB
LLVM
77 lines
2.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 | FileCheck %s --check-prefix=CHECK --check-prefix=NOAVX512
|
|
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512
|
|
|
|
; Test conditional move for the supported types (i16, i32, and i32) and
|
|
; conditon input (argument or cmp). Currently i8 is not supported.
|
|
|
|
define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroext %b) {
|
|
; CHECK-LABEL: select_cmov_i16:
|
|
; CHECK: ## BB#0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: cmovew %dx, %si
|
|
; CHECK-NEXT: movzwl %si, %eax
|
|
; CHECK-NEXT: retq
|
|
%1 = select i1 %cond, i16 %a, i16 %b
|
|
ret i16 %1
|
|
}
|
|
|
|
define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
|
|
; CHECK-LABEL: select_cmp_cmov_i16:
|
|
; CHECK: ## BB#0:
|
|
; CHECK-NEXT: cmpw %si, %di
|
|
; CHECK-NEXT: cmovbw %di, %si
|
|
; CHECK-NEXT: movzwl %si, %eax
|
|
; CHECK-NEXT: retq
|
|
%1 = icmp ult i16 %a, %b
|
|
%2 = select i1 %1, i16 %a, i16 %b
|
|
ret i16 %2
|
|
}
|
|
|
|
define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
|
|
; CHECK-LABEL: select_cmov_i32:
|
|
; CHECK: ## BB#0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: cmovel %edx, %esi
|
|
; CHECK-NEXT: movl %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%1 = select i1 %cond, i32 %a, i32 %b
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: select_cmp_cmov_i32:
|
|
; CHECK: ## BB#0:
|
|
; CHECK-NEXT: cmpl %esi, %edi
|
|
; CHECK-NEXT: cmovbl %edi, %esi
|
|
; CHECK-NEXT: movl %esi, %eax
|
|
; CHECK-NEXT: retq
|
|
%1 = icmp ult i32 %a, %b
|
|
%2 = select i1 %1, i32 %a, i32 %b
|
|
ret i32 %2
|
|
}
|
|
|
|
define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
|
|
; CHECK-LABEL: select_cmov_i64:
|
|
; CHECK: ## BB#0:
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: cmoveq %rdx, %rsi
|
|
; CHECK-NEXT: movq %rsi, %rax
|
|
; CHECK-NEXT: retq
|
|
%1 = select i1 %cond, i64 %a, i64 %b
|
|
ret i64 %1
|
|
}
|
|
|
|
define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) {
|
|
; CHECK-LABEL: select_cmp_cmov_i64:
|
|
; CHECK: ## BB#0:
|
|
; CHECK-NEXT: cmpq %rsi, %rdi
|
|
; CHECK-NEXT: cmovbq %rdi, %rsi
|
|
; CHECK-NEXT: movq %rsi, %rax
|
|
; CHECK-NEXT: retq
|
|
%1 = icmp ult i64 %a, %b
|
|
%2 = select i1 %1, i64 %a, i64 %b
|
|
ret i64 %2
|
|
}
|
|
|