[llvm] r337858 - [X86] When expanding a multiply by a negative of one less than a power of 2, like 31, don't generate a negate of a subtract that we'll never optimize.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 24 14:31:21 PDT 2018


Author: ctopper
Date: Tue Jul 24 14:31:21 2018
New Revision: 337858

URL: http://llvm.org/viewvc/llvm-project?rev=337858&view=rev
Log:
[X86] When expanding a multiply by a negative of one less than a power of 2, like 31, don't generate a negate of a subtract that we'll never optimize.

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.

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

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=337858&r1=337857&r2=337858&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Jul 24 14:31:21 2018
@@ -33922,14 +33922,20 @@ static SDValue combineMul(SDNode *N, Sel
             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, Sel
         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);
     }
   }
 

Modified: llvm/trunk/test/CodeGen/X86/imul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/imul.ll?rev=337858&r1=337857&r2=337858&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/imul.ll (original)
+++ llvm/trunk/test/CodeGen/X86/imul.ll Tue Jul 24 14:31:21 2018
@@ -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




More information about the llvm-commits mailing list