diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 9f0e2bd1e6ff5246f84e919402c687687a84beb8..63750cf630816182c24062195f70074ed0f57fd1 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -346,6 +346,16 @@ (define_insn "bic<mode>3"
   [(set_attr "type" "neon_logic<q>")]
 )
 
+(define_insn "*bic_and_not_simd_<mode>3"
+  [(set (match_operand:VDQ_I 0 "register_operand" "=w")
+        (minus:VDQ_I (ior:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
+                                (match_operand:VDQ_I 2 "register_operand" "w"))
+                     (match_dup 2)))]
+ "TARGET_SIMD"
+ "bic\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
+  [(set_attr "type" "neon_logic<q>")]
+)
+
 (define_insn "add<mode>3"
   [(set (match_operand:VDQ_I 0 "register_operand" "=w")
         (plus:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index deca0004fedcb41c1e6b88ef3f8b4b187b4eecf8..d0177fc1586069281936eaeb96ba7b608f117dbd 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4733,6 +4733,17 @@ (define_insn_and_split "*xor_one_cmpl<mode>3"
    (set_attr "arch" "*,simd")]
 )
 
+;; (minus (or a b) b) pattern which simplifies to (and a (not b))
+(define_insn "*bic_and_not_<mode>3"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+        (minus:GPI (ior:GPI (match_operand:GPI 1 "register_operand" "r")
+                            (match_operand:GPI 2 "register_operand" "r"))
+                   (match_dup 2)))]
+  ""
+  "bic\\t%<w>0, %<w>1, %<w>2"
+  [(set_attr "type" "logic_reg")]
+)
+
 (define_insn "*and_one_cmpl<mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
diff --git a/gcc/testsuite/gcc.target/aarch64/bic_and_not_di3.c b/gcc/testsuite/gcc.target/aarch64/bic_and_not_di3.c
new file mode 100644
index 0000000000000000000000000000000000000000..a338415860e9e0b056db995e02e0f63661bc9689
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bic_and_not_di3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long long
+f(long long x, long long y)
+{
+  return (x | y) - y;
+}
+
+/* { dg-final { scan-assembler-not "orr\tx\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "sub\tx\[0-9\]+" } } */
+
+/* { dg-final { scan-assembler "bic\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bic_and_not_si3.c b/gcc/testsuite/gcc.target/aarch64/bic_and_not_si3.c
new file mode 100644
index 0000000000000000000000000000000000000000..4fb6b6aca2713dac63b903cc72ba0f54b09daa34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bic_and_not_si3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+f(int x, int y)
+{
+  return (x | y) - y;
+}
+
+/* { dg-final { scan-assembler-not "orr\tw\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "sub\tw\[0-9\]+" } } */
+
+/* { dg-final { scan-assembler "bic\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bic_and_not_v2di3.c b/gcc/testsuite/gcc.target/aarch64/bic_and_not_v2di3.c
new file mode 100644
index 0000000000000000000000000000000000000000..7ac46d3b08277a0ce5e4e89094cfad907852bdff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bic_and_not_v2di3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+v2di
+f_v2di(v2di x, v2di y) {
+    return (x | y) - y;
+}
+
+/* { dg-final { scan-assembler-not "orr\tv\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "sub\tv\[0-9\]+" } } */
+
+/* { dg-final { scan-assembler "bic\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bic_and_not_v4si3.c b/gcc/testsuite/gcc.target/aarch64/bic_and_not_v4si3.c
new file mode 100644
index 0000000000000000000000000000000000000000..406adb086d2f5e8338a85e1f272fa851d060cb75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bic_and_not_v4si3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+v4si
+f_v4si(v4si x, v4si y) {
+    return (x | y) - y;
+}
+
+/* { dg-final { scan-assembler-not "orr\tv\[0-9\]+" } } */
+/* { dg-final { scan-assembler-not "sub\tv\[0-9\]+" } } */
+
+/* { dg-final { scan-assembler "bic\tv\[0-9\]+\.16b, v\[0-9\]+\.16b, v\[0-9\]+\.16b" } } */
