Index: llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -1710,6 +1710,29 @@ llvm_unreachable("cannot find MemSDNode in the pattern!"); } +/// Split \p COffsetVal into {immediate offset field, remainder offset} values. +static std::pair splitFlatOffset(int64_t COffsetVal, + const SIInstrInfo *TII, + unsigned AddrSpace, + bool IsSigned) { + int64_t RemainderOffset = COffsetVal; + int64_t ImmField = 0; + const unsigned NumBits = TII->getNumFlatOffsetBits(IsSigned); + if (IsSigned) { + // Use signed division by a power of two to truncate towards 0. + int64_t D = 1LL << (NumBits - 1); + RemainderOffset = (static_cast(COffsetVal) / D) * D; + ImmField = COffsetVal - RemainderOffset; + } else if (static_cast(COffsetVal) >= 0) { + ImmField = COffsetVal & maskTrailingOnes(NumBits); + RemainderOffset = COffsetVal - ImmField; + } + + assert(TII->isLegalFLATOffset(ImmField, AddrSpace, IsSigned)); + assert(RemainderOffset + ImmField == COffsetVal); + return {ImmField, RemainderOffset}; +} + template bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N, SDValue Addr, @@ -1742,22 +1765,10 @@ // into two pieces that are both >= 0 or both <= 0. SDLoc DL(N); - uint64_t RemainderOffset = COffsetVal; - uint64_t ImmField = 0; - const unsigned NumBits = TII->getNumFlatOffsetBits(IsSigned); - if (IsSigned) { - // Use signed division by a power of two to truncate towards 0. - int64_t D = 1LL << (NumBits - 1); - RemainderOffset = (static_cast(COffsetVal) / D) * D; - ImmField = COffsetVal - RemainderOffset; - } else if (static_cast(COffsetVal) >= 0) { - ImmField = COffsetVal & maskTrailingOnes(NumBits); - RemainderOffset = COffsetVal - ImmField; - } - assert(TII->isLegalFLATOffset(ImmField, AS, IsSigned)); - assert(RemainderOffset + ImmField == COffsetVal); + uint64_t RemainderOffset; - OffsetVal = ImmField; + std::tie(OffsetVal, RemainderOffset) + = splitFlatOffset(COffsetVal, TII, AS, IsSigned); SDValue AddOffsetLo = getMaterializedScalarImm32(Lo_32(RemainderOffset), DL);