[PATCH] D37896: [DAGCombine] Resolving PR34474 by transforming mul(x, 2^c +/- 1) -> sub/add(shl(x, c) x) for any type including vector types

Michael Haidl via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 01:35:22 PDT 2017


pacxx created this revision.

PR34474 <https://bugs.llvm.org/show_bug.cgi?id=34474> describes problems for code generation of multiplications with a factor of 2^C +/-1. The patch transforms multiplications of this type to a left shift and an additional addition or subtraction.

The test cases which produced bad MC:

  define <2 x i64> @mul7(<2 x i64>) {
    %2 = mul <2 x i64> %0, <i64 7, i64 7>
    ret <2 x i64> %2
  }
  
  define <2 x i64> @mul17(<2 x i64>) {
    %2 = mul <2 x i64> %0, <i64 17, i64 17>
    ret <2 x i64> %2
  }
  
  define <16 x i8> @mul31(<16 x i8>) {
    %2 = mul <16 x i8> %0, <i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31, i8 31>
    ret <16 x i8> %2
  }

and are now lowered as follows:

  mul7:
    # BB#0: 
            vpsllq  $3, %xmm0, %xmm1
            vpsubq  %xmm0, %xmm1, %xmm0
            retq
  
  
   mul17:
    # BB#0:                    
            vpsllq  $4, %xmm0, %xmm1
            vpaddq  %xmm0, %xmm1, %xmm0
            retq
  
  
  mul31:
    # BB#0:                                 # %entry
            vpsllw  $5, %xmm0, %xmm1
            vpand   .LCPI4_0(%rip), %xmm1, %xmm1
            vpsubb  %xmm0, %xmm1, %xmm0
            retq




https://reviews.llvm.org/D37896

Files:
  lib/CodeGen/SelectionDAG/DAGCombiner.cpp


Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2675,6 +2675,25 @@
       return DAG.getNode(ISD::MUL, SDLoc(N), VT, N0.getOperand(0), C3);
   }
 
+  // change (mul X, 2^C+/-1) -> (add/sub (shl X, C ), X)
+  if (N1IsConst && ConstValue1.getSExtValue() > 2) {
+    APInt Plus1 = ConstValue1 + 1;
+    APInt Minus1 = ConstValue1 - 1;
+    int isPow2 = Plus1.isPowerOf2() ? 1 : Minus1.isPowerOf2() ? -1 : 0;
+    if (isPow2) {
+      APInt &Pow2 = isPow2 > 0 ? Plus1 : Minus1;
+      // avoid poison through shifts
+      if (VT.getScalarSizeInBits() > Pow2.logBase2()) {
+        SDLoc DL(N);
+        SDValue logBase2 = DAG.getConstant(Pow2.logBase2(), DL, VT);
+        AddToWorklist(logBase2.getNode());
+        auto Shl = DAG.getNode(ISD::SHL, DL, VT, N0, logBase2);
+        AddToWorklist(Shl.getNode());
+        return DAG.getNode(isPow2 > 0 ? ISD::SUB : ISD::ADD, DL, VT, Shl, N0);
+      }
+    }
+  }
+
   // Change (mul (shl X, C), Y) -> (shl (mul X, Y), C) when the shift has one
   // use.
   {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37896.115366.patch
Type: text/x-patch
Size: 1169 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170915/66385175/attachment.bin>


More information about the llvm-commits mailing list