diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 0a6314a..ef0ec72 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -1137,7 +1137,7 @@ XLogInsertRecord(XLogRecData *rdata,
 			EndPos = StartPos + SizeOfXLogRecord;
 			if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
 			{
-				if (EndPos % XLOG_SEG_SIZE == EndPos % XLOG_BLCKSZ)
+				if (XLogSegmentOffset(EndPos) == EndPos % XLOG_BLCKSZ)
 					EndPos += SizeOfXLogLongPHD;
 				else
 					EndPos += SizeOfXLogShortPHD;
@@ -1296,7 +1296,7 @@ ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 	startbytepos = Insert->CurrBytePos;
 
 	ptr = XLogBytePosToEndRecPtr(startbytepos);
-	if (ptr % XLOG_SEG_SIZE == 0)
+	if (XLogSegmentOffset(ptr) == 0)
 	{
 		SpinLockRelease(&Insert->insertpos_lck);
 		*EndPos = *StartPos = ptr;
@@ -1309,7 +1309,7 @@ ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 	*StartPos = XLogBytePosToRecPtr(startbytepos);
 	*EndPos = XLogBytePosToEndRecPtr(endbytepos);
 
-	segleft = XLOG_SEG_SIZE - ((*EndPos) % XLOG_SEG_SIZE);
+	segleft = XLOG_SEG_SIZE - (XLogSegmentOffset(*EndPos));
 	if (segleft != XLOG_SEG_SIZE)
 	{
 		/* consume the rest of the segment */
@@ -1323,7 +1323,7 @@ ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
 	*PrevPtr = XLogBytePosToRecPtr(prevbytepos);
 
-	Assert((*EndPos) % XLOG_SEG_SIZE == 0);
+	Assert(XLogSegmentOffset(*EndPos) == 0);
 	Assert(XLogRecPtrToBytePos(*EndPos) == endbytepos);
 	Assert(XLogRecPtrToBytePos(*StartPos) == startbytepos);
 	Assert(XLogRecPtrToBytePos(*PrevPtr) == prevbytepos);
@@ -1501,7 +1501,7 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
 			pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
 
 			/* skip over the page header */
-			if (CurrPos % XLogSegSize == 0)
+			if (XLogSegmentOffset(CurrPos) == 0)
 			{
 				CurrPos += SizeOfXLogLongPHD;
 				currpos += SizeOfXLogLongPHD;
@@ -1532,7 +1532,7 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
 	 * allocated and zeroed in the WAL buffers so that when the caller (or
 	 * someone else) does XLogWrite(), it can really write out all the zeros.
 	 */
-	if (isLogSwitch && CurrPos % XLOG_SEG_SIZE != 0)
+	if (isLogSwitch && XLogSegmentOffset(CurrPos) != 0)
 	{
 		/* An xlog-switch record doesn't contain any data besides the header */
 		Assert(write_len == SizeOfXLogRecord);
@@ -1541,7 +1541,7 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
 		 * We do this one page at a time, to make sure we don't deadlock
 		 * against ourselves if wal_buffers < XLOG_SEG_SIZE.
 		 */
-		Assert(EndPos % XLogSegSize == 0);
+		Assert(XLogSegmentOffset(EndPos) == 0);
 
 		/* Use up all the remaining space on the first page */
 		CurrPos += freespace;
@@ -1866,10 +1866,10 @@ GetXLogBuffer(XLogRecPtr ptr)
 		 * the page header.
 		 */
 		if (ptr % XLOG_BLCKSZ == SizeOfXLogShortPHD &&
-			ptr % XLOG_SEG_SIZE > XLOG_BLCKSZ)
+			XLogSegmentOffset(ptr) > XLOG_BLCKSZ)
 			initializedUpto = ptr - SizeOfXLogShortPHD;
 		else if (ptr % XLOG_BLCKSZ == SizeOfXLogLongPHD &&
-				 ptr % XLOG_SEG_SIZE < XLOG_BLCKSZ)
+				 XLogSegmentOffset(ptr) < XLOG_BLCKSZ)
 			initializedUpto = ptr - SizeOfXLogLongPHD;
 		else
 			initializedUpto = ptr;
@@ -2003,7 +2003,7 @@ XLogRecPtrToBytePos(XLogRecPtr ptr)
 
 	XLByteToSeg(ptr, fullsegs);
 
-	fullpages = (ptr % XLOG_SEG_SIZE) / XLOG_BLCKSZ;
+	fullpages = (XLogSegmentOffset(ptr)) / XLOG_BLCKSZ;
 	offset = ptr % XLOG_BLCKSZ;
 
 	if (fullpages == 0)
@@ -2168,7 +2168,7 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic)
 		/*
 		 * If first page of an XLOG segment file, make it a long header.
 		 */
-		if ((NewPage->xlp_pageaddr % XLogSegSize) == 0)
+		if ((XLogSegmentOffset(NewPage->xlp_pageaddr)) == 0)
 		{
 			XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
 
@@ -2422,7 +2422,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 		{
 			/* first of group */
 			startidx = curridx;
-			startoffset = (LogwrtResult.Write - XLOG_BLCKSZ) % XLogSegSize;
+			startoffset = XLogSegmentOffset(LogwrtResult.Write - XLOG_BLCKSZ);
 		}
 		npages++;
 
@@ -3743,7 +3743,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
 	bool		use_existent;
 
 	XLByteToPrevSeg(endptr, _logSegNo);
-	if ((endptr - 1) % XLogSegSize >= (uint32) (0.75 * XLogSegSize))
+	if (XLogSegmentOffset(endptr - 1) >= (uint32) (0.75 * XLogSegSize))
 	{
 		_logSegNo++;
 		use_existent = true;
@@ -4193,7 +4193,7 @@ ReadRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode,
 			int32		offset;
 
 			XLByteToSeg(xlogreader->latestPagePtr, segno);
-			offset = xlogreader->latestPagePtr % XLogSegSize;
+			offset = XLogSegmentOffset(xlogreader->latestPagePtr);
 			XLogFileName(fname, xlogreader->readPageTLI, segno);
 			ereport(emode_for_corrupt_record(emode,
 											 RecPtr ? RecPtr : EndRecPtr),
@@ -5516,7 +5516,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
 		 * avoid emplacing a bogus file.
 		 */
 		XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
-					 endOfLog % XLOG_SEG_SIZE);
+					 XLogSegmentOffset(endOfLog));
 	}
 	else
 	{
@@ -7475,7 +7475,7 @@ StartupXLOG(void)
 		XLogRecPtr	pageBeginPtr;
 
 		pageBeginPtr = EndOfLog - (EndOfLog % XLOG_BLCKSZ);
-		Assert(readOff == pageBeginPtr % XLogSegSize);
+		Assert(readOff == XLogSegmentOffset(pageBeginPtr));
 
 		firstIdx = XLogRecPtrToBufIdx(EndOfLog);
 
@@ -7624,7 +7624,7 @@ StartupXLOG(void)
 		 * restored from the archive to begin with, it's expected to have a
 		 * .done file).
 		 */
-		if (EndOfLog % XLOG_SEG_SIZE != 0 && XLogArchivingActive())
+		if (XLogSegmentOffset(EndOfLog) != 0 && XLogArchivingActive())
 		{
 			char		origfname[MAXFNAMELEN];
 			XLogSegNo	endLogSegNo;
@@ -8673,7 +8673,7 @@ CreateCheckPoint(int flags)
 	freespace = INSERT_FREESPACE(curInsert);
 	if (freespace == 0)
 	{
-		if (curInsert % XLogSegSize == 0)
+		if (XLogSegmentOffset(curInsert) == 0)
 			curInsert += SizeOfXLogLongPHD;
 		else
 			curInsert += SizeOfXLogShortPHD;
@@ -10952,7 +10952,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 	 */
 	XLByteToSeg(startpoint, _logSegNo);
 	BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logSegNo,
-						  (uint32) (startpoint % XLogSegSize));
+						  (uint32) (XLogSegmentOffset(startpoint)));
 	fp = AllocateFile(histfilepath, "w");
 	if (!fp)
 		ereport(ERROR,
@@ -11006,7 +11006,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
 		XLByteToSeg(startpoint, _logSegNo);
 		BackupHistoryFileName(histfilename, ThisTimeLineID, _logSegNo,
-							  (uint32) (startpoint % XLogSegSize));
+							  (uint32) (XLogSegmentOffset(startpoint)));
 
 		seconds_before_warning = 60;
 		waits = 0;
@@ -11450,7 +11450,7 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
 	XLogSegNo	targetSegNo PG_USED_FOR_ASSERTS_ONLY;
 
 	XLByteToSeg(targetPagePtr, targetSegNo);
-	targetPageOff = targetPagePtr % XLogSegSize;
+	targetPageOff = XLogSegmentOffset(targetPagePtr);
 
 	/*
 	 * See if we need to switch to a new segment because the requested record
@@ -11517,7 +11517,7 @@ retry:
 		if (((targetPagePtr) / XLOG_BLCKSZ) != (receivedUpto / XLOG_BLCKSZ))
 			readLen = XLOG_BLCKSZ;
 		else
-			readLen = receivedUpto % XLogSegSize - targetPageOff;
+			readLen = XLogSegmentOffset(receivedUpto) - targetPageOff;
 	}
 	else
 		readLen = XLOG_BLCKSZ;
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index f9b49ba..c4e8492 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -498,7 +498,7 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS)
 	/*
 	 * offset
 	 */
-	xrecoff = locationpoint % XLogSegSize;
+	xrecoff = XLogSegmentOffset(locationpoint);
 
 	values[1] = UInt32GetDatum(xrecoff);
 	isnull[1] = false;
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 0781a7b..60523d1 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -467,7 +467,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
 	{
 		/* Pretend it extends to end of segment */
 		state->EndRecPtr += XLogSegSize - 1;
-		state->EndRecPtr -= state->EndRecPtr % XLogSegSize;
+		state->EndRecPtr -= XLogSegmentOffset(state->EndRecPtr);
 	}
 
 	if (DecodeXLogRecord(state, record, errormsg))
@@ -510,7 +510,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
 	Assert((pageptr % XLOG_BLCKSZ) == 0);
 
 	XLByteToSeg(pageptr, targetSegNo);
-	targetPageOff = (pageptr % XLogSegSize);
+	targetPageOff = XLogSegmentOffset(pageptr);
 
 	/* check whether we have all the requested data already */
 	if (targetSegNo == state->readSegNo && targetPageOff == state->readOff &&
@@ -720,7 +720,7 @@ ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr,
 	Assert((recptr % XLOG_BLCKSZ) == 0);
 
 	XLByteToSeg(recptr, segno);
-	offset = recptr % XLogSegSize;
+	offset = XLogSegmentOffset(recptr);
 
 	XLogSegNoOffsetToRecPtr(segno, offset, recaddr);
 
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index bbae733..c8f234e 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -676,7 +676,7 @@ XLogRead(char *buf, TimeLineID tli, XLogRecPtr startptr, Size count)
 		int			segbytes;
 		int			readbytes;
 
-		startoff = recptr % XLogSegSize;
+		startoff = XLogSegmentOffset(recptr);
 
 		/* Do we need to switch to a different xlog segment? */
 		if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo) ||
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index e48ebd5..f14f23a 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -624,7 +624,7 @@ CheckArchiveTimeout(void)
 			 * If the returned pointer points exactly to a segment boundary,
 			 * assume nothing happened.
 			 */
-			if ((switchpoint % XLogSegSize) != 0)
+			if (XLogSegmentOffset(switchpoint) != 0)
 				elog(DEBUG1, "write-ahead log switch forced (archive_timeout=%d)",
 					 XLogArchiveTimeout);
 		}
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 8a249e2..c236c57 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -989,7 +989,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
 		}
 
 		/* Calculate the start offset of the received logs */
-		startoff = recptr % XLogSegSize;
+		startoff = XLogSegmentOffset(recptr);
 
 		if (startoff + nbytes > XLogSegSize)
 			segbytes = XLogSegSize - startoff;
diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c
index 8ed7254..a7338dd 100644
--- a/src/backend/replication/walreceiverfuncs.c
+++ b/src/backend/replication/walreceiverfuncs.c
@@ -233,8 +233,8 @@ RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo,
 	 * being created by XLOG streaming, which might cause trouble later on if
 	 * the segment is e.g archived.
 	 */
-	if (recptr % XLogSegSize != 0)
-		recptr -= recptr % XLogSegSize;
+	if (XLogSegmentOffset(recptr) != 0)
+		recptr -= XLogSegmentOffset(recptr);
 
 	SpinLockAcquire(&walrcv->mutex);
 
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index f845180..4694b73 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -2310,7 +2310,7 @@ retry:
 		int			segbytes;
 		int			readbytes;
 
-		startoff = recptr % XLogSegSize;
+		startoff = XLogSegmentOffset(recptr);
 
 		if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo))
 		{
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 3ad0699..be754a5 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -26,6 +26,7 @@
 #include <zlib.h>
 #endif
 
+#include "access/xlog_internal.h"
 #include "common/file_utils.h"
 #include "common/string.h"
 #include "fe_utils/string_utils.h"
@@ -555,7 +556,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
 	}
 	param->startptr = ((uint64) hi) << 32 | lo;
 	/* Round off to even segment position */
-	param->startptr -= param->startptr % XLOG_SEG_SIZE;
+	param->startptr -= XLogSegmentOffset(param->startptr);
 
 #ifndef WIN32
 	/* Create our background pipe */
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index f3c7668..144823d 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -397,7 +397,7 @@ StreamLog(void)
 	/*
 	 * Always start streaming at the beginning of a segment
 	 */
-	stream.startpos -= stream.startpos % XLOG_SEG_SIZE;
+	stream.startpos -= XLogSegmentOffset(stream.startpos);
 
 	/*
 	 * Start the replication
diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
index 15932c6..7b842a5 100644
--- a/src/bin/pg_basebackup/receivelog.c
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -674,7 +674,7 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
 			 * start streaming at the beginning of a segment.
 			 */
 			stream->timeline = newtimeline;
-			stream->startpos = stream->startpos - (stream->startpos % XLOG_SEG_SIZE);
+			stream->startpos = stream->startpos - XLogSegmentOffset(stream->startpos);
 			continue;
 		}
 		else if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -1109,7 +1109,7 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
 	*blockpos = fe_recvint64(&copybuf[1]);
 
 	/* Extract WAL location for this block */
-	xlogoff = *blockpos % XLOG_SEG_SIZE;
+	xlogoff = XLogSegmentOffset(*blockpos);
 
 	/*
 	 * Verify that the initial location in the stream matches where we think
@@ -1180,7 +1180,7 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
 		xlogoff += bytes_to_write;
 
 		/* Did we reach the end of a WAL segment? */
-		if (*blockpos % XLOG_SEG_SIZE == 0)
+		if (XLogSegmentOffset(*blockpos) == 0)
 		{
 			if (!close_walfile(stream, *blockpos))
 				/* Error message written in close_walfile() */
diff --git a/src/bin/pg_rewind/parsexlog.c b/src/bin/pg_rewind/parsexlog.c
index 1befdbd..c5e00da 100644
--- a/src/bin/pg_rewind/parsexlog.c
+++ b/src/bin/pg_rewind/parsexlog.c
@@ -170,7 +170,7 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex,
 	 * header in that case to find the next record.
 	 */
 	if (forkptr % XLOG_BLCKSZ == 0)
-		forkptr += (forkptr % XLogSegSize == 0) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD;
+		forkptr += (XLogSegmentOffset(forkptr) == 0) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD;
 
 	private.datadir = datadir;
 	private.tliIndex = tliIndex;
@@ -241,7 +241,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
 
 	XLByteToSeg(targetPagePtr, targetSegNo);
 	XLogSegNoOffsetToRecPtr(targetSegNo + 1, 0, targetSegEnd);
-	targetPageOff = targetPagePtr % XLogSegSize;
+	targetPageOff = XLogSegmentOffset(targetPagePtr);
 
 	/*
 	 * See if we need to switch to a new segment because the requested record
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 81ec3e3..ed73ffe 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -244,7 +244,7 @@ XLogDumpXLogRead(const char *directory, TimeLineID timeline_id,
 		int			segbytes;
 		int			readbytes;
 
-		startoff = recptr % XLogSegSize;
+		startoff = XLogSegmentOffset(recptr);
 
 		if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo))
 		{
@@ -1028,7 +1028,7 @@ main(int argc, char **argv)
 	 * to the start of a record and also wasn't a pointer to the beginning of
 	 * a segment (e.g. we were used in file mode).
 	 */
-	if (first_record != private.startptr && (private.startptr % XLogSegSize) != 0)
+	if (first_record != private.startptr && XLogSegmentOffset(private.startptr) != 0)
 		printf(_("first record is after %X/%X, at %X/%X, skipping over %u bytes\n"),
 			   (uint32) (private.startptr >> 32), (uint32) private.startptr,
 			   (uint32) (first_record >> 32), (uint32) first_record,
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index a661ec0..3fee2ee 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -95,6 +95,9 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
 #define XLogSegNoOffsetToRecPtr(segno, offset, dest) \
 		(dest) = (segno) * XLOG_SEG_SIZE + (offset)
 
+#define XLogSegmentOffset(xlogptr)	\
+	((xlogptr) & (XLogSegSize - 1))
+
 /*
  * Compute ID and segment from an XLogRecPtr.
  *
