This is an archive of the discontinued LLVM Phabricator instance.

[AArch64][SVEIntrinsicOpts] Factor out redundant SVE mul/fmul intrinsics
ClosedPublic

Authored by joechrisellis on Mar 5 2021, 3:42 AM.

Details

Summary

This commit implements an IR-level optimization to eliminate idempotent
SVE mul/fmul intrinsic calls. Currently, the following patterns are
captured:

fmul  pg  (dup_x  1.0)  V  =>  V
mul   pg  (dup_x  1)    V  =>  V

fmul  pg  V  (dup_x  1.0)  =>  V
mul   pg  V  (dup_x  1)    =>  V

fmul  pg  V  (dup  v  pg  1.0)  =>  V
mul   pg  V  (dup  v  pg  1)    =>  V

The result of this commit is that code such as:

1  #include <arm_sve.h>
2
3  svfloat64_t foo(svfloat64_t a) {
4    svbool_t t = svptrue_b64();
5    svfloat64_t b = svdup_f64(1.0);
6    return svmul_m(t, a, b);
7  }

will lower to a nop.

This commit does not capture all possibilities; only the simple cases
described above. There is still room for further optimisation.

Diff Detail

Event Timeline

joechrisellis created this revision.Mar 5 2021, 3:42 AM
joechrisellis requested review of this revision.Mar 5 2021, 3:42 AM
Herald added a project: Restricted Project. ยท View Herald TranscriptMar 5 2021, 3:42 AM
Herald added a subscriber: llvm-commits. ยท View Herald Transcript
peterwaller-arm added inline comments.Mar 8 2021, 4:57 AM
llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp
377

Naming suggestions: OpPredicate, OpMultiplicand, OpMultiplier.

420

I've had a quick grep, and can't see much precedent for this style. If there are braces on the preceding if body, it seems to almost always appear as } else if () { (I couldn't find a counterexample). I can see why you've written it like this but the structure looks a bit too much like independent if's and I might have missed the else's.

Suggested syntax:

if () {
  // [f]mul pg (dupx 1) %n => %n
} else if () {
  // [f]mul pg %n (dupx 1) => %n
}

etc.

450

As discussed offline, you can check if the rightmost operand is what you're interested in, and if it's not, std::swap the two operands and recheck, to avoid duplication of the substitution logic across operands.

david-arm added inline comments.Mar 8 2021, 5:22 AM
llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp
375

nit: Is this better named as Pg instead of Op0 so it's more obvious that Op1 and Op2 are the integer/FP vector inputs?

380

I think it would be good to make use of existing match functions if possible, i.e.:

return match(V, m_FPOne()) || match(V, m_One());
joechrisellis marked 5 inline comments as done.

Address review comments.

  • @peterwaller-arm:
    • more descriptive variable names.
    • use swap idiom to reduce code duplication.
    • move comments into body of if-statements.
  • @david-arm:
    • more descriptive variable names.
    • use existing match functions.

Politely pinging this. ๐Ÿ™‚

peterwaller-arm accepted this revision.Mar 16 2021, 3:29 AM

LGTM modulo nit.

llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp
404

Nit: AFAIUI, typically during canonicalization, constant-like things would appear in the righthand side (multiplier, in this case).

This revision is now accepted and ready to land.Mar 16 2021, 3:29 AM
joechrisellis marked an inline comment as done.

Address comments:

  • @peterwaller-arm: swap uses of OpMultiplicand and OpMultiplier so that the constant-like DUP is treated as the RHS of the mul/fmul.
This revision was landed with ongoing or failed builds.Mar 16 2021, 7:50 AM
This revision was automatically updated to reflect the committed changes.