diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index a546fc3d34..61a62074cf 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -133,6 +133,16 @@ static bool postmaster_running = false;
 static int	success_count = 0;
 static int	fail_count = 0;
 
+/*
+ * Mac OS X removes DYLD_LIBRARY_PATH on exec(). Use this variable to explicitly pass it. See:
+ * https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html
+ */
+#ifdef __darwin__
+static char extra_envvars[4096];
+#else
+static const char extra_envvars[] = "";
+#endif
+
 static bool directory_exists(const char *dir);
 static void make_directory(const char *dir);
 
@@ -897,6 +907,16 @@ initialize_environment(void)
 			note("using postmaster on Unix socket, default port");
 	}
 
+#ifdef __darwin__
+	/* Required to find shared libraries after exec(). See comment on extra_envars. */
+	int result = snprintf(extra_envvars, sizeof(extra_envvars), "DYLD_LIBRARY_PATH=%s",
+						  getenv("DYLD_LIBRARY_PATH"));
+	if (result < 0 || result >= sizeof(extra_envvars))
+	{
+		bail("BUG: extra_envars too small for DYLD_LIBRARY_PATH");
+	}
+#endif
+
 	load_resultmap();
 }
 
@@ -1106,7 +1126,8 @@ psql_start_command(void)
 	StringInfo	buf = makeStringInfo();
 
 	appendStringInfo(buf,
-					 "\"%s%spsql\" -X -q",
+					 "%s \"%s%spsql\" -X -q",
+					 extra_envvars,
 					 bindir ? bindir : "",
 					 bindir ? "/" : "");
 	return buf;
@@ -1216,7 +1237,7 @@ spawn_process(const char *cmdline)
 		 */
 		char	   *cmdline2;
 
-		cmdline2 = psprintf("exec %s", cmdline);
+		cmdline2 = psprintf("%s exec %s", extra_envvars, cmdline);
 		execl(shellprog, shellprog, "-c", cmdline2, (char *) NULL);
 		/* Not using the normal bail() here as we want _exit */
 		bail_noatexit("could not exec \"%s\": %s", shellprog, strerror(errno));
@@ -2319,7 +2340,8 @@ regression_main(int argc, char *argv[],
 
 		/* initdb */
 		snprintf(buf, sizeof(buf),
-				 "\"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync%s%s > \"%s/log/initdb.log\" 2>&1",
+				 "%s \"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync%s%s > \"%s/log/initdb.log\" 2>&1",
+				 extra_envvars,
 				 bindir ? bindir : "",
 				 bindir ? "/" : "",
 				 temp_instance,
@@ -2393,7 +2415,8 @@ regression_main(int argc, char *argv[],
 		 * Check if there is a postmaster running already.
 		 */
 		snprintf(buf2, sizeof(buf2),
-				 "\"%s%spsql\" -X postgres <%s 2>%s",
+				 "%s \"%s%spsql\" -X postgres <%s 2>%s",
+				 extra_envvars,
 				 bindir ? bindir : "",
 				 bindir ? "/" : "",
 				 DEVNULL, DEVNULL);
