Hello!

-march=i586 activates TARGET_ZERO_EXTEND_WITH_AND, which disables movz
instructions. These targets have to use and instructions, and when
flags are not allowed to be clobbered a sequence of register clear +
movstrict.

2016-01-27  Uros Bizjak  <ubiz...@gmail.com>

    PR target/69512
    * config/i386/i386.md (*zext<mode>_doubleword_and): New pattern.
    (*zext<mode>_doubleword): Disable for TARGET_ZERO_EXTEND_WITH_AND.

testsuite/ChangeLog:

2016-01-27  Uros Bizjak  <ubiz...@gmail.com>

    PR target/69512
    * gcc.target/i386/pr69512.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
Committed to mainline SVN.

Uros.
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 232878)
+++ config/i386/i386.md (working copy)
@@ -3874,10 +3874,29 @@
   [(set_attr "type" "imovx")
    (set_attr "mode" "SI")])
 
+(define_insn_and_split "*zext<mode>_doubleword_and"
+  [(set (match_operand:DI 0 "register_operand" "=&<r>")
+       (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
+  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
+  "#"
+  "&& reload_completed && GENERAL_REG_P (operands[0])"
+  [(set (match_dup 2) (const_int 0))]
+{
+  split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
+
+  emit_move_insn (operands[0], const0_rtx);
+
+  gcc_assert (!TARGET_PARTIAL_REG_STALL);
+  emit_insn (gen_movstrict<mode>
+            (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
+})
+
 (define_insn_and_split "*zext<mode>_doubleword"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
-  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
+  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+   && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
   "#"
   "&& reload_completed && GENERAL_REG_P (operands[0])"
   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
Index: testsuite/gcc.target/i386/pr69512.c
===================================================================
--- testsuite/gcc.target/i386/pr69512.c (nonexistent)
+++ testsuite/gcc.target/i386/pr69512.c (working copy)
@@ -0,0 +1,14 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-march=i586 -mavx -O2" } */
+
+extern double s1[];
+extern double s2[];
+extern long long e[];
+
+void test (void)
+{
+  int i;
+
+  for (i = 0; i < 2; i++)
+    e[i] = !__builtin_isunordered(s1[i], s2[i]) && s1[i] != s2[i] ? -1 : 0;
+}

Reply via email to