[PATCH] D38130: [mips] Improve genConstMult() so it works with arbitrary precision

Miloš Stojanović via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 27 06:04:48 PDT 2017


mstojanovic updated this revision to Diff 116799.
mstojanovic retitled this revision from "[mips] Fix negative constant multiplication when using int128_t" to "[mips] Improve genConstMult() so it works with arbitrary precision".
mstojanovic edited the summary of this revision.
mstojanovic added a comment.

Added arbitrary precision in genConstMult().


https://reviews.llvm.org/D38130

Files:
  lib/Target/Mips/MipsSEISelLowering.cpp
  test/CodeGen/Mips/const-mult.ll


Index: test/CodeGen/Mips/const-mult.ll
===================================================================
--- test/CodeGen/Mips/const-mult.ll
+++ test/CodeGen/Mips/const-mult.ll
@@ -46,3 +46,23 @@
   %mul = mul nsw i64 %a, -9223372036854775805
   ret i64 %mul
 }
+
+; CHECK64-LABEL:     muln170141183460469231731687303715884105725_128:
+; CHECK64-DAG: dsrl $[[R0:[0-9]+]], $4, 63
+; CHECK64-DAG: dsll $[[R1:[0-9]+]], $5, 1
+; CHECK64-DAG: or $[[R2:[0-9]+]], $[[R1]], $[[R0]]
+; CHECK64-DAG: daddu $[[R3:[0-9]+]], $[[R2]], $5
+; CHECK64-DAG: dsll $[[R4:[0-9]+]], $4, 1
+; CHECK64-DAG: daddu $[[R5:[0-9]+]], $[[R4]], $4
+; CHECK64-DAG: sltu $[[R6:[0-9]+]], $[[R5]], $[[R4]]
+; CHECK64-DAG: dsll $[[R7:[0-9]+]], $[[R6]], 32
+; CHECK64-DAG: dsrl $[[R8:[0-9]+]], $[[R7]], 32
+; CHECK64-DAG: daddu $[[R9:[0-9]+]], $[[R3]], $[[R8]]
+; CHECK64-DAG: dsll $[[R10:[0-9]+]], $4, 63
+; CHECK64:     daddu ${{[0-9]+}}, $[[R10]], $[[R9]]
+
+define i128 @muln170141183460469231731687303715884105725_128(i128 signext %a) {
+entry:
+  %mul = mul nsw i128 %a, -170141183460469231731687303715884105725
+  ret i128 %mul
+}
\ No newline at end of file
Index: lib/Target/Mips/MipsSEISelLowering.cpp
===================================================================
--- lib/Target/Mips/MipsSEISelLowering.cpp
+++ lib/Target/Mips/MipsSEISelLowering.cpp
@@ -701,11 +701,8 @@
   return SDValue();
 }
 
-static SDValue genConstMult(SDValue X, uint64_t C, const SDLoc &DL, EVT VT,
+static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT,
                             EVT ShiftTy, SelectionDAG &DAG) {
-  // Clear the upper (64 - VT.sizeInBits) bits.
-  C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
-
   // Return 0.
   if (C == 0)
     return DAG.getConstant(0, DL, VT);
@@ -715,18 +712,19 @@
     return X;
 
   // If c is power of 2, return (shl x, log2(c)).
-  if (isPowerOf2_64(C))
+  if (C.isPowerOf2())
     return DAG.getNode(ISD::SHL, DL, VT, X,
-                       DAG.getConstant(Log2_64(C), DL, ShiftTy));
+                       DAG.getConstant(C.logBase2(), DL, ShiftTy));
 
-  unsigned Log2Ceil = Log2_64_Ceil(C);
-  uint64_t Floor = 1LL << Log2_64(C);
-  uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
+  unsigned BitWidth = C.getBitWidth();
+  APInt Floor = APInt(BitWidth, 1) << C.logBase2();
+  APInt Ceil = C.isNegative() ? APInt(BitWidth, 0) :
+                                APInt(BitWidth, 1) << C.ceilLogBase2();
 
   // If |c - floor_c| <= |c - ceil_c|,
   // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
   // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
-  if (C - Floor <= Ceil - C) {
+  if ((C - Floor).ule(Ceil - C)) {
     SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
     SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
     return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
@@ -746,7 +744,7 @@
 
   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
     if (!VT.isVector())
-      return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N), VT,
+      return genConstMult(N->getOperand(0), C->getAPIntValue(), SDLoc(N), VT,
                           TL->getScalarShiftAmountTy(DAG.getDataLayout(), VT),
                           DAG);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38130.116799.patch
Type: text/x-patch
Size: 3283 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170927/5c983943/attachment.bin>


More information about the llvm-commits mailing list