From 69aaf3604708dc9b704d58ba8ef5592c5957e25b Mon Sep 17 00:00:00 2001
From: Paul Amonson <paul.d.amonson@intel.com>
Date: Mon, 26 Aug 2024 09:18:04 -0700
Subject: [PATCH] [Feat] Targeted use of legacy crc32c.

Signed-off-by: Paul Amonson <paul.d.amonson@intel.com>
---
 configure                                   |  2 +-
 configure.ac                                |  2 +-
 src/backend/access/transam/xlog.c           |  8 ++++----
 src/backend/access/transam/xlogreader.c     |  2 +-
 src/backend/replication/logical/origin.c    |  8 ++++----
 src/backend/replication/logical/snapbuild.c |  4 ++--
 src/backend/utils/cache/relmapper.c         |  4 ++--
 src/bin/pg_resetwal/pg_resetwal.c           |  2 +-
 src/bin/pg_rewind/pg_rewind.c               |  2 +-
 src/common/controldata_utils.c              |  4 ++--
 src/include/port/pg_crc32c.h                | 17 +++++++++--------
 src/port/meson.build                        |  2 ++
 12 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/configure b/configure
index fca02db11d..f78b4c2890 100755
--- a/configure
+++ b/configure
@@ -18114,7 +18114,7 @@ else
 
 $as_echo "#define USE_AVX512_CRC32C_WITH_RUNTIME_CHECK 1" >>confdefs.h
 
-    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_avx512_choose.o"
+    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_avx512_choose.o pg_crc32c_sse42.o pg_crc32c_sb8.o"
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: AVX 512 with runtime check" >&5
 $as_echo "AVX 512 with runtime check" >&6; }
   else
diff --git a/configure.ac b/configure.ac
index ce68dce9d2..13172a0295 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2215,7 +2215,7 @@ if test x"$USE_SSE42_CRC32C" = x"1"; then
 else
   if test x"$USE_AVX512_CRC32C_WITH_RUNTIME_CHECK" = x"1"; then
     AC_DEFINE(USE_AVX512_CRC32C_WITH_RUNTIME_CHECK, 1, [Define to 1 to use Intel AVX 512 CRC instructions with a runtime check.])
-    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_avx512_choose.o"
+    PG_CRC32C_OBJS="pg_crc32c_avx512.o pg_crc32c_sb8.o pg_crc32c_avx512_choose.o pg_crc32c_sse42.o pg_crc32c_sb8.o"
     AC_MSG_RESULT(AVX 512 with runtime check)
   else
     if test x"$USE_SSE42_CRC32C_WITH_RUNTIME_CHECK" = x"1"; then
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index ee0fb0e28f..23c465d08f 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -910,7 +910,7 @@ XLogInsertRecord(XLogRecData *rdata,
 		 * header.
 		 */
 		rdata_crc = rechdr->xl_crc;
-		COMP_CRC32C(rdata_crc, rechdr, offsetof(XLogRecord, xl_crc));
+		COMP_CRC32C_SMALL(rdata_crc, rechdr, offsetof(XLogRecord, xl_crc));
 		FIN_CRC32C(rdata_crc);
 		rechdr->xl_crc = rdata_crc;
 
@@ -4258,7 +4258,7 @@ WriteControlFile(void)
 
 	/* Contents are protected with a CRC */
 	INIT_CRC32C(ControlFile->crc);
-	COMP_CRC32C(ControlFile->crc,
+	COMP_CRC32C_SMALL(ControlFile->crc,
 				(char *) ControlFile,
 				offsetof(ControlFileData, crc));
 	FIN_CRC32C(ControlFile->crc);
@@ -4376,7 +4376,7 @@ ReadControlFile(void)
 
 	/* Now check the CRC. */
 	INIT_CRC32C(crc);
-	COMP_CRC32C(crc,
+	COMP_CRC32C_SMALL(crc,
 				(char *) ControlFile,
 				offsetof(ControlFileData, crc));
 	FIN_CRC32C(crc);
@@ -5101,7 +5101,7 @@ BootStrapXLOG(uint32 data_checksum_version)
 
 	INIT_CRC32C(crc);
 	COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
-	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	COMP_CRC32C_SMALL(crc, (char *) record, offsetof(XLogRecord, xl_crc));
 	FIN_CRC32C(crc);
 	record->xl_crc = crc;
 
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 0c5e040a94..fdededf9a4 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1200,7 +1200,7 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
 	INIT_CRC32C(crc);
 	COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
 	/* include the record header last */
-	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	COMP_CRC32C_SMALL(crc, (char *) record, offsetof(XLogRecord, xl_crc));
 	FIN_CRC32C(crc);
 
 	if (!EQ_CRC32C(record->xl_crc, crc))
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 419e4814f0..3590f75c77 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -615,7 +615,7 @@ CheckPointReplicationOrigin(void)
 				 errmsg("could not write to file \"%s\": %m",
 						tmppath)));
 	}
-	COMP_CRC32C(crc, &magic, sizeof(magic));
+	COMP_CRC32C_SMALL(crc, &magic, sizeof(magic));
 
 	/* prevent concurrent creations/drops */
 	LWLockAcquire(ReplicationOriginLock, LW_SHARED);
@@ -658,7 +658,7 @@ CheckPointReplicationOrigin(void)
 							tmppath)));
 		}
 
-		COMP_CRC32C(crc, &disk_state, sizeof(disk_state));
+		COMP_CRC32C_SMALL(crc, &disk_state, sizeof(disk_state));
 	}
 
 	LWLockRelease(ReplicationOriginLock);
@@ -750,7 +750,7 @@ StartupReplicationOrigin(void)
 					 errmsg("could not read file \"%s\": read %d of %zu",
 							path, readBytes, sizeof(magic))));
 	}
-	COMP_CRC32C(crc, &magic, sizeof(magic));
+	COMP_CRC32C_SMALL(crc, &magic, sizeof(magic));
 
 	if (magic != REPLICATION_STATE_MAGIC)
 		ereport(PANIC,
@@ -790,7 +790,7 @@ StartupReplicationOrigin(void)
 							path, readBytes, sizeof(disk_state))));
 		}
 
-		COMP_CRC32C(crc, &disk_state, sizeof(disk_state));
+		COMP_CRC32C_SMALL(crc, &disk_state, sizeof(disk_state));
 
 		if (last_state == max_replication_slots)
 			ereport(PANIC,
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index ae676145e6..6362dfabeb 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1741,7 +1741,7 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 	/* update catchange only on disk data */
 	ondisk->builder.catchange.xcnt = catchange_xcnt;
 
-	COMP_CRC32C(ondisk->checksum,
+	COMP_CRC32C_SMALL(ondisk->checksum,
 				&ondisk->builder,
 				sizeof(SnapBuild));
 
@@ -1917,7 +1917,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 
 	/* read SnapBuild */
 	SnapBuildRestoreContents(fd, (char *) &ondisk.builder, sizeof(SnapBuild), path);
-	COMP_CRC32C(checksum, &ondisk.builder, sizeof(SnapBuild));
+	COMP_CRC32C_SMALL(checksum, &ondisk.builder, sizeof(SnapBuild));
 
 	/* restore committed xacts information */
 	if (ondisk.builder.committed.xcnt > 0)
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 48d344ae3f..dbc1a4a1a6 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -854,7 +854,7 @@ read_relmap_file(RelMapFile *map, char *dbpath, bool lock_held, int elevel)
 
 	/* verify the CRC */
 	INIT_CRC32C(crc);
-	COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
+	COMP_CRC32C_SMALL(crc, (char *) map, offsetof(RelMapFile, crc));
 	FIN_CRC32C(crc);
 
 	if (!EQ_CRC32C(crc, map->crc))
@@ -910,7 +910,7 @@ write_relmap_file(RelMapFile *newmap, bool write_wal, bool send_sinval,
 		elog(ERROR, "attempt to write bogus relation mapping");
 
 	INIT_CRC32C(newmap->crc);
-	COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
+	COMP_CRC32C_SMALL(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
 	FIN_CRC32C(newmap->crc);
 
 	/*
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index e9dcb5a6d8..c09ae27dfe 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -593,7 +593,7 @@ read_controlfile(void)
 	{
 		/* Check the CRC. */
 		INIT_CRC32C(crc);
-		COMP_CRC32C(crc,
+		COMP_CRC32C_SMALL(crc,
 					buffer,
 					offsetof(ControlFileData, crc));
 		FIN_CRC32C(crc);
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index 323c35646c..ecfe340f00 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -1004,7 +1004,7 @@ checkControlFile(ControlFileData *ControlFile)
 
 	/* Calculate CRC */
 	INIT_CRC32C(crc);
-	COMP_CRC32C(crc, (char *) ControlFile, offsetof(ControlFileData, crc));
+	COMP_CRC32C_SMALL(crc, (char *) ControlFile, offsetof(ControlFileData, crc));
 	FIN_CRC32C(crc);
 
 	/* And simply compare it */
diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c
index 82309b2510..1cd9194120 100644
--- a/src/common/controldata_utils.c
+++ b/src/common/controldata_utils.c
@@ -134,7 +134,7 @@ retry:
 
 	/* Check the CRC. */
 	INIT_CRC32C(crc);
-	COMP_CRC32C(crc,
+	COMP_CRC32C_SMALL(crc,
 				(char *) ControlFile,
 				offsetof(ControlFileData, crc));
 	FIN_CRC32C(crc);
@@ -198,7 +198,7 @@ update_controlfile(const char *DataDir,
 
 	/* Recalculate CRC of control file */
 	INIT_CRC32C(ControlFile->crc);
-	COMP_CRC32C(ControlFile->crc,
+	COMP_CRC32C_SMALL(ControlFile->crc,
 				(char *) ControlFile,
 				offsetof(ControlFileData, crc));
 	FIN_CRC32C(ControlFile->crc);
diff --git a/src/include/port/pg_crc32c.h b/src/include/port/pg_crc32c.h
index ade06dbcab..263a9ccaaf 100644
--- a/src/include/port/pg_crc32c.h
+++ b/src/include/port/pg_crc32c.h
@@ -40,12 +40,12 @@ typedef uint32 pg_crc32c;
 /* The INIT and EQ macros are the same for all implementations. */
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
+#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 #if defined(USE_SSE42_CRC32C)
 /* Use Intel SSE4.2 instructions. */
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c_sse42((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len);
 
@@ -53,7 +53,6 @@ extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t le
 /* Use Intel AVX512 instructions. */
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c_avx512((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t len);
 
@@ -62,7 +61,6 @@ extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t l
 
 #define COMP_CRC32C(crc, data, len)							\
 	((crc) = pg_comp_crc32c_armv8((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len);
 
@@ -71,7 +69,6 @@ extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t le
 
 #define COMP_CRC32C(crc, data, len)							\
 	((crc) = pg_comp_crc32c_loongarch((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_loongarch(pg_crc32c crc, const void *data, size_t len);
 
@@ -83,13 +80,16 @@ extern pg_crc32c pg_comp_crc32c_loongarch(pg_crc32c crc, const void *data, size_
  */
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len);
 extern pg_crc32c (*pg_comp_crc32c)(pg_crc32c crc, const void *data, size_t len);
 
 extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t len);
 
+extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len);
+#define COMP_CRC32C_SMALL(crc, data, len) \
+	((crc) = pg_comp_crc32c_sse42((crc), (data), (len)))
+
 #elif defined(USE_SSE42_CRC32C_WITH_RUNTIME_CHECK) || defined(USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK)
 
 /*
@@ -98,7 +98,6 @@ extern pg_crc32c pg_comp_crc32c_avx512(pg_crc32c crc, const void *data, size_t l
  */
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c((crc), (data), (len)))
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 
 extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len);
 extern pg_crc32c (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len);
@@ -121,13 +120,15 @@ extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t le
 #define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c_sb8((crc), (data), (len)))
 #ifdef WORDS_BIGENDIAN
+#undef FIN_CRC32C
 #define FIN_CRC32C(crc) ((crc) = pg_bswap32(crc) ^ 0xFFFFFFFF)
-#else
-#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 #endif
 
 extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len);
+#endif
 
+#if !defined(COMP_CRC32C_SMALL)
+#define COMP_CRC32C_SMALL(crc, data, len) COMP_CRC32C((crc), (data), (len))
 #endif
 
 #endif							/* PG_CRC32C_H */
diff --git a/src/port/meson.build b/src/port/meson.build
index 31d50a7a3b..6502687e7d 100644
--- a/src/port/meson.build
+++ b/src/port/meson.build
@@ -86,6 +86,8 @@ replace_funcs_pos = [
   ['pg_crc32c_sse42_choose', 'USE_SSE42_CRC32C_WITH_RUNTIME_CHECK'],
   ['pg_crc32c_avx512', 'USE_AVX512_CRC32C'],
   ['pg_crc32c_avx512', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK', 'crc'],
+  ['pg_crc32c_sse42', 'USE_AVX512_CRC32C'],
+  ['pg_crc32c_sse42', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK', 'crc'],
   ['pg_crc32c_avx512_choose', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK'],
   ['pg_crc32c_sb8', 'USE_AVX512_CRC32C_WITH_RUNTIME_CHECK'],
   ['pg_crc32c_sb8', 'USE_SSE42_CRC32C_WITH_RUNTIME_CHECK'],
-- 
2.34.1

