[llvm] r306072 - [x86] add/sub (X==0) --> sbb(cmp X, 1)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 22 16:47:16 PDT 2017
Author: spatel
Date: Thu Jun 22 18:47:15 2017
New Revision: 306072
URL: http://llvm.org/viewvc/llvm-project?rev=306072&view=rev
Log:
[x86] add/sub (X==0) --> sbb(cmp X, 1)
This is very similar to the transform in:
https://reviews.llvm.org/rL306040
...but in this case, we use cmp X, 1 to set the carry bit as needed.
Again, we can show that all of these are logically equivalent (although
InstCombine currently canonicalizes to a form not seen here), and if
we believe IACA, then this is the smallest/fastest code. Eg, with SNB:
| Num Of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | |
---------------------------------------------------------------------
| 1 | 1.0 | | | | | | | cmp edi, 0x1
| 2 | | 1.0 | | | | 1.0 | CP | sbb eax, eax
The larger motivation is to clean up all select-of-constants combining/lowering
because we're missing some common cases.
Modified:
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/test/CodeGen/X86/sbb.ll
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=306072&r1=306071&r2=306072&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Jun 22 18:47:15 2017
@@ -34900,12 +34900,13 @@ static SDValue combineAddOrSubToADCOrSBB
SDValue Z = Cmp.getOperand(0);
SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::i32);
- // If X is -1 or 0, then we have an opportunity to avoid constants required by
- // the cmp transform below. 'neg' sets the carry flag when Z != 0, so create 0
- // or -1 using 'sbb' with fake operands:
- // 0 - (Z != 0) --> sbb %eax, %eax, (neg Z)
- // -1 + (Z == 0) --> sbb %eax, %eax, (neg Z)
+ // If X is -1 or 0, then we have an opportunity to avoid constants required in
+ // the general case below.
if (auto *ConstantX = dyn_cast<ConstantSDNode>(X)) {
+ // 'neg' sets the carry flag when Z != 0, so create 0 or -1 using 'sbb' with
+ // fake operands:
+ // 0 - (Z != 0) --> sbb %eax, %eax, (neg Z)
+ // -1 + (Z == 0) --> sbb %eax, %eax, (neg Z)
if ((IsSub && CC == X86::COND_NE && ConstantX->isNullValue()) ||
(!IsSub && CC == X86::COND_E && ConstantX->isAllOnesValue())) {
SDValue Zero = DAG.getConstant(0, DL, VT);
@@ -34914,6 +34915,17 @@ static SDValue combineAddOrSubToADCOrSBB
DAG.getConstant(X86::COND_B, DL, MVT::i8),
SDValue(Neg.getNode(), 1));
}
+ // cmp with 1 sets the carry flag when Z == 0, so create 0 or -1 using 'sbb'
+ // with fake operands:
+ // 0 - (Z == 0) --> sbb %eax, %eax, (cmp Z, 1)
+ // -1 + (Z != 0) --> sbb %eax, %eax, (cmp Z, 1)
+ if ((IsSub && CC == X86::COND_E && ConstantX->isNullValue()) ||
+ (!IsSub && CC == X86::COND_NE && ConstantX->isAllOnesValue())) {
+ SDValue One = DAG.getConstant(1, DL, Z.getValueType());
+ SDValue Cmp1 = DAG.getNode(X86ISD::CMP, DL, MVT::i32, Z, One);
+ return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
+ DAG.getConstant(X86::COND_B, DL, MVT::i8), Cmp1);
+ }
}
// (cmp Z, 1) sets the carry flag if Z is 0.
Modified: llvm/trunk/test/CodeGen/X86/sbb.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sbb.ll?rev=306072&r1=306071&r2=306072&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/sbb.ll (original)
+++ llvm/trunk/test/CodeGen/X86/sbb.ll Thu Jun 22 18:47:15 2017
@@ -75,9 +75,8 @@ define i64 @i64_select_neg1_or_0(i64 %x)
define i32 @i32_select_neg1_or_0_as_math(i32 %x) {
; CHECK-LABEL: i32_select_neg1_or_0_as_math:
; CHECK: # BB#0:
-; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpl $1, %edi
-; CHECK-NEXT: sbbl $0, %eax
+; CHECK-NEXT: sbbl %eax, %eax
; CHECK-NEXT: retq
%cmp = icmp eq i32 %x, 0
%ext = zext i1 %cmp to i32
@@ -91,8 +90,7 @@ define i16 @i16_select_neg1_or_0_commute
; CHECK-LABEL: i16_select_neg1_or_0_commuted:
; CHECK: # BB#0:
; CHECK-NEXT: cmpw $1, %di
-; CHECK-NEXT: movw $-1, %ax
-; CHECK-NEXT: sbbw $-1, %ax
+; CHECK-NEXT: sbbw %ax, %ax
; CHECK-NEXT: retq
%cmp = icmp ne i16 %x, 0
%sel = select i1 %cmp, i16 0, i16 -1
@@ -105,8 +103,7 @@ define i8 @i8_select_neg1_or_0_commuted_
; CHECK-LABEL: i8_select_neg1_or_0_commuted_as_math:
; CHECK: # BB#0:
; CHECK-NEXT: cmpb $1, %dil
-; CHECK-NEXT: movb $-1, %al
-; CHECK-NEXT: sbbb $-1, %al
+; CHECK-NEXT: sbbb %al, %al
; CHECK-NEXT: retq
%cmp = icmp ne i8 %x, 0
%ext = zext i1 %cmp to i8
More information about the llvm-commits
mailing list