mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[X86] Use XOR for SUB (C, X) during isel if will help fold an immediate
Summary: Same idea as D48529, but restricted to X86 and done very late to avoid any surprises where subtract might be better for DAG combining. This seems like the safest way to do this trick. And we consider doing it as a DAG combine later. Reviewers: spatel, RKSimon Reviewed By: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D48557 llvm-svn: 335575
This commit is contained in:
parent
29e06076c9
commit
702b88ddc2
@ -1364,6 +1364,44 @@ def ADD64ri32_DB : I<0, Pseudo,
|
||||
}
|
||||
} // AddedComplexity, SchedRW
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pattern match SUB as XOR
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// An immediate in the LHS of a subtract can't be encoded in the instruction.
|
||||
// If there is no possibility of a borrow we can use an XOR instead of a SUB
|
||||
// to enable the immediate to be folded.
|
||||
// TODO: Move this to a DAG combine?
|
||||
|
||||
def sub_is_xor : PatFrag<(ops node:$lhs, node:$rhs), (sub node:$lhs, node:$rhs),[{
|
||||
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
|
||||
KnownBits Known;
|
||||
CurDAG->computeKnownBits(N->getOperand(1), Known);
|
||||
|
||||
// If all possible ones in the RHS are set in the LHS then there can't be
|
||||
// a borrow and we can use xor.
|
||||
return (~Known.Zero).isSubsetOf(CN->getAPIntValue());
|
||||
}
|
||||
|
||||
return false;
|
||||
}]>;
|
||||
|
||||
let AddedComplexity = 5 in {
|
||||
def : Pat<(sub_is_xor imm:$src2, GR8:$src1),
|
||||
(XOR8ri GR8:$src1, imm:$src2)>;
|
||||
def : Pat<(sub_is_xor i16immSExt8:$src2, GR16:$src1),
|
||||
(XOR16ri8 GR16:$src1, i16immSExt8:$src2)>;
|
||||
def : Pat<(sub_is_xor imm:$src2, GR16:$src1),
|
||||
(XOR16ri GR16:$src1, imm:$src2)>;
|
||||
def : Pat<(sub_is_xor i32immSExt8:$src2, GR32:$src1),
|
||||
(XOR32ri8 GR32:$src1, i32immSExt8:$src2)>;
|
||||
def : Pat<(sub_is_xor imm:$src2, GR32:$src1),
|
||||
(XOR32ri GR32:$src1, imm:$src2)>;
|
||||
def : Pat<(sub_is_xor i64immSExt8:$src2, GR64:$src1),
|
||||
(XOR64ri8 GR64:$src1, i64immSExt8:$src2)>;
|
||||
def : Pat<(sub_is_xor i64immSExt32:$src2, GR64:$src1),
|
||||
(XOR64ri32 GR64:$src1, i64immSExt32:$src2)>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Some peepholes
|
||||
|
@ -47,8 +47,8 @@ define i8 @add_zext_cmp_mask_same_size_result(i8 %x) {
|
||||
; CHECK-LABEL: add_zext_cmp_mask_same_size_result:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andb $1, %dil
|
||||
; CHECK-NEXT: movb $27, %al
|
||||
; CHECK-NEXT: subb %dil, %al
|
||||
; CHECK-NEXT: xorb $27, %dil
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%a = and i8 %x, 1
|
||||
%c = icmp eq i8 %a, 0
|
||||
@ -61,8 +61,8 @@ define i32 @add_zext_cmp_mask_wider_result(i8 %x) {
|
||||
; CHECK-LABEL: add_zext_cmp_mask_wider_result:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andl $1, %edi
|
||||
; CHECK-NEXT: movl $27, %eax
|
||||
; CHECK-NEXT: subl %edi, %eax
|
||||
; CHECK-NEXT: xorl $27, %edi
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%a = and i8 %x, 1
|
||||
%c = icmp eq i8 %a, 0
|
||||
@ -75,8 +75,8 @@ define i8 @add_zext_cmp_mask_narrower_result(i32 %x) {
|
||||
; CHECK-LABEL: add_zext_cmp_mask_narrower_result:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andl $1, %edi
|
||||
; CHECK-NEXT: movb $43, %al
|
||||
; CHECK-NEXT: subb %dil, %al
|
||||
; CHECK-NEXT: xorb $43, %dil
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%a = and i32 %x, 1
|
||||
%c = icmp eq i32 %a, 0
|
||||
@ -129,8 +129,8 @@ define i8 @low_bit_select_constants_bigger_true_same_size_result(i8 %x) {
|
||||
; CHECK-LABEL: low_bit_select_constants_bigger_true_same_size_result:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andb $1, %dil
|
||||
; CHECK-NEXT: movb $-29, %al
|
||||
; CHECK-NEXT: subb %dil, %al
|
||||
; CHECK-NEXT: xorb $-29, %dil
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%a = and i8 %x, 1
|
||||
%c = icmp eq i8 %a, 0
|
||||
@ -142,8 +142,8 @@ define i32 @low_bit_select_constants_bigger_true_wider_result(i8 %x) {
|
||||
; CHECK-LABEL: low_bit_select_constants_bigger_true_wider_result:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andl $1, %edi
|
||||
; CHECK-NEXT: movl $227, %eax
|
||||
; CHECK-NEXT: subl %edi, %eax
|
||||
; CHECK-NEXT: xorl $227, %edi
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%a = and i8 %x, 1
|
||||
%c = icmp eq i8 %a, 0
|
||||
@ -155,8 +155,8 @@ define i8 @low_bit_select_constants_bigger_true_narrower_result(i16 %x) {
|
||||
; CHECK-LABEL: low_bit_select_constants_bigger_true_narrower_result:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andl $1, %edi
|
||||
; CHECK-NEXT: movb $41, %al
|
||||
; CHECK-NEXT: subb %dil, %al
|
||||
; CHECK-NEXT: xorb $41, %dil
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%a = and i16 %x, 1
|
||||
%c = icmp eq i16 %a, 0
|
||||
|
@ -194,9 +194,9 @@ define i32 @shl_constant_sel_constants(i1 %cond) {
|
||||
; CHECK-LABEL: shl_constant_sel_constants:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andb $1, %dil
|
||||
; CHECK-NEXT: movb $3, %cl
|
||||
; CHECK-NEXT: subb %dil, %cl
|
||||
; CHECK-NEXT: xorb $3, %dil
|
||||
; CHECK-NEXT: movl $1, %eax
|
||||
; CHECK-NEXT: movl %edi, %ecx
|
||||
; CHECK-NEXT: shll %cl, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%sel = select i1 %cond, i32 2, i32 3
|
||||
@ -208,9 +208,9 @@ define i32 @lshr_constant_sel_constants(i1 %cond) {
|
||||
; CHECK-LABEL: lshr_constant_sel_constants:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andb $1, %dil
|
||||
; CHECK-NEXT: movb $3, %cl
|
||||
; CHECK-NEXT: subb %dil, %cl
|
||||
; CHECK-NEXT: xorb $3, %dil
|
||||
; CHECK-NEXT: movl $64, %eax
|
||||
; CHECK-NEXT: movl %edi, %ecx
|
||||
; CHECK-NEXT: shrl %cl, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%sel = select i1 %cond, i32 2, i32 3
|
||||
@ -222,9 +222,9 @@ define i32 @ashr_constant_sel_constants(i1 %cond) {
|
||||
; CHECK-LABEL: ashr_constant_sel_constants:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andb $1, %dil
|
||||
; CHECK-NEXT: movb $3, %cl
|
||||
; CHECK-NEXT: subb %dil, %cl
|
||||
; CHECK-NEXT: xorb $3, %dil
|
||||
; CHECK-NEXT: movl $128, %eax
|
||||
; CHECK-NEXT: movl %edi, %ecx
|
||||
; CHECK-NEXT: shrl %cl, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%sel = select i1 %cond, i32 2, i32 3
|
||||
|
Loading…
x
Reference in New Issue
Block a user