[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