diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index a8c3f84a70b5353f48ddd34d9a5e9200a3882cba..257ca5bf6adcddfd426262e31d69aa1c6b8890b7 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -47,11 +47,31 @@
 #include "aarch64-builtins.h"
 #include "ssa.h"
 #include "gimple-fold.h"
+#include "tree-ssa.h"
 
 using namespace aarch64_sve;
 
 namespace {
 
+/* Return true if VAL is an undefined value.  */
+static bool
+is_undef (tree val)
+{
+  if (TREE_CODE (val) == SSA_NAME)
+    {
+      if (ssa_undefined_value_p (val, false))
+	return true;
+
+      gimple *def = SSA_NAME_DEF_STMT (val);
+      if (gcall *call = dyn_cast<gcall *> (def))
+	if (tree fndecl = gimple_call_fndecl (call))
+	  if (const function_instance *instance = lookup_fndecl (fndecl))
+	    if (instance->base == functions::svundef)
+	      return true;
+    }
+  return false;
+}
+
 /* Return the UNSPEC_CMLA* unspec for rotation amount ROT.  */
 static int
 unspec_cmla (int rot)
@@ -1142,6 +1162,13 @@ public:
   expand (function_expander &e) const override
   {
     machine_mode mode = e.vector_mode (0);
+
+    /* If the SVE argument is undefined, we just need to reinterpret the
+       Advanced SIMD argument as an SVE vector.  */
+    if (!BYTES_BIG_ENDIAN
+	&& is_undef (CALL_EXPR_ARG (e.call_expr, 0)))
+      return simplify_gen_subreg (mode, e.args[1], GET_MODE (e.args[1]), 0);
+
     rtx_vector_builder builder (VNx16BImode, 16, 2);
     for (unsigned int i = 0; i < 16; i++)
       builder.quick_push (CONST1_RTX (BImode));
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index 11f5c5c500c8331094933cb1c1205a1360eca79b..e124d1f90a586029502605e360a8bd1e6453ff81 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -1055,6 +1055,22 @@ get_vector_type (sve_type type)
   return acle_vector_types[type.num_vectors - 1][vector_type];
 }
 
+/* If FNDECL is an SVE builtin, return its function instance, otherwise
+   return null.  */
+const function_instance *
+lookup_fndecl (tree fndecl)
+{
+  if (!fndecl_built_in_p (fndecl, BUILT_IN_MD))
+    return nullptr;
+
+  unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
+  if ((code & AARCH64_BUILTIN_CLASS) != AARCH64_BUILTIN_SVE)
+    return nullptr;
+
+  unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT;
+  return &(*registered_functions)[subcode]->instance;
+}
+
 /* Report an error against LOCATION that the user has tried to use
    function FNDECL when extension EXTENSION is disabled.  */
 static void
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h
index e66729ed63532811b3b16ab57ae11cb10518caca..053006776a985d56e55834c839c6e78acff3f4cf 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins.h
@@ -810,6 +810,7 @@ extern tree acle_svprfop;
 
 bool vector_cst_all_same (tree, unsigned int);
 bool is_ptrue (tree, unsigned int);
+const function_instance *lookup_fndecl (tree);
 
 /* Try to find a mode with the given mode_suffix_info fields.  Return the
    mode on success or MODE_none on failure.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr114577_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr114577_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..2566c2d86c434bd9415f57b4dc039dcde636bdd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr114577_1.c
@@ -0,0 +1,94 @@
+/* { dg-options "-O" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_neon_sve_bridge.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+svint32_t svundef_foo ();
+
+/*
+** f1:		{ target aarch64_little_endian }
+**	ldr	q0, \[x0\]
+**	ret
+*/
+svint32_t
+f1 (int *a)
+{
+  return svset_neonq (svundef_s32 (), vld1q_s32 (a));
+}
+
+/*
+** f2:		{ target aarch64_little_endian }
+**	ldr	q0, \[x0\]
+**	ret
+*/
+svint32_t
+f2 (int *a)
+{
+  svint32_t undef;
+  return svset_neonq (undef, vld1q_s32 (a));
+}
+
+/*
+** f3:		{ target aarch64_little_endian }
+**	mov	[vz]0.[^\n]+, [vz]1.[^\n]+
+**	ret
+*/
+svint32_t
+f3 (int32x4_t v0, int32x4_t v1)
+{
+  return svset_neonq (svundef_s32 (), v1);
+}
+
+/*
+** f4:		{ target aarch64_little_endian }
+**	uzp1	z([0-9]+)\.s, z0\.s, z1\.s
+**	ldr	q([0-9]+), \[x0\]
+**	ptrue	p([0-7])\.s, vl4
+**	sel	z0\.s, p\3, z\2\.s, z\1\.s
+**	ret
+*/
+svint32_t
+f4 (int *a, svint32_t x, svint32_t y)
+{
+  x = svuzp1 (x, y);
+  int32x4_t z = vld1q_s32 (a);
+  return svset_neonq (x, z);
+}
+
+/*
+** f5:
+**	...
+**	bl	svundef_foo
+**	...
+**	sel	z0\.s, [^\n]+
+**	...
+**	ret
+*/
+svint32_t
+f5 (int *a)
+{
+  return svset_neonq (svundef_foo (), vld1q_s32 (a));
+}
+
+/*
+** f6:
+**	...
+**	blr	x[0-9]+
+**	...
+**	sel	z0\.s, [^\n]+
+**	...
+**	ret
+*/
+svint32_t
+f6 (int *a, svint32_t (*svundef_s32) ())
+{
+  return svset_neonq (svundef_s32 (), vld1q_s32 (a));
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr114577_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr114577_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..0775162e6b520090af19392ba143c455e5fc6e08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr114577_2.c
@@ -0,0 +1,46 @@
+/* { dg-options "-O -msve-vector-bits=256" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_neon_sve_bridge.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** f1:		{ target aarch64_little_endian }
+**	ldr	q0, \[x0\]
+**	ret
+*/
+svint32_t
+f1 (int *a)
+{
+  return svset_neonq (svundef_s32 (), vld1q_s32 (a));
+}
+
+/*
+** f2:		{ target aarch64_little_endian }
+**	ldr	q0, \[x0\]
+**	ret
+*/
+svint32_t
+f2 (int *a)
+{
+  svint32_t undef;
+  return svset_neonq (undef, vld1q_s32 (a));
+}
+
+/*
+** f3:		{ target aarch64_little_endian }
+**	mov	[vz]0.[^\n]+, [vz]1.[^\n]+
+**	ret
+*/
+svint32_t
+f3 (int32x4_t v0, int32x4_t v1)
+{
+  return svset_neonq (svundef_s32 (), v1);
+}
+
+#ifdef __cplusplus
+}
+#endif