Page MenuHomePhabricator

[AMDGPU] Skip CFIInstructions in SIInsertWaitcnts
ClosedPublic

Authored by scott.linder on Mar 26 2020, 12:21 PM.

Details

Summary

CFI emitted during PEI at the beginning of the prologue needs to apply
to any inserted waitcnts on function entry.

Diff Detail

Event Timeline

scott.linder created this revision.Mar 26 2020, 12:21 PM

git clang-format

arsenm added inline comments.Mar 26 2020, 1:21 PM
llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
1636

Why just CFI? Why not isMetaInstruction?

llvm/test/CodeGen/AMDGPU/waitcnt-skip-cfi.mir
3–9 ↗(On Diff #252965)

Shouldn't need IR section

Harbormaster completed remote builds in B50610: Diff 252965.
scott.linder marked an inline comment as done.Mar 26 2020, 2:28 PM
scott.linder added inline comments.
llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
1636

Seems reasonable to me. Is there a reason why isMetaInstruction doesn't include PHIs?

arsenm added inline comments.Mar 26 2020, 2:44 PM
llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
1636

It's a real instruction that will emit a copy

Skip all meta instructions, not just CFI

arsenm accepted this revision.Mar 26 2020, 4:08 PM
This revision is now accepted and ready to land.Mar 26 2020, 4:08 PM

I may have pushed this up to soon, I missed some tests, and after thinking it
through again I don't know if it is actually correct to put the DEBUG_VALUE
before the waitcnt if the waitcnt could be ensuring some writes are available?

dbg.value isn't supposed to change codegen, so always ignoring them seems like the correct choice?

Right, but the placement of the meta instructions here can't affect change codegen, can it? Also, if we do need to skip the DEBUG_VALUEs it may also be that we would need to either update or drop them to avoid producing incorrect debug info. I'm not actually certain this is an issue though, but the situation I have in mind is if we pass an argument by-ref or on the stack, and in the callee we claim the value is in memory when the appropriate counts haven't been waited on yet.

Right, but the placement of the meta instructions here can't affect change codegen, can it? Also, if we do need to skip the DEBUG_VALUEs it may also be that we would need to either update or drop them to avoid producing incorrect debug info. I'm not actually certain this is an issue though, but the situation I have in mind is if we pass an argument by-ref or on the stack, and in the callee we claim the value is in memory when the appropriate counts haven't been waited on yet.

Doesn't the placement of CFI matter relative to the real instructions?

Right, but the placement of the meta instructions here can't affect change codegen, can it? Also, if we do need to skip the DEBUG_VALUEs it may also be that we would need to either update or drop them to avoid producing incorrect debug info. I'm not actually certain this is an issue though, but the situation I have in mind is if we pass an argument by-ref or on the stack, and in the callee we claim the value is in memory when the appropriate counts haven't been waited on yet.

Doesn't the placement of CFI matter relative to the real instructions?

Yes, and same for DEBUG_VALUE, which is where my uncertainty comes up. For CFI we absolutely need the directives at the beginning of the block to precede any real instructions, because they apply "on entry". For example, we reference the ABI return address registers here, and we can't have these be defined incorrectly until after the initial s_waitcnt. Conversely for DEBUG_VALUEs it may be that we are constructing them assuming they can reference memory locations for arguments that are only valid after the initial s_waitcnt. So I think we need to handle the two cases distinctly.

Right, but the placement of the meta instructions here can't affect change codegen, can it? Also, if we do need to skip the DEBUG_VALUEs it may also be that we would need to either update or drop them to avoid producing incorrect debug info. I'm not actually certain this is an issue though, but the situation I have in mind is if we pass an argument by-ref or on the stack, and in the callee we claim the value is in memory when the appropriate counts haven't been waited on yet.

Doesn't the placement of CFI matter relative to the real instructions?

Yes, and same for DEBUG_VALUE, which is where my uncertainty comes up. For CFI we absolutely need the directives at the beginning of the block to precede any real instructions, because they apply "on entry". For example, we reference the ABI return address registers here, and we can't have these be defined incorrectly until after the initial s_waitcnt. Conversely for DEBUG_VALUEs it may be that we are constructing them assuming they can reference memory locations for arguments that are only valid after the initial s_waitcnt. So I think we need to handle the two cases distinctly.

ok

t-tye added a comment.Mar 27 2020, 2:20 PM

Right, but the placement of the meta instructions here can't affect change codegen, can it? Also, if we do need to skip the DEBUG_VALUEs it may also be that we would need to either update or drop them to avoid producing incorrect debug info. I'm not actually certain this is an issue though, but the situation I have in mind is if we pass an argument by-ref or on the stack, and in the callee we claim the value is in memory when the appropriate counts haven't been waited on yet.

Doesn't the placement of CFI matter relative to the real instructions?

Yes, and same for DEBUG_VALUE, which is where my uncertainty comes up. For CFI we absolutely need the directives at the beginning of the block to precede any real instructions, because they apply "on entry". For example, we reference the ABI return address registers here, and we can't have these be defined incorrectly until after the initial s_waitcnt. Conversely for DEBUG_VALUEs it may be that we are constructing them assuming they can reference memory locations for arguments that are only valid after the initial s_waitcnt. So I think we need to handle the two cases distinctly.

ok

From a debug information point of view, the memory is updated when the instruction is issued, regardless of the waitcnt having completed. The Debugger has to stop the wave before it can see that waves state. The act of stopping a wave ensures that all memory actions it has performed are made coherent with the debugger. That includes ensuring all outstanding operations are complete, and caches are flushed and written back.

Right, but the placement of the meta instructions here can't affect change codegen, can it? Also, if we do need to skip the DEBUG_VALUEs it may also be that we would need to either update or drop them to avoid producing incorrect debug info. I'm not actually certain this is an issue though, but the situation I have in mind is if we pass an argument by-ref or on the stack, and in the callee we claim the value is in memory when the appropriate counts haven't been waited on yet.

Doesn't the placement of CFI matter relative to the real instructions?

Yes, and same for DEBUG_VALUE, which is where my uncertainty comes up. For CFI we absolutely need the directives at the beginning of the block to precede any real instructions, because they apply "on entry". For example, we reference the ABI return address registers here, and we can't have these be defined incorrectly until after the initial s_waitcnt. Conversely for DEBUG_VALUEs it may be that we are constructing them assuming they can reference memory locations for arguments that are only valid after the initial s_waitcnt. So I think we need to handle the two cases distinctly.

ok

From a debug information point of view, the memory is updated when the instruction is issued, regardless of the waitcnt having completed. The Debugger has to stop the wave before it can see that waves state. The act of stopping a wave ensures that all memory actions it has performed are made coherent with the debugger. That includes ensuring all outstanding operations are complete, and caches are flushed and written back.

Ok, that makes sense, in that case I do think that the patch is correct as-is, skipping all meta instructions.

This revision was automatically updated to reflect the committed changes.