# IR question re: constants

I'm curious. Is there a specific technical reason that the high-level
IR doesn't have an instruction to simply set a register to a constant?
This limitation means we cannot hoist an "expensive" constant out of a
loop until we lower the IR to MachineInstrs. Or more to the point, it
forces backends to undo any such hoisting done by frontends.

Or am I not understanding something?

-David

The LLVM IR doesn't have registers. The computations are values and a constant represents itself.

-Krzysztof

On that note, you can hoist any constant yourself:

Define:
%blah = llvm.my.own.intrinsic C
Then have:
... = %blah
And lower the intrinsic to the value of its argument.

Alternatively, define
%blah = select i1 true, C, 0.
The instruction selection happens on a basic-block basis, so if that "select" is in its own block, it will not be propagated into other blocks at that time.

There are limitations to each such approach though. In the above cases, the intrinsic won't be "understood" by the optimizer, but it can be considered expensive. The select will be folded back into the constant if you do it too early, but this will allow further simplifications.

-Krzysztof

Krzysztof Parzyszek via llvm-dev <llvm-dev@lists.llvm.org> writes:

The LLVM IR doesn't have registers. The computations are values and a
constant represents itself.

Well, it certainly does have registers in the IR text but I understand
what you mean.

On that note, you can hoist any constant yourself:

Define:
%blah = llvm.my.own.intrinsic C
Then have:
... = %blah
And lower the intrinsic to the value of its argument.

We thought of this. Yuck. Loses all analysis and optimization.

Alternatively, define
%blah = select i1 true, C, 0.
The instruction selection happens on a basic-block basis, so if that
"select" is in its own block, it will not be propagated into other
blocks at that time.

I thought of this solution as well but there's no guarantee that some
pass won't fold the select back into the loop.

There are limitations to each such approach though. In the above
cases, the intrinsic won't be "understood" by the optimizer, but it
can be considered expensive. The select will be folded back into the
constant if you do it too early, but this will allow further
simplifications.

Yes. Both are undesirable. The select will always be generated "early"
because we need to generate IR out of our frontend anf we'd like to
preserve the hoisting that's already been done. Yet we still want to
run some LLVM optimization passes that could upset it.

This is a really unfortunate aspect of the IR.

-David