diff mbox

[AArch32] Additional bics patterns.

Message ID 555632A9.6050007@arm.com
State New
Headers show

Commit Message

Alex Velenko May 15, 2015, 5:53 p.m. UTC
On 01/05/15 10:28, Kyrill Tkachov wrote:
>
> Can you please confirm that bootstraps with both arm and thumb pass?
> That is, configured with --with-mode=arm and --with-mode=thumb
>

Hi Kyrill,

Bootstrapped on arm-none-gnueabihf with arm and thumb mode.

Following patch requires bics shift operand on Thumb2 to be
const int, as bics shifted by register is not supported by
Thumb2.

Is patch ok?

gcc

2015-05-15  Alex Velenko  <Alex.Velenko@arm.com>

    * config/arm/arm.md (andsi_not_shiftsi_si_scc): New pattern.
    * (andsi_not_shiftsi_si_scc_no_reuse): New pattern.

gcc/testsuite

2015-05-15  Alex Velenko <Alex.Velenko@arm.com>

    * gcc.target/arm/bics_1.c : New testcase.
    * gcc.target/arm/bics_2.c : New testcase.
    * gcc.target/arm/bics_3.c : New testcase.
    * gcc.target/arm/bics_4.c : New testcase.
---
   gcc/config/arm/arm.md                 | 49 ++++++++++++++++++++++++++++++
   gcc/testsuite/gcc.target/arm/bics_1.c | 54
+++++++++++++++++++++++++++++++++
   gcc/testsuite/gcc.target/arm/bics_2.c | 57
+++++++++++++++++++++++++++++++++++
   gcc/testsuite/gcc.target/arm/bics_3.c | 41 +++++++++++++++++++++++++
   gcc/testsuite/gcc.target/arm/bics_4.c | 49 ++++++++++++++++++++++++++++++
   5 files changed, 250 insertions(+)
   create mode 100644 gcc/testsuite/gcc.target/arm/bics_1.c
   create mode 100644 gcc/testsuite/gcc.target/arm/bics_2.c
   create mode 100644 gcc/testsuite/gcc.target/arm/bics_3.c
   create mode 100644 gcc/testsuite/gcc.target/arm/bics_4.c

+/* { dg-final { cleanup-saved-temps } } */
--
1.8.1.2

Comments

Kyrylo Tkachov May 18, 2015, 8:28 a.m. UTC | #1
Hi Alex,

On 15/05/15 18:53, Alex Velenko wrote:
> On 01/05/15 10:28, Kyrill Tkachov wrote:
>> Can you please confirm that bootstraps with both arm and thumb pass?
>> That is, configured with --with-mode=arm and --with-mode=thumb
>>
> Hi Kyrill,
>
> Bootstrapped on arm-none-gnueabihf with arm and thumb mode.
>
> Following patch requires bics shift operand on Thumb2 to be
> const int, as bics shifted by register is not supported by
> Thumb2.
>
> Is patch ok?
>
> gcc
>
> 2015-05-15  Alex Velenko  <Alex.Velenko@arm.com>
>
>      * config/arm/arm.md (andsi_not_shiftsi_si_scc): New pattern.
>      * (andsi_not_shiftsi_si_scc_no_reuse): New pattern.

No need for the '*', just:

     * config/arm/arm.md (andsi_not_shiftsi_si_scc): New pattern.
     (andsi_not_shiftsi_si_scc_no_reuse): Likewise.


will do.
Ok for trunk with that ChangeLog nit.

Thanks,
Kyrill

>
> gcc/testsuite
>
> 2015-05-15  Alex Velenko <Alex.Velenko@arm.com>
>
>      * gcc.target/arm/bics_1.c : New testcase.
>      * gcc.target/arm/bics_2.c : New testcase.
>      * gcc.target/arm/bics_3.c : New testcase.
>      * gcc.target/arm/bics_4.c : New testcase.
> ---
>     gcc/config/arm/arm.md                 | 49 ++++++++++++++++++++++++++++++
>     gcc/testsuite/gcc.target/arm/bics_1.c | 54
> +++++++++++++++++++++++++++++++++
>     gcc/testsuite/gcc.target/arm/bics_2.c | 57
> +++++++++++++++++++++++++++++++++++
>     gcc/testsuite/gcc.target/arm/bics_3.c | 41 +++++++++++++++++++++++++
>     gcc/testsuite/gcc.target/arm/bics_4.c | 49 ++++++++++++++++++++++++++++++
>     5 files changed, 250 insertions(+)
>     create mode 100644 gcc/testsuite/gcc.target/arm/bics_1.c
>     create mode 100644 gcc/testsuite/gcc.target/arm/bics_2.c
>     create mode 100644 gcc/testsuite/gcc.target/arm/bics_3.c
>     create mode 100644 gcc/testsuite/gcc.target/arm/bics_4.c
>
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 164ac13..26d3ad2 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -2768,6 +2768,55 @@
>                         (const_string "logic_shift_reg")))]
>     )
>
> +;; Shifted bics pattern used to set up CC status register and not reusing
> +;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
> +;; does not support shift by register.
> +(define_insn "andsi_not_shiftsi_si_scc_no_reuse"
> +  [(set (reg:CC_NOOV CC_REGNUM)
> +       (compare:CC_NOOV
> +               (and:SI (not:SI (match_operator:SI 0 "shift_operator"
> +                       [(match_operand:SI 1 "s_register_operand" "r")
> +                        (match_operand:SI 2 "arm_rhs_operand" "rM")]))
> +                       (match_operand:SI 3 "s_register_operand" "r"))
> +               (const_int 0)))
> +   (clobber (match_scratch:SI 4 "=3Dr"))]
> +  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
> +  "bic%.%?\\t%4, %3, %1%S0"
> +  [(set_attr "predicable" "yes")
> +   (set_attr "predicable_short_it" "no")
> +   (set_attr "conds" "set")
> +   (set_attr "shift" "1")
> +   (set (attr "type") (if_then_else (match_operand 2
> "const_int_operand" "")
> +                     (const_string "logic_shift_imm")
> +                     (const_string "logic_shift_reg")))]
> +)
> +
> +;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
> +;; getting reused later.
> +(define_insn "andsi_not_shiftsi_si_scc"
> +  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
> +       (compare:CC_NOOV
> +               (and:SI (not:SI (match_operator:SI 0 "shift_operator"
> +                       [(match_operand:SI 1 "s_register_operand" "r")
> +                        (match_operand:SI 2 "arm_rhs_operand" "rM")]))
> +                       (match_operand:SI 3 "s_register_operand" "r"))
> +               (const_int 0)))
> +       (set (match_operand:SI 4 "s_register_operand" "=3Dr")
> +            (and:SI (not:SI (match_op_dup 0
> +                    [(match_dup 1)
> +                     (match_dup 2)]))
> +                    (match_dup 3)))])]
> +  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
> +  "bic%.%?\\t%4, %3, %1%S0"
> +  [(set_attr "predicable" "yes")
> +   (set_attr "predicable_short_it" "no")
> +   (set_attr "conds" "set")
> +   (set_attr "shift" "1")
> +   (set (attr "type") (if_then_else (match_operand 2
> "const_int_operand" "")
> +                     (const_string "logic_shift_imm")
> +                     (const_string "logic_shift_reg")))]
> +)
> +
>     (define_insn "*andsi_notsi_si_compare0"
>       [(set (reg:CC_NOOV CC_REGNUM)
>           (compare:CC_NOOV
> diff --git a/gcc/testsuite/gcc.target/arm/bics_1.c
> b/gcc/testsuite/gcc.target/arm/bics_1.c
> new file mode 100644
> index 0000000..173eb89
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/bics_1.c
> @@ -0,0 +1,54 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 --save-temps -fno-inline" } */
> +/* { dg-require-effective-target arm32 } */
> +
> +extern void abort (void);
> +
> +int
> +bics_si_test1 (int a, int b, int c)
> +{
> +  int d =3D a & ~b;
> +
> +  /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+" 2 } } */
> +  if (d =3D=3D 0)
> +    return a + c;
> +  else
> +    return b + d + c;
> +}
> +
> +int
> +bics_si_test2 (int a, int b, int c)
> +{
> +  int d =3D a & ~(b << 3);
> +
> +  /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+, .sl \#3" 1 } } */
> +  if (d =3D=3D 0)
> +    return a + c;
> +  else
> +    return b + d + c;
> +}
> +
> +int
> +main ()
> +{
> +  int x;
> +
> +  x =3D bics_si_test1 (29, ~4, 5);
> +  if (x !=3D ((29 & 4) + ~4 + 5))
> +    abort ();
> +
> +  x =3D bics_si_test1 (5, ~2, 20);
> +  if (x !=3D 25)
> +    abort ();
> +
> +    x =3D bics_si_test2 (35, ~4, 5);
> +  if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5))
> +    abort ();
> +
> +  x =3D bics_si_test2 (96, ~2, 20);
> +  if (x !=3D 116)
> +  abort ();
> +
> +  return 0;
> +}
> +/* { dg-final { cleanup-saved-temps } } */
> diff --git a/gcc/testsuite/gcc.target/arm/bics_2.c
> b/gcc/testsuite/gcc.target/arm/bics_2.c
> new file mode 100644
> index 0000000..740d7c9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/bics_2.c
> @@ -0,0 +1,57 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 --save-temps -fno-inline" } */
> +/* { dg-require-effective-target arm32 } */
> +
> +extern void abort (void);
> +
> +int
> +bics_si_test1 (int a, int b, int c)
> +{
> +  int d =3D a & ~b;
> +
> +  /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+" } } */
> +  /* { dg-final { scan-assembler-times "bic\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+" 2 } } */
> +  if (d <=3D 0)
> +    return a + c;
> +  else
> +    return b + d + c;
> +}
> +
> +int
> +bics_si_test2 (int a, int b, int c)
> +{
> +  int d =3D a & ~(b << 3);
> +
> +  /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+, .sl \#3" } } */
> +  /* { dg-final { scan-assembler "bic\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+,
> .sl \#3" } } */
> +  if (d <=3D 0)
> +    return a + c;
> +  else
> +    return b + d + c;
> +}
> +
> +int
> +main ()
> +{
> +  int x;
> +
> +  x =3D bics_si_test1 (29, ~4, 5);
> +  if (x !=3D ((29 & 4) + ~4 + 5))
> +    abort ();
> +
> +  x =3D bics_si_test1 (5, ~2, 20);
> +  if (x !=3D 25)
> +    abort ();
> +
> +  x =3D bics_si_test2 (35, ~4, 5);
> +  if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5))
> +    abort ();
> +
> +  x =3D bics_si_test2 (96, ~2, 20);
> +  if (x !=3D 116)
> +    abort ();
> +
> +  return 0;
> +}
> +
> +/* { dg-final { cleanup-saved-temps } } */
> diff --git a/gcc/testsuite/gcc.target/arm/bics_3.c
> b/gcc/testsuite/gcc.target/arm/bics_3.c
> new file mode 100644
> index 0000000..e2b1c72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/bics_3.c
> @@ -0,0 +1,41 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 --save-temps -fno-inline" } */
> +/* { dg-require-effective-target arm32 } */
> +
> +extern void abort (void);
> +
> +int
> +bics_si_test (int a, int b)
> +{
> +  if (a & ~b)
> +    return 1;
> +  else
> +    return 0;
> +}
> +
> +int
> +bics_si_test2 (int a, int b)
> +{
> +  if (a & ~ (b << 2))
> +    return 1;
> +  else
> +    return 0;
> +}
> +
> +int
> +main (void)
> +{
> +  int a =3D 5;
> +  int b =3D 5;
> +  int c =3D 20;
> +  if (bics_si_test (a, b))
> +    abort ();
> +  if (bics_si_test2 (c, b))
> +    abort ();
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+" 2 } } */
> +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+, .sl #2" 1 } } */
> +
> +/* { dg-final { cleanup-saved-temps } } */
> diff --git a/gcc/testsuite/gcc.target/arm/bics_4.c
> b/gcc/testsuite/gcc.target/arm/bics_4.c
> new file mode 100644
> index 0000000..8f2faf0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/bics_4.c
> @@ -0,0 +1,49 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 --save-temps -fno-inline" } */
> +/* { dg-require-effective-target arm32 } */
> +
> +extern void abort (void);
> +
> +int
> +bics_si_test1 (int a, int b, int c)
> +{
> +  if ((a & b) =3D=3D a)
> +    return a;
> +  else
> +    return c;
> +}
> +
> +int
> +bics_si_test2 (int a, int b, int c)
> +{
> +  if ((a & b) =3D=3D b)
> +    return b;
> +  else
> +    return c;
> +}
> +
> +int
> +main ()
> +{
> +  int x;
> +  x =3D bics_si_test1 (0xf00d, 0xf11f, 0);
> +  if (x !=3D 0xf00d)
> +    abort ();
> +
> +  x =3D bics_si_test1 (0xf11f, 0xf00d, 0);
> +  if (x !=3D 0)
> +    abort ();
> +
> +  x =3D bics_si_test2 (0xf00d, 0xf11f, 0);
> +  if (x !=3D 0)
> +    abort ();
> +
> +  x =3D bics_si_test2 (0xf11f, 0xf00d, 0);
> +  if (x !=3D 0xf00d)
> +    abort ();
> +
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
> r\[0-9\]+" 2 } } */
> +/* { dg-final { cleanup-saved-temps } } */
> --
> 1.8.1.2
Alex Velenko May 18, 2015, 2:42 p.m. UTC | #2
Committed r223295.

Alex.
diff mbox

Patch

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 164ac13..26d3ad2 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2768,6 +2768,55 @@ 
                       (const_string "logic_shift_reg")))]
   )

+;; Shifted bics pattern used to set up CC status register and not reusing
+;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
+;; does not support shift by register.
+(define_insn "andsi_not_shiftsi_si_scc_no_reuse"
+  [(set (reg:CC_NOOV CC_REGNUM)
+       (compare:CC_NOOV
+               (and:SI (not:SI (match_operator:SI 0 "shift_operator"
+                       [(match_operand:SI 1 "s_register_operand" "r")
+                        (match_operand:SI 2 "arm_rhs_operand" "rM")]))
+                       (match_operand:SI 3 "s_register_operand" "r"))
+               (const_int 0)))
+   (clobber (match_scratch:SI 4 "=3Dr"))]
+  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
+  "bic%.%?\\t%4, %3, %1%S0"
+  [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
+   (set_attr "conds" "set")
+   (set_attr "shift" "1")
+   (set (attr "type") (if_then_else (match_operand 2
"const_int_operand" "")
+                     (const_string "logic_shift_imm")
+                     (const_string "logic_shift_reg")))]
+)
+
+;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
+;; getting reused later.
+(define_insn "andsi_not_shiftsi_si_scc"
+  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
+       (compare:CC_NOOV
+               (and:SI (not:SI (match_operator:SI 0 "shift_operator"
+                       [(match_operand:SI 1 "s_register_operand" "r")
+                        (match_operand:SI 2 "arm_rhs_operand" "rM")]))
+                       (match_operand:SI 3 "s_register_operand" "r"))
+               (const_int 0)))
+       (set (match_operand:SI 4 "s_register_operand" "=3Dr")
+            (and:SI (not:SI (match_op_dup 0
+                    [(match_dup 1)
+                     (match_dup 2)]))
+                    (match_dup 3)))])]
+  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
+  "bic%.%?\\t%4, %3, %1%S0"
+  [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
+   (set_attr "conds" "set")
+   (set_attr "shift" "1")
+   (set (attr "type") (if_then_else (match_operand 2
"const_int_operand" "")
+                     (const_string "logic_shift_imm")
+                     (const_string "logic_shift_reg")))]
+)
+
   (define_insn "*andsi_notsi_si_compare0"
     [(set (reg:CC_NOOV CC_REGNUM)
         (compare:CC_NOOV
diff --git a/gcc/testsuite/gcc.target/arm/bics_1.c
b/gcc/testsuite/gcc.target/arm/bics_1.c
new file mode 100644
index 0000000..173eb89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bics_1.c
@@ -0,0 +1,54 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target arm32 } */
+
+extern void abort (void);
+
+int
+bics_si_test1 (int a, int b, int c)
+{
+  int d =3D a & ~b;
+
+  /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+" 2 } } */
+  if (d =3D=3D 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+bics_si_test2 (int a, int b, int c)
+{
+  int d =3D a & ~(b << 3);
+
+  /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+, .sl \#3" 1 } } */
+  if (d =3D=3D 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+main ()
+{
+  int x;
+
+  x =3D bics_si_test1 (29, ~4, 5);
+  if (x !=3D ((29 & 4) + ~4 + 5))
+    abort ();
+
+  x =3D bics_si_test1 (5, ~2, 20);
+  if (x !=3D 25)
+    abort ();
+
+    x =3D bics_si_test2 (35, ~4, 5);
+  if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5))
+    abort ();
+
+  x =3D bics_si_test2 (96, ~2, 20);
+  if (x !=3D 116)
+  abort ();
+
+  return 0;
+}
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/bics_2.c
b/gcc/testsuite/gcc.target/arm/bics_2.c
new file mode 100644
index 0000000..740d7c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bics_2.c
@@ -0,0 +1,57 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target arm32 } */
+
+extern void abort (void);
+
+int
+bics_si_test1 (int a, int b, int c)
+{
+  int d =3D a & ~b;
+
+  /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+" } } */
+  /* { dg-final { scan-assembler-times "bic\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+" 2 } } */
+  if (d <=3D 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+bics_si_test2 (int a, int b, int c)
+{
+  int d =3D a & ~(b << 3);
+
+  /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+, .sl \#3" } } */
+  /* { dg-final { scan-assembler "bic\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+,
.sl \#3" } } */
+  if (d <=3D 0)
+    return a + c;
+  else
+    return b + d + c;
+}
+
+int
+main ()
+{
+  int x;
+
+  x =3D bics_si_test1 (29, ~4, 5);
+  if (x !=3D ((29 & 4) + ~4 + 5))
+    abort ();
+
+  x =3D bics_si_test1 (5, ~2, 20);
+  if (x !=3D 25)
+    abort ();
+
+  x =3D bics_si_test2 (35, ~4, 5);
+  if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5))
+    abort ();
+
+  x =3D bics_si_test2 (96, ~2, 20);
+  if (x !=3D 116)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/bics_3.c
b/gcc/testsuite/gcc.target/arm/bics_3.c
new file mode 100644
index 0000000..e2b1c72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bics_3.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target arm32 } */
+
+extern void abort (void);
+
+int
+bics_si_test (int a, int b)
+{
+  if (a & ~b)
+    return 1;
+  else
+    return 0;
+}
+
+int
+bics_si_test2 (int a, int b)
+{
+  if (a & ~ (b << 2))
+    return 1;
+  else
+    return 0;
+}
+
+int
+main (void)
+{
+  int a =3D 5;
+  int b =3D 5;
+  int c =3D 20;
+  if (bics_si_test (a, b))
+    abort ();
+  if (bics_si_test2 (c, b))
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+" 2 } } */
+/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+, .sl #2" 1 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/bics_4.c
b/gcc/testsuite/gcc.target/arm/bics_4.c
new file mode 100644
index 0000000..8f2faf0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bics_4.c
@@ -0,0 +1,49 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target arm32 } */
+
+extern void abort (void);
+
+int
+bics_si_test1 (int a, int b, int c)
+{
+  if ((a & b) =3D=3D a)
+    return a;
+  else
+    return c;
+}
+
+int
+bics_si_test2 (int a, int b, int c)
+{
+  if ((a & b) =3D=3D b)
+    return b;
+  else
+    return c;
+}
+
+int
+main ()
+{
+  int x;
+  x =3D bics_si_test1 (0xf00d, 0xf11f, 0);
+  if (x !=3D 0xf00d)
+    abort ();
+
+  x =3D bics_si_test1 (0xf11f, 0xf00d, 0);
+  if (x !=3D 0)
+    abort ();
+
+  x =3D bics_si_test2 (0xf00d, 0xf11f, 0);
+  if (x !=3D 0)
+    abort ();
+
+  x =3D bics_si_test2 (0xf11f, 0xf00d, 0);
+  if (x !=3D 0xf00d)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+,
r\[0-9\]+" 2 } } */