[PATCH] Add a Scalarize pass

Richard Sandiford rsandifo at linux.vnet.ibm.com
Wed Nov 13 02:03:18 PST 2013

Nadav Rotem <nrotem at apple.com> writes:
> I think that it is a good idea to have a scalarizer pass for people who
> want to build llvm-based compilers, but I don’t think that this pass
> should be a part of the default pass manager.  Targets that want to
> scalarize the code should do it as part of instruction-selection (just
> declare the types as illegal).  Why do you want to control scalatization
> from the target ?  IMHO scalarization is only useful in undoing domain
> specific input IR.

The problem is that instruction selection is so late that the scalar
operations don't get optimised very much.  The only pass that runs after
type legalisation and still understands the function at an operational
level is DAGCombiner, which is only block-local.

Take for example something like:

  typedef unsigned int V4SI __attribute__ ((vector_size (16)));
  void foo (V4SI *vec, unsigned int n, unsigned int x)
    V4SI factor = { x, 2, 4, 8 };
    for (unsigned i = 0; i < n; ++i)
      vec[i] *= factor;

Without the Scalarizer pass, this multiplication remains a vector
multiplication between variables until after type legalisation.
It is then split into four scalar multiplications between variables,
which we select as multiplications rather than shifts.  With the
Scalarizer pass, we get one multiplication and three shifts.

You could argue that in this case, the target-specific CodeGen code
should be prepared to rewrite multiplications as shifts as a result
of later (CodeGen) constant propagation, but that isn't as easy for
more complicated chains of operations.

This wasn't a motivation, but: I believe there's a long-term plan
to move away from SelectionDAG-based instruction selection.  I was
hoping that doing scalarisation at the IR level would help with that.

More information about the llvm-commits mailing list