[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