[ARM] Fix PR target/69403: Bug in thumb2_ior_scc_strict_it pattern
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Jan 2016 13:58:11 +0000 (13:58 +0000)
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Jan 2016 13:58:11 +0000 (13:58 +0000)
PR target/69403
* config/arm/thumb2.md (*thumb2_ior_scc_strict_it): Convert to
define_insn_and_split.  Ensure operands[1] and operands[0] do not
get assigned the same register.

* gcc.c-torture/execute/pr69403.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232727 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/thumb2.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr69403.c [new file with mode: 0644]

index 92c5bda..16813c7 100644 (file)
@@ -1,3 +1,10 @@
+2016-01-22  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR target/69403
+       * config/arm/thumb2.md (*thumb2_ior_scc_strict_it): Convert to
+       define_insn_and_split.  Ensure operands[1] and operands[0] do not
+       get assigned the same register.
+
 2016-01-22  Kugan Vivekanandarajah  <kuganv@linaro.org>
 
        * ipa-prop.c (ipa_set_jf_constant): Remove redundant unshare_expr.
index 3e76201..39a3d80 100644 (file)
    (set_attr "type" "multiple")]
 )
 
-(define_insn "*thumb2_ior_scc_strict_it"
-  [(set (match_operand:SI 0 "s_register_operand" "=l,l")
+(define_insn_and_split "*thumb2_ior_scc_strict_it"
+  [(set (match_operand:SI 0 "s_register_operand" "=&r")
        (ior:SI (match_operator:SI 2 "arm_comparison_operator"
                 [(match_operand 3 "cc_register" "") (const_int 0)])
-               (match_operand:SI 1 "s_register_operand" "0,?l")))]
+               (match_operand:SI 1 "s_register_operand" "r")))]
   "TARGET_THUMB2 && arm_restrict_it"
-  "@
-   it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1
-   mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1"
+  "#" ; orr\\t%0, %1, #1\;it\\t%D2\;mov%D2\\t%0, %1
+  "&& reload_completed"
+  [(set (match_dup 0) (ior:SI (match_dup 1) (const_int 1)))
+   (cond_exec (match_dup 4)
+     (set (match_dup 0) (match_dup 1)))]
+  {
+    machine_mode mode = GET_MODE (operands[3]);
+    rtx_code rc = GET_CODE (operands[2]);
+
+    if (mode == CCFPmode || mode == CCFPEmode)
+      rc = reverse_condition_maybe_unordered (rc);
+    else
+      rc = reverse_condition (rc);
+    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
+  }
   [(set_attr "conds" "use")
    (set_attr "length" "8")
    (set_attr "type" "multiple")]
index 29a048d..64687d7 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-22  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR target/69403
+       * gcc.c-torture/execute/pr69403.c: New test.
+
 2016-01-22  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/55843
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr69403.c b/gcc/testsuite/gcc.c-torture/execute/pr69403.c
new file mode 100644 (file)
index 0000000..097d366
--- /dev/null
@@ -0,0 +1,20 @@
+/* PR target/69403.  */
+
+int a, b, c;
+
+__attribute__ ((__noinline__)) int
+fn1 ()
+{
+  if ((b | (a != (a & c))) == 1)
+    __builtin_abort ();
+  return 0;
+}
+
+int
+main (void)
+{
+  a = 5;
+  c = 1;
+  b = 6;
+  return fn1 ();
+}