Selects of the form `cond ? 1 : 0` are created during unrolling of setcc+vselect. Currently these are not optimized away post-legalization even if fully redundant. Having these extra selects sitting between things can prevent other folds from applying. Enabling this requires some mitigations in the ARM backend, in particular in the interaction with MVE support. There's two changes here: * Form CSINV/CSNEG/CSINC from CMOV, rather than only creating it during SELECT_CC lowering. (After this change, the lowering in SELECT_CC can be dropped without test changes, let me know if I should do that.) * Support pushing negations through CMOV in more cases, in particular if the operands are constant or the negation can be handled by flipping lshr/ashr. Additionally, in the X86 backend, try to simplify CMOV to SETCC if only the low bit is demanded.
51 lines
1.8 KiB
LLVM
51 lines
1.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=ve -mattr=+vpu | FileCheck %s
|
|
|
|
; This would assert because VE specified that all setcc
|
|
; nodes (even with vector operands) return a scalar value.
|
|
|
|
define <4 x i8> @udiv_by_minus_one(<4 x i8> %x) {
|
|
; CHECK-LABEL: udiv_by_minus_one:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: and %s4, %s0, (56)0
|
|
; CHECK-NEXT: and %s1, %s1, (56)0
|
|
; CHECK-NEXT: and %s2, %s2, (56)0
|
|
; CHECK-NEXT: and %s0, %s3, (56)0
|
|
; CHECK-NEXT: lea %s5, 255
|
|
; CHECK-NEXT: cmps.w.sx %s6, %s0, %s5
|
|
; CHECK-NEXT: or %s0, 0, (0)1
|
|
; CHECK-NEXT: or %s3, 0, (0)1
|
|
; CHECK-NEXT: cmov.w.eq %s3, (63)0, %s6
|
|
; CHECK-NEXT: cmps.w.sx %s6, %s2, %s5
|
|
; CHECK-NEXT: or %s2, 0, (0)1
|
|
; CHECK-NEXT: cmov.w.eq %s2, (63)0, %s6
|
|
; CHECK-NEXT: cmps.w.sx %s6, %s1, %s5
|
|
; CHECK-NEXT: or %s1, 0, (0)1
|
|
; CHECK-NEXT: cmov.w.eq %s1, (63)0, %s6
|
|
; CHECK-NEXT: cmps.w.sx %s4, %s4, %s5
|
|
; CHECK-NEXT: cmov.w.eq %s0, (63)0, %s4
|
|
; CHECK-NEXT: b.l.t (, %s10)
|
|
%r = udiv <4 x i8> %x, <i8 255, i8 255, i8 255, i8 255>
|
|
ret <4 x i8> %r
|
|
}
|
|
|
|
define <4 x i8> @urem_by_minus_one(<4 x i8> %x) {
|
|
; CHECK-LABEL: urem_by_minus_one:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: and %s4, %s0, (56)0
|
|
; CHECK-NEXT: and %s5, %s1, (56)0
|
|
; CHECK-NEXT: and %s6, %s2, (56)0
|
|
; CHECK-NEXT: and %s7, %s3, (56)0
|
|
; CHECK-NEXT: cmpu.w %s7, %s7, (56)0
|
|
; CHECK-NEXT: cmov.w.eq %s3, (0)1, %s7
|
|
; CHECK-NEXT: cmpu.w %s6, %s6, (56)0
|
|
; CHECK-NEXT: cmov.w.eq %s2, (0)1, %s6
|
|
; CHECK-NEXT: cmpu.w %s5, %s5, (56)0
|
|
; CHECK-NEXT: cmov.w.eq %s1, (0)1, %s5
|
|
; CHECK-NEXT: cmpu.w %s4, %s4, (56)0
|
|
; CHECK-NEXT: cmov.w.eq %s0, (0)1, %s4
|
|
; CHECK-NEXT: b.l.t (, %s10)
|
|
%r = urem <4 x i8> %x, <i8 255, i8 255, i8 255, i8 255>
|
|
ret <4 x i8> %r
|
|
}
|