The offset values may result in an erroneous scheduling of a load before write for a memory location if the offset values are represented as negative values in MIR, despite actually being unsigned values. This representation in MIR happens as SelectionDAG::getConstant could go through APInt to represent the encoding which assumes the MSB of the encoding as a sign-bit, regardless of whether it is supposed to be a signed value. The 8-bit negative (interpreted) value gets cast to an unsigned 32 bit value in getMemOperandsWithOffset used for comparisons in areMemAccessesTriviallyDisjoint eventually leading to an erroneous schedule in the machine scheduler.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | ||
---|---|---|
332–333 | Don't need to involve APInt? Just use int64_t like every imm operand really is |
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | ||
---|---|---|
332–333 | The added tests will fail in that case, Offset0Op->getImm() returns a negative value while the operand is supposed to be unsigned so we need to force unsigned type for the correct number of bits. I could change to uint8_t since it seems that all cases of this instruction will have 8 bit operands for the offsets. |
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | ||
---|---|---|
332–333 |
llvm/test/CodeGen/AMDGPU/triv-disjoint-mem-access-neg-offset.mir | ||
---|---|---|
2 | It should be able to figure out it's mir without -x Can you run just the scheduler instead of -start-after? |
LGTM but please try to cut down the test case some more. Usually you only need name:, tracksRegLiveness: and body:.
Don't need to involve APInt? Just use int64_t like every imm operand really is