]> granicus.if.org Git - llvm/commitdiff
[X86] Simplify X86ISD::ADD/SUB if we don't use the result flag
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Fri, 25 Jan 2019 15:58:28 +0000 (15:58 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Fri, 25 Jan 2019 15:58:28 +0000 (15:58 +0000)
Simplify to the generic ISD::ADD/SUB if we don't make use of the result flag.

This mainly helps with ADDCARRY/SUBBORROW intrinsics which get expanded to X86ISD::ADD/SUB but could be simplified further.

Noticed in some of the test cases in PR31754

Differential Revision: https://reviews.llvm.org/D57234

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352210 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/adx-intrinsics-upgrade.ll
test/CodeGen/X86/adx-intrinsics.ll
test/CodeGen/X86/combine-adx.ll

index 162cb8b3f3c1ee8281bc295df98d91425229f482..0f0f6aa5f0b8529835f0c55e5dbd311f84c48634 100644 (file)
@@ -40491,6 +40491,22 @@ static SDValue combineCMP(SDNode *N, SelectionDAG &DAG) {
   return Op.getValue(1);
 }
 
+static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG) {
+  assert((X86ISD::ADD == N->getOpcode() || X86ISD::SUB == N->getOpcode()) &&
+         "Expected X86ISD::ADD or X86ISD::SUB");
+
+  // If we don't use the flag result, simplify back to a simple ADD/SUB.
+  if (N->hasAnyUseOfValue(1))
+    return SDValue();
+
+  SDLoc DL(N);
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
+  SDValue Res = DAG.getNode(X86ISD::ADD == N->getOpcode() ? ISD::ADD : ISD::SUB,
+                            DL, LHS.getSimpleValueType(), LHS, RHS);
+  return DAG.getMergeValues({Res, DAG.getConstant(0, DL, MVT::i32)}, DL);
+}
+
 static SDValue combineSBB(SDNode *N, SelectionDAG &DAG) {
   if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
     MVT VT = N->getSimpleValueType(0);
@@ -41660,6 +41676,8 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
   case X86ISD::CMP:         return combineCMP(N, DAG);
   case ISD::ADD:            return combineAdd(N, DAG, Subtarget);
   case ISD::SUB:            return combineSub(N, DAG, Subtarget);
+  case X86ISD::ADD:
+  case X86ISD::SUB:         return combineX86AddSub(N, DAG);
   case X86ISD::SBB:         return combineSBB(N, DAG);
   case X86ISD::ADC:         return combineADC(N, DAG, DCI);
   case ISD::MUL:            return combineMul(N, DAG, DCI, Subtarget);
index 34f8ff8725958e0fe2cf20d84eac2e3c2dec7bc1..762314a5b5546f4728c4e1ed8764f6ae4e92cb7f 100644 (file)
@@ -108,9 +108,7 @@ define i32 @load_crash(i64* nocapture readonly %a, i64* nocapture readonly %b, i
 define void @allzeros() {
 ; CHECK-LABEL: allzeros:
 ; CHECK:       ## %bb.0: ## %entry
-; CHECK-NEXT:    xorl %eax, %eax ## encoding: [0x31,0xc0]
-; CHECK-NEXT:    addq $0, %rax ## encoding: [0x48,0x83,0xc0,0x00]
-; CHECK-NEXT:    movq %rax, 0 ## encoding: [0x48,0x89,0x04,0x25,0x00,0x00,0x00,0x00]
+; CHECK-NEXT:    movq $0, 0 ## encoding: [0x48,0xc7,0x04,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
 ; CHECK-NEXT:    retq ## encoding: [0xc3]
 entry:
   %0 = tail call i8 @llvm.x86.addcarryx.u64(i8 0, i64 0, i64 0, i8* null)
index d37be0653289bbd36773f4941d48cc6b61771495..6c1c2739c64dcead5b678c32b169665a4cca2b06 100644 (file)
@@ -134,9 +134,7 @@ define i32 @load_crash(i64* nocapture readonly %a, i64* nocapture readonly %b, i
 define void @allzeros() {
 ; CHECK-LABEL: allzeros:
 ; CHECK:       ## %bb.0: ## %entry
-; CHECK-NEXT:    xorl %eax, %eax ## encoding: [0x31,0xc0]
-; CHECK-NEXT:    addq $0, %rax ## encoding: [0x48,0x83,0xc0,0x00]
-; CHECK-NEXT:    movq %rax, 0 ## encoding: [0x48,0x89,0x04,0x25,0x00,0x00,0x00,0x00]
+; CHECK-NEXT:    movq $0, 0 ## encoding: [0x48,0xc7,0x04,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
 ; CHECK-NEXT:    retq ## encoding: [0xc3]
 entry:
   %0 = call { i8, i64 } @llvm.x86.addcarry.64(i8 0, i64 0, i64 0)
index 15d39184aa9d0467cc12647dc0875d83b3a91f8a..c2b11e78115a8d6886e026c6128e5ebdd9c98a25 100644 (file)
@@ -6,13 +6,11 @@ define i32 @test_addcarry_32_x_0_false(i32 %a0)  {
 ; X86-LABEL: test_addcarry_32_x_0_false:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl $0, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_addcarry_32_x_0_false:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    retq
   %1 = tail call { i8, i32 } @llvm.x86.addcarry.32(i8 0, i32 %a0, i32 0)
   %2 = extractvalue { i8, i32 } %1, 1
@@ -22,14 +20,12 @@ define i32 @test_addcarry_32_x_0_false(i32 %a0)  {
 define i32 @test_addcarry_32_0_x_false(i32 %a0)  {
 ; X86-LABEL: test_addcarry_32_0_x_false:
 ; X86:       # %bb.0:
-; X86-NEXT:    xorl %eax, %eax
-; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_addcarry_32_0_x_false:
 ; X64:       # %bb.0:
-; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi), %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    retq
   %1 = tail call { i8, i32 } @llvm.x86.addcarry.32(i8 0, i32 0, i32 %a0)
   %2 = extractvalue { i8, i32 } %1, 1
@@ -40,13 +36,11 @@ define i32 @test_subborrow_32_x_0_false(i32 %a0)  {
 ; X86-LABEL: test_subborrow_32_x_0_false:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    subl $0, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: test_subborrow_32_x_0_false:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    subl $0, %eax
 ; X64-NEXT:    retq
   %1 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %a0, i32 0)
   %2 = extractvalue { i8, i32 } %1, 1