When folding a vmerge into its operands, if the resulting VL is smaller than
what the vmerge had originally then what was previously in its body then gets
moved to the tail. In that case, we can't relax the tail policy to agnostic
when the merge operand is undefined, since we need to preserve these elements
past the new VL.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | ||
---|---|---|
3512 | If instead, we were to change this line to: uint64_t Policy = isImplicitDef(False) ? RISCVII::TAIL_AGNOSTIC : /*TUMU*/ 0; What would happen? I'm worried there's some other case we haven't caught where Merge was implicit_def, but the resulting operation has a non-implicit_def result. I think *all* such cases needs to be TU. |
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | ||
---|---|---|
3512 | Answer: A lot of regressions. I tried this, and it definitely doesn't seem to work. I'm still a bit worried there's another case here. I don't have anything specific though. |
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | ||
---|---|---|
3512 | The new tail of the Result node is every element from min(vmerge.vl, true.vl) onwards. Therefore if we want to set a tail agnostic policy on it, we need to know that every element of vmerge from min(vmerge.vl, true.vl) onwards would have been implicit-def anyway. The vmerge pseudo gets its tail from Merge, so if the Merge at that element was implicit-def, then that tail element will be implicit-def. implicit-def(Merge[i]) We can rewrite this to implicit-def(Merge[i]) ∧ vmerge.vl == min(vmerge.vl, true.vl) So as long as we check isImplicitDef(Merge) and VL == OldVL, then we can infer the result implicit-def(vmerge[i]), min(vmerge.vl, true.vl) <= i < vlmax i.e. every element past min(vmerge.vl, true.vl) in vmerge would have been implicit-def. Btw I tried substituting Merge for False as well before posting the patch and got the same result. implicit(False) -> implicit(Merge) so as long as we also check the VL stays the same, it's a correct transformation, just not optimal. |
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | ||
---|---|---|
3512 | 80 columns |
I sat down and did the case analysis for all 9 combinations of policy states. We disallow certain combinations via early returns, and I believe that with this patch, all the other cases are covered correctly.
I think this might be a case where generalizing to handle the remaining cases actually simplifies and makes the code more obvious, but that's definitely a future patch!
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | ||
---|---|---|
3512 | Fixed in commit |
If instead, we were to change this line to:
What would happen? I'm worried there's some other case we haven't caught where Merge was implicit_def, but the resulting operation has a non-implicit_def result. I think *all* such cases needs to be TU.