Currently, SelectionDAG assumes 8/16-bit cmpxchg returns either a sign
extended result, or a zero extended result. SystemZ takes a third
option by returning junk in the high bits (rotated contents of the other
bytes in the memory word). In that case, don't use Assert*ext, and
zero-extend the result ourselves if a comparison is needed.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
2863 | ISD::ZERO_EXTEND only takes one operand so the DAG.getValueType(AtomicType) argument isn't necessary. | |
2872 | I'm not sure why the ANY_EXTEND case returns ExtRes.getValue(0) instead of LHS.getValue(0). Is there a reason for it? I'm currently thinking that returning LHS allows SelectionDAG to take advantage of the additional known-zero bits from the zero extend but returning ExtRes allows more scheduling freedom because it can be used before the comparison completes. I'm not sure which is the better choice though. |
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
2872 | The comparison result may be unused and DCEd - in this case, it's better not to do the zero extension at all. |
LGTM with the tests changes.
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
2872 | That makes sense to me. ATOMIC_CMP_SWAP_WITH_SUCCESS is always a strong operation so it's not strange to ignore the success result. | |
test/CodeGen/SystemZ/cmpxchg-05.ll | ||
6–12 | This should check that the zero extend and comparison is not emitted in this test (and likewise below). I think there should also be a test that doesn't ignore the success result to check the comparison is as expected and also one that zero extends the success result to check that multiple zero extends don't occur. |
ISD::ZERO_EXTEND only takes one operand so the DAG.getValueType(AtomicType) argument isn't necessary.