[llvm] r335575 - [X86] Use XOR for SUB (C, X) during isel if will help fold an immediate
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 25 20:11:15 PDT 2018
Author: ctopper
Date: Mon Jun 25 20:11:15 2018
New Revision: 335575
URL: http://llvm.org/viewvc/llvm-project?rev=335575&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Target/X86/X86InstrCompiler.td
llvm/trunk/test/CodeGen/X86/bool-math.ll
llvm/trunk/test/CodeGen/X86/dagcombine-select.ll
Modified: llvm/trunk/lib/Target/X86/X86InstrCompiler.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrCompiler.td?rev=335575&r1=335574&r2=335575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrCompiler.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrCompiler.td Mon Jun 25 20:11:15 2018
@@ -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
Modified: llvm/trunk/test/CodeGen/X86/bool-math.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-math.ll?rev=335575&r1=335574&r2=335575&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/bool-math.ll (original)
+++ llvm/trunk/test/CodeGen/X86/bool-math.ll Mon Jun 25 20:11:15 2018
@@ -47,8 +47,8 @@ define i8 @add_zext_cmp_mask_same_size_r
; 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_resu
; 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_re
; 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_bigg
; 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_big
; 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_bigg
; 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
Modified: llvm/trunk/test/CodeGen/X86/dagcombine-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dagcombine-select.ll?rev=335575&r1=335574&r2=335575&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dagcombine-select.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dagcombine-select.ll Mon Jun 25 20:11:15 2018
@@ -194,9 +194,9 @@ define i32 @shl_constant_sel_constants(i
; 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(
; 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(
; 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
More information about the llvm-commits
mailing list