diff --git a/bits/indirect-return.h b/bits/indirect-return.h
index 819bd25b..4bfe3d35 100644
--- a/bits/indirect-return.h
+++ b/bits/indirect-return.h
@@ -21,5 +21,16 @@
 #endif
 
 /* __INDIRECT_RETURN is used on swapcontext to indicate if it requires
-   special compiler treatment.  */
-#define __INDIRECT_RETURN
+   special compiler treatment.  swapcontext does not restore every
+   callee-saved register on all targets -- on sparc the %l and %i
+   registers are not in the saved context at all -- so where
+   indirect_return is unavailable, returns_twice stops the compiler
+   assuming such a value survives the call.  Targets that need this only
+   under an optional feature override this file.  */
+#if __glibc_has_attribute (__indirect_return__)
+# define __INDIRECT_RETURN __attribute__ ((__indirect_return__))
+#elif __glibc_has_attribute (__returns_twice__)
+# define __INDIRECT_RETURN __attribute__ ((__returns_twice__))
+#else
+# define __INDIRECT_RETURN
+#endif
diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c
index 3aa13d03..26e2ec1c 100644
--- a/string/tst-xbzero-opt.c
+++ b/string/tst-xbzero-opt.c
@@ -111,10 +111,9 @@ use_test_buffer (unsigned char *buf)
 /* Always check the test buffer immediately after filling it; this
    makes externally visible side effects depend on the buffer existing
    and having been filled in.  */
-#if defined __CET__ && !__glibc_has_attribute (__indirect_return__)
-/* Note: swapcontext returns via indirect branch when SHSTK is enabled.
-   Without indirect_return attribute, swapcontext is marked with
-   returns_twice attribute, which prevents always_inline to work.  */
+#if !__glibc_has_attribute (__indirect_return__)
+/* Without indirect_return, swapcontext is marked returns_twice, which
+   prevents always_inline from working.  */
 # define ALWAYS_INLINE
 #else
 # define ALWAYS_INLINE	__attribute__ ((always_inline))
