Page MenuHomePhabricator

Don't mark convergent instructions as trivially rematerializable.
Needs ReviewPublic

Authored by jlebar on Feb 18 2016, 5:48 PM.



No testcase, as all convergent MIs I'm aware of already have unmodeled
side-effects, which is sufficient.

Diff Detail

Event Timeline

jlebar updated this revision to Diff 48440.Feb 18 2016, 5:48 PM
jlebar retitled this revision from to Don't mark convergent instructions as trivially rematerializable..
jlebar updated this object.
jlebar added a reviewer: echristo.
jlebar added subscribers: tra, llvm-commits.

My targets have convergent instructions that are rematerializable.


My targets have convergent instructions that are rematerializable.


Are they *trivially* rematerializable? The documentation says a trivially-rematerializable instr must have no side-effects and must have the same effect wherever it's placed in the function. But if you can move the instruction wherever you want, then in particular you can add a control-flow dependency, which is what's specifically disallowed by convergence.

Maybe the documentation needs to be updated? I admit that I don't yet have a non-superficial understanding of what this is *used* for.

I have convergent instructions that are essentially register->register arithmetic operations. I don't have any great dependence on them being rematerialized, but I wanted to point out that it's not inconceivable.

escha added a subscriber: escha.Feb 18 2016, 9:39 PM

I think any GPU register SIMD operation counts as convergent and trivially rematerializable as long as it doesn't have side-effects (even if it probably wouldn't be particularly useful to in most cases).

example: a hypothetical f32reduce x, y that summed the values of 'y' for all the threads in a warp and saved the result in x.

It's convergent because you need to run it when all the relevant threads are enabled, but it doesn't have any side-effects, so if the same vreg representing 'y' is still available unmodified and control flow is the same, you could repeat it, I think.

Thank you for your comments.

/// Return true if the instruction is trivially rematerializable, meaning it
/// has no side effects and requires no operands that aren't always available.
/// This means the only allowed uses are constants and unallocatable physical
/// registers so that the instructions result is independent of the place
/// in the function.
bool isTriviallyReMaterializable(const MachineInstr *MI

AIUI, this means our hypothetical f32reduce x, y is not trivially rematerializable, since its operands aren't always available.

I'm having difficulty imagining an op that has no side effects and requires no operands but which would nonetheless be unsafe to run while some threads are disabled (so is convergent). But would this putative instruction's result be independent of its place in the function? It seems not, since by assumption there is something different about running it while some threads are disabled vs when all threads are enabled.

Maybe I'm misunderstanding what it means when it says it requires no operands; I see LiveRangeEdit looking at the rematerializable instruction's inputs to check that they're available at the point to which it wants to move the instruction. But the issue of moving the instruction anywhere in a function -- not just elsewhere in a BB -- remains.

Friendly ping. Would be good to have this figured out before we all lose state. :)