Teaching the ARM backend to set upper zero bits when performing a sign or zero extend allows to remove redundant masking.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13639 ↗ | (On Diff #179545) | IIUC we're computing here the known bits on the input vector operand. However, when computing the result of the VGETLANE operation we're not taking into account the lane operand, which seems wrong to me. We should have additional tests to cover both the sext and zext cases and cases where the lane operand is not zero. |
13656 ↗ | (On Diff #179545) | Is this assert unreachable? |
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13639 ↗ | (On Diff #179545) | Perhaps I've got it wrong, but from what I've seen is that computeKnownBits tells bits that are known to be zero or one in all vector elements (lanes). So it really does not matter which lane is being extracted. Even the width is the number of bits of a single element, not the entire vector. I'll add a signed extension test, to show that the behavior is the same. |
13656 ↗ | (On Diff #179545) | It is. Compiling fore release does not test it. Thanks. |
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13639 ↗ | (On Diff #179545) | computeKnownBits can takes DemandedElts mask to indicate the vector elements that you care about - see the ISD::EXTRACT_VECTOR_ELT code in SelectionDAG::computeKnownBits for an example of how it works. |
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13639 ↗ | (On Diff #179545) | Hi, thanks for the suggestion. I just couldn't find a straightforward test to capture such behavior, as most simplifications are done before extractelement gets replaced by VGETLANE. It doesn't seems to have an intrinsic as well. |
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13639 ↗ | (On Diff #179545) | Something that make use of the implicit sext/zext should be testable? IIRC we do something similar on X86 for PEXTRB/PEXTRW |
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13643 ↗ | (On Diff #179634) | I think this test should always evaluate to true. Maybe it should be an assert? |
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13643 ↗ | (On Diff #179634) | Don't know. Can't Pos be nullptr? That is, the position is not a constant value? (vector[variableX] ?) |
Removed treatment for out of bounds constant, as it is simplified to poison before being transformed to VGETLANE.
Also removed treatment for variable index, as it is not accepted by VGETLANE.
Added extra tests.
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13643 ↗ | (On Diff #179634) | Oh, I see that when creating these operands we only allow constant values. And trying llvm-mc it confirms it so. Sorry, did not get the suggestion. :) |
LGTM! (with one nit)
lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
13642 ↗ | (On Diff #180253) | Nit: you can use a cast<> instead of dyn_cast here and remove the assert. |
13643 ↗ | (On Diff #179634) | Yeah, sorry, I should have given a justification for that. These nodes are also used to only select instructions that have the lane encoded as an immediate. |