[LLVMdev] RFC: Missing canonicalization in LLVM

Chandler Carruth chandlerc at gmail.com
Wed Jan 21 15:02:46 PST 2015


On Wed, Jan 21, 2015 at 2:43 PM, Pete Cooper <peter_cooper at apple.com> wrote:

> The first thing that springs to mind is that I don’t trust the backend to
> get this right.  I don’t think it will understand when an i32 load/store
> would have been preferable to a float one or vice versa.  I have no
> evidence of this, but given how strongly typed tablegen is, I don’t think
> it can make a good choice here.
>

I don't think tablegen is relevant to making a good choice here. This only
comes up when we have a load which is only ever stored. See below, I'll
come back to this after clarifying...


>
> So I think we probably need to teach the backend how to undo whatever
> canonical form we choose if it has a reason to.  And the best long term
> solution is for tablegen to have sized load/stores, not typed ones.
>
> One (potentially expensive) way to choose the canonical form here is to
> look at the users of the load and see what type works best.  If we load an
> i32, but bit cast and do an fp operation on it, then a float load was
> best.  If we just load it then store, then in theory either type works.
>

We actually already do this. =] I tought instcombine to do this recently.
The way this works is as follows:

If we find a load with a single bitcast of its value to some other type, we
try to load that type instead. We rely on the fact that if there is in fact
a single type that the load is used as, some other part of LLVM will fold
the redundant bitcasts. I can easily handle redundant bitcasts if you like.

If we find a store of a bitcasted value, we try to store the original value
instead.

This works really well *except* for the case when the only (transitive)
users of the loaded value are themselves stores. In that case, there is no
"truth" we can rely on from operational semantics. We need to just pick a
consistent answer IMO. Integers seem like the right consistent answer, and
this isn't the only place LLVM does this -- we also lower a small memcpy as
an integer load and store.

As for the backend, I agree I don't trust them to do anything clever here,
but I think you may be missing how clever they would need to be. =D The
only way this matters is that, for example, you have a store-to-load
forwarding unit in your CPU that only works within a register class, and
thus a stored integer will fail to get forwarded in the CPU to a load of a
floating point value at the same address. If LLVM is ever able to forward
this in the IR, it should re-write all the types to match whatever
operation we have.

I don't think any backend today (or in the foreseeable future) would have
such smarts. But if CPUs are actually impacted by this kind of thing (and I
have no evidence that they are), we might be getting lucky some of the time.

Personally, I don't think this is compelling enough to delay making a
change because i have test cases where we are getting *unlucky* today, and
picking a canonical form will either directly fix them or make it much
easier to fix them.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150121/b61b7282/attachment.html>


More information about the llvm-dev mailing list