diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 385a669b9b3c31cc9108a660e881b9091c71fc7c..dbde066f7478bec51a8703b017ea553aa98be309 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4811,7 +4811,7 @@
   ""
   {@ [ cons: =0 , 1  , 2        ; attrs: type , arch  ]
      [ r        , %r , r        ; logic_reg   , *     ] <logical>\t%<w>0, %<w>1, %<w>2
-     [ rk       , ^r , <lconst> ; logic_imm   , *     ] <logical>\t%<w>0, %<w>1, %2
+     [ rk       , r  , <lconst> ; logic_imm   , *     ] <logical>\t%<w>0, %<w>1, %2
      [ w        , 0  , <lconst> ; *           , sve   ] <logical>\t%Z0.<s>, %Z0.<s>, #%2
      [ w        , w  , w        ; neon_logic  , simd  ] <logical>\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
   }
@@ -7192,22 +7192,29 @@
    (match_operand:GPF 2 "nonmemory_operand")]
   "TARGET_SIMD"
 {
-  machine_mode int_mode = <V_INT_EQUIV>mode;
-  rtx bitmask = gen_reg_rtx (int_mode);
-  emit_move_insn (bitmask, GEN_INT (HOST_WIDE_INT_M1U
-				    << (GET_MODE_BITSIZE (<MODE>mode) - 1)));
+  rtx signbit_const = GEN_INT (HOST_WIDE_INT_M1U
+			       << (GET_MODE_BITSIZE (<MODE>mode) - 1));
   /* copysign (x, -1) should instead be expanded as orr with the sign
      bit.  */
   rtx op2_elt = unwrap_const_vec_duplicate (operands[2]);
   if (GET_CODE (op2_elt) == CONST_DOUBLE
       && real_isneg (CONST_DOUBLE_REAL_VALUE (op2_elt)))
     {
-      emit_insn (gen_ior<v_int_equiv>3 (
-	lowpart_subreg (int_mode, operands[0], <MODE>mode),
-	lowpart_subreg (int_mode, operands[1], <MODE>mode), bitmask));
+      rtx v_bitmask
+	= force_reg (V2<V_INT_EQUIV>mode,
+		     gen_const_vec_duplicate (V2<V_INT_EQUIV>mode,
+					      signbit_const));
+
+      emit_insn (gen_iorv2<v_int_equiv>3 (
+	lowpart_subreg (V2<V_INT_EQUIV>mode, operands[0], <MODE>mode),
+	lowpart_subreg (V2<V_INT_EQUIV>mode, operands[1], <MODE>mode),
+	v_bitmask));
       DONE;
     }
 
+  machine_mode int_mode = <V_INT_EQUIV>mode;
+  rtx bitmask = gen_reg_rtx (int_mode);
+  emit_move_insn (bitmask, signbit_const);
   operands[2] = force_reg (<MODE>mode, operands[2]);
   emit_insn (gen_copysign<mode>3_insn (operands[0], operands[1], operands[2],
 				       bitmask));
diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c
index eed41ea18e69ff60ac79cbdb7c0c935850b49b33..18d10ee834d5d9b4361d890447060e78f09d3a73 100644
--- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c
@@ -9,8 +9,7 @@
 
 /*
 ** f1:
-**	movi	v[0-9]+.2s, 0x80, lsl 24
-**	orr	v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b
+**	orr	v[0-9]+.2s, #?128, lsl #?24
 **	ret
 */
 float32_t f1 (float32_t a)
@@ -22,7 +21,7 @@ float32_t f1 (float32_t a)
 ** f2:
 **	movi	v[0-9]+.4s, #?0
 **	fneg	v[0-9]+.2d, v[0-9]+.2d
-**	orr	v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b
+**	orr	v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
 **	ret
 */
 float64_t f2 (float64_t a)
diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c
index d45c3d1210c682f38177a89f1137ab4f6decfbc1..6da95a4b052ca3d9e0b8db0e465c5f40139b2b18 100644
--- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c
@@ -7,7 +7,7 @@
 #include <string.h>
 
 /*
-** negabs:
+** negabs: { xfail *-*-* }
 **	movi	v31.4s, #?0
 **	fneg	v[0-9]+.2d, v[0-9]+.2d
 **	orr	v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b
@@ -23,7 +23,7 @@ double negabs (double x)
 }
 
 /*
-** negabsf:
+** negabsf: { xfail *-*-* }
 **	movi	v[0-9]+.2s, 0x80, lsl 24
 **	orr	v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b
 **	ret
diff --git a/gcc/testsuite/gcc.target/aarch64/pr114741.c b/gcc/testsuite/gcc.target/aarch64/pr114741.c
new file mode 100644
index 0000000000000000000000000000000000000000..fd2182da0e966afcf0ab5bdef2f8d3892c2a3d67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr114741.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
+
+#pragma GCC target "+nosve"
+
+/*
+** foo1:
+**	and	w0, w0, 1
+**	str	w0, \[x1\]
+**	ret
+*/
+void foo1(unsigned v, unsigned *p)
+{
+    *p = v & 1;
+}
+
+#pragma GCC target "+sve"
+
+/*
+** foo2:
+**	and	w0, w0, 1
+**	str	w0, \[x1\]
+**	ret
+*/
+void foo2(unsigned v, unsigned *p)
+{
+    *p = v & 1;
+}