[X86] When expanding a multiply by a negative of one less than a power of 2, like...
authorCraig Topper <craig.topper@intel.com>
Tue, 24 Jul 2018 21:31:21 +0000 (21:31 +0000)
committerCraig Topper <craig.topper@intel.com>
Tue, 24 Jul 2018 21:31:21 +0000 (21:31 +0000)
We generated a subtract for the power of 2 minus one then negated the result. The negate can be optimized away by swapping the subtract operands, but DAG combine doesn't know how to do that and we don't add any of the new nodes to the worklist anyway.

This patch makes use explicitly emit the swapped subtract.

llvm-svn: 337858

llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/imul.ll

index ef8a6d68395417f8913b1ab73a1c9643f24fbcba..12f6d409a6030c0a62e3fa241ba547bec687de69 100644 (file)
@@ -33922,14 +33922,20 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
             DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
                         DAG.getConstant(Log2_64(NumSign * SignMulAmt - 1), DL,
                                         MVT::i8)));
+        // To negate, subtract the number from zero
+        if (SignMulAmt < 0)
+          NewMul = DAG.getNode(ISD::SUB, DL, VT,
+                               DAG.getConstant(0, DL, VT), NewMul);
       } else if (IsPowerOf2_64MinusOne) {
         // (mul x, 2^N - 1) => (sub (shl x, N), x)
-        NewMul = DAG.getNode(
-            ISD::SUB, DL, VT,
-            DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
-                        DAG.getConstant(Log2_64(NumSign * SignMulAmt + 1), DL,
-                                        MVT::i8)),
-            N->getOperand(0));
+        NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
+                             DAG.getConstant(Log2_64(NumSign * SignMulAmt + 1),
+                                             DL, MVT::i8));
+        // To negate, reverse the operands of the subtract.
+        if (SignMulAmt < 0)
+          NewMul = DAG.getNode(ISD::SUB, DL, VT, N->getOperand(0), NewMul);
+        else
+          NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
       } else if (IsPowerOf2_64MinusTwo && NumSign == 1) {
         // (mul x, 2^N - 1) => (sub (shl x, N), x)
         NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
@@ -33938,10 +33944,6 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
         NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
         NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
       }
-      // To negate, subtract the number from zero
-      if (NewMul && NumSign == -1)
-        NewMul =
-            DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), NewMul);
     }
   }
 
index 761484c069bedd9eb13d6ab5d2dd47dcfcd38003..14f15143b95dbd6362f4a66d3121274530d37f84 100644 (file)
@@ -324,17 +324,16 @@ define i32 @test1(i32 %a) {
 ; X64:       # %bb.0: # %entry
 ; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    shll $5, %eax
-; X64-NEXT:    subl %edi, %eax
-; X64-NEXT:    negl %eax
+; X64-NEXT:    subl %eax, %edi
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    retq
 ;
 ; X86-LABEL: test1:
 ; X86:       # %bb.0: # %entry
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, %eax
-; X86-NEXT:    shll $5, %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl %eax, %ecx
+; X86-NEXT:    shll $5, %ecx
 ; X86-NEXT:    subl %ecx, %eax
-; X86-NEXT:    negl %eax
 ; X86-NEXT:    retl
 entry:
        %tmp3 = mul i32 %a, -31
@@ -414,8 +413,8 @@ define i64 @test5(i64 %a) {
 ; X64:       # %bb.0: # %entry
 ; X64-NEXT:    movq %rdi, %rax
 ; X64-NEXT:    shlq $5, %rax
-; X64-NEXT:    subq %rdi, %rax
-; X64-NEXT:    negq %rax
+; X64-NEXT:    subq %rax, %rdi
+; X64-NEXT:    movq %rdi, %rax
 ; X64-NEXT:    retq
 ;
 ; X86-LABEL: test5:
@@ -424,15 +423,15 @@ define i64 @test5(i64 %a) {
 ; X86-NEXT:    .cfi_def_cfa_offset 8
 ; X86-NEXT:    .cfi_offset %esi, -8
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, %esi
-; X86-NEXT:    shll $5, %esi
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    movl %esi, %eax
+; X86-NEXT:    shll $5, %eax
 ; X86-NEXT:    subl %eax, %esi
 ; X86-NEXT:    movl $-31, %edx
 ; X86-NEXT:    movl %ecx, %eax
 ; X86-NEXT:    mull %edx
 ; X86-NEXT:    subl %ecx, %edx
-; X86-NEXT:    subl %esi, %edx
+; X86-NEXT:    addl %esi, %edx
 ; X86-NEXT:    popl %esi
 ; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl