It appears that vscale values truncated to i1 causes mismatches in the constant types when created in getNode. https://godbolt.org/z/TaaTo86ne.
Details
Diff Detail
Event Timeline
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | ||
---|---|---|
5754–5756 | SelectionDAG::getVScale does the right thing by truncating the APInt value, but it only does so after the assert: assert(MulImm.getSignificantBits() <= VT.getSizeInBits() && "Immediate does not fit VT"); which fails because for MulImm=1, MulImm.getSignificantBits() results in 2. This happens because it adds the sign bit, which for a 1-bit value is nonsensical. I think the better thing to do is to fix the assert itself. |
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | ||
---|---|---|
5754–5756 | I'm not sure it wouldn't be better for getVScale to only accept APInt of the correct bitwidth, to be more precise. I couldn't see any other code that looked like the APInt and the VT could be a mismatch. The new version just adds an override for i1 to the assert. Let me know what you think. |
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | ||
---|---|---|
1945 | I guess this still needs an additional check that for MVT::i1 the immediate fits, i.e. ... || (VT == MVT::i1 && MulImm <= 1) ? |
I was thinking about it, and I think it would be better to not be sloppy about the APInt passed to getVScale. Similar to existing methods in DAG like getConstant, we should be asserting that the size of the APInt and the type match. Otherwise it should be up to the caller to make them match in a way that is appropriate.
It appears from looking through the calls to getVScale that the version in getNode when truncating the value is the only one where they can be a mismatch.
Thanks for fixing this @dmgreen !
Any chance to land this soon? We (folks working on SVE/SSVE/SME support in MLIR) rely heavily on clang-aarch64-sve-vla that's currently failing.
That makes sense. I thought there would have been more instances that needed fixing, but glad to see that wasn't the case.
Thanks. I'll commit this now, just after my machine has finished rerunning the tests. Hopefully I didn't miss any cases for getVScale.
I guess this still needs an additional check that for MVT::i1 the immediate fits, i.e. ... || (VT == MVT::i1 && MulImm <= 1) ?