-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RDDSP operands are added too late #27490
Comments
I don't think how early the implicit uses are added is the whole problem. When InstrEmitter::EmitMachineNode() processes the implicit-def in the CMPU_EQ_Qb instruction, it doesn't see a MVT::Glue value and doesn't see the RDDSP instruction. As a result, it wouldn't see the implicit-use even if it were there. Shouldn't this function be following both the chain and the glue? I only see code for the glue. |
I forgot to mention that I've been looking into moving the addition of the implicit-uses to the hasPostISelHook mechanism. This is still too late at the moment but it's very close. |
I've posted my current experimental patch at http://reviews.llvm.org/differential/diff/52368/ to help me explain why I think there's more to this. Aside from some debug-related noise, this patch moves RDDSP/WRDSP's implicit-use/implicit-def handling into the hasPostISelHook mechanism and moves that mechanism before the call to setPhysRegsDeadExcept(). If I run a test that only contains the failing function from dsp-r1.ll, it emits the output at the bottom of this comment. The interesting bit is between the '{ CMPU_...' and '} CMPU_...' lines which shows that %DSPCCond is declared dead without looking at the RDDSP. This is because it's only looking at uses in the glue chain. I believe it should be looking at the output chain as well. If we were to search the output chain as well, we would then find the RDDSP but would only consult the statically defined implicit-defs/implicit-uses in the MCInstrDesc objects. In the case of RDDSP/WRDSP, these are currently calculated from the immediate and are added in the post-ISel hook. This can be solved by iterating over the implicit_operands() of the newly created instruction but we don't appear to have enough liveness information to get the dead flag correct and the safe assumption (always live) harms register allocation*. At this point I don't see a simple way to fix the crash while preserving the dynamically generated implicit-defs/implicit-uses. Does anyone have any suggestions? If not, I'll probably have to make RDDSP/WRDSP say they always act on the whole dsp control register. This will harm code quality but hopefully it will only be a tiny amount.
Output:
In Register ScavengerMachine code for function test__builtin_mips_cmpu_eq_qb1: Properties: : Post SSAFunction Live Ins: %A1, %A2 BB#0: derived from LLVM BB %entry End machine code for function test__builtin_mips_cmpu_eq_qb1.*** Bad machine code: Using an undefined physical register ***
|
I think if the operands are just added to the MachineInstr it is too late either way as the InstrEmitter code only looks at the selection DAG nodes and the MCInstrDesc. With the current code we would need additional SDNode operands to show the reads/writes, maybe there is a way to produce CopyFromReg/CopyToReg in a custom lower callback? I am not sure why we deal with adding dead flags in code selection at all. The liveness calculations (LiveVariables + LiveIntervalAnalysis) can both detect them so the allocation should be the same. The only register allocator affected would be FastRegAlloc which is designed for compile time first anyway. The fact that we add a dead flag to a reserved register is also very odd but indeed harmless as none of the liveness based architecture depends on it. Note that this issue can be low priority at the moment. The issue mainly popped up because I am in the process of adding a new pass (DetectDeadLanes) which uses a more precise dataflow analysis across COPY-like instructions to find dead/unused operands. I just needed the LiveVariables pass to not remove the dead flags added by the more precise analysis, luckily this only affects virtual regs, so I left the code that removes dead flags from physregs in. |
Extended Description
The RDDSPs operands are currently added in MipsSEDAGToDAGISel::processFunctionAfterISel(), if they are the only user of a physreg then these physreg will appear dead during the earlier InstrEmitter phase of selection dag, so some defs will be incorrectly marked as dead.
This is currently not a problem because the LiveVariables pass happens to reset all dead flags, however long term we plan to remove the whole LiveVariables pass.
(The problem is visible in some functions in test/CodeGen/Mips/dsp-r1.ll when dead flag removal is disabled in the LiveVariables pass.)
The text was updated successfully, but these errors were encountered: