[PATCH] D147305: [LoongArch] Optimize multiplication with immediates

WÁNG Xuěruì via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 31 02:03:04 PDT 2023


xen0n added a comment.

This is good strength reduction overall, thanks for the insight!

Though maybe the exact patterns can be automatically generated with nested loops, for reduced mental burden to prove correctness? I've sketched something and it seems doable:

  >>> alsl = lambda j, k, imm: (j << imm) + k
  >>> a = [alsl(alsl(1, 1, i), alsl(1, 1, i), j) for j in range(1,5) for i in range(1,5)]
  >>> a
  [9, 15, 27, 51, 15, 25, 45, 85, 27, 45, 81, 153, 51, 85, 153, 289]
  >>> list(sorted(set(a)))
  [9, 15, 25, 27, 45, 51, 81, 85, 153, 289]
  >>> b = [alsl(alsl(1, 1, i), 1, j) for j in range(1,5) for i in range(1,5)]
  >>> b
  [7, 11, 19, 35, 13, 21, 37, 69, 25, 41, 73, 137, 49, 81, 145, 273]
  >>> ab = set(a).union(set(b))
  >>> len(ab)
  24
  >>> list(sorted(set(a).intersection(set(b))))
  [25, 81]
  
  >>> c = [alsl(1, alsl(1, 1, i), j) for j in range(1,5) for i in range(1,5)]
  >>> c
  [5, 7, 11, 19, 7, 9, 13, 21, 11, 13, 17, 25, 19, 21, 25, 33]
  >>> list(sorted(set(c)))
  [5, 7, 9, 11, 13, 17, 19, 21, 25, 33]
  
  >>> set(c).difference(ab)
  {33, 5, 17}
  >>> all = set(c).union(ab).difference({3, 5, 9, 17})
  >>> len(all)
  24
  >>> list(sorted(all))
  [7, 11, 13, 15, 19, 21, 25, 27, 33, 35, 37, 41, 45, 49, 51, 69, 73, 81, 85, 137, 145, 153, 273, 289]

So basically, we can strength-reduce a total of 24 different constant-multiplications with two `alsl`'s:

- case 1: `alsl T, X, X, i; alsl Y, T, T, j`: 15, 25, 27, 45, 51, 81, 85, 153, 289
- case 2: `alsl T, X, X, i; alsl Y, T, X, j`: 7, 11, 19, 35, 13, 21, 37, 69, 25, 41, 73, 137, 49, 81, 145, 273
- case 3: `alsl T, X, X, i; alsl Y, X, T, j`: 7, 11, 13, 19, 21, 25, 33

Problem is that there are some overlaps between the 3 possible combinations, and some inside case 1 and 3. If we could somehow avoid producing conflicting rules then probably leveraging TableGen's loop and computation abilities would produce code that's easier to maintain. Otherwise, simplifying the code with some macros could also be beneficial.



================
Comment at: llvm/lib/Target/LoongArch/LoongArchInstrInfo.td:865-866
+  if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
+    if (N1C->hasOneUse())
+      return true;
+  return false;
----------------
The inner `if` could be simplified into just `return N1C->hasOneUse()`. The outer `return false` could be kept though, for avoiding an overly complex single return expression.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147305/new/

https://reviews.llvm.org/D147305



More information about the llvm-commits mailing list