i386.md (*movsicc_noc_zext): New insn.
authorUros Bizjak <ubizjak@gmail.com>
Thu, 18 Jun 2015 19:26:26 +0000 (21:26 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Thu, 18 Jun 2015 19:26:26 +0000 (21:26 +0200)
* config/i386/i386.md (*movsicc_noc_zext): New insn.
(zero-extended cmove with mem peephole2): New pattern.
(cmove with mem peephole2): Merge patterns.

testsuite/ChangeLog:

* gcc.target/i386/cmov9.c: New test.

From-SVN: r224631

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/cmov9.c [new file with mode: 0644]

index 9fdc1076c1551c45db0b5074767cddb9b98e0c85..25628faad67fd240fc85053b5f20a449c8b182f6 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-18  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (*movsicc_noc_zext): New insn.
+       (zero-extended cmove with mem peephole2): New pattern.
+       (cmove with mem peephole2): Merge patterns.
+
 2015-06-18  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * config/rs6000/rs6000.h (WORD_REGISTER_OPERATIONS): Delete.
index b409c17266d21810db12554705fa1dece8a36faa..d75b2e119c3b04527f2deab7e6f3d52e77b2092f 100644 (file)
   [(set_attr "type" "icmov")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*movsicc_noc_zext"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+       (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
+                          [(reg FLAGS_REG) (const_int 0)])
+         (zero_extend:DI
+           (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
+         (zero_extend:DI
+           (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
+  "TARGET_64BIT
+   && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
+  "@
+   cmov%O2%C1\t{%2, %k0|%k0, %2}
+   cmov%O2%c1\t{%3, %k0|%k0, %3}"
+  [(set_attr "type" "icmov")
+   (set_attr "mode" "SI")])
+
 ;; Don't do conditional moves with memory inputs.  This splitter helps
 ;; register starved x86_32 by forcing inputs into registers before reload.
 (define_split
 
 ;; Don't do conditional moves with memory inputs
 (define_peephole2
-  [(match_scratch:SWI248 2 "r")
+  [(match_scratch:SWI248 4 "r")
    (set (match_operand:SWI248 0 "register_operand")
        (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
                               [(reg FLAGS_REG) (const_int 0)])
-         (match_dup 0)
-         (match_operand:SWI248 3 "memory_operand")))]
+         (match_operand:SWI248 2 "nonimmediate_operand")
+         (match_operand:SWI248 3 "nonimmediate_operand")))]
   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+   && (MEM_P (operands[2]) || MEM_P (operands[3]))
    && optimize_insn_for_speed_p ()"
-  [(set (match_dup 2) (match_dup 3))
+  [(set (match_dup 4) (match_dup 5))
    (set (match_dup 0)
-       (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
+       (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
+{
+  if (MEM_P (operands[2]))
+    {
+      operands[5] = operands[2];
+      operands[2] = operands[4];
+    }
+  else if (MEM_P (operands[3]))
+    {
+      operands[5] = operands[3];
+      operands[3] = operands[4];
+    }
+  else
+    gcc_unreachable ();
+})
 
 (define_peephole2
-  [(match_scratch:SWI248 2 "r")
-   (set (match_operand:SWI248 0 "register_operand")
-       (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
-                              [(reg FLAGS_REG) (const_int 0)])
-         (match_operand:SWI248 3 "memory_operand")
-         (match_dup 0)))]
-  "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+  [(match_scratch:SI 4 "r")
+   (set (match_operand:DI 0 "register_operand")
+       (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
+                          [(reg FLAGS_REG) (const_int 0)])
+         (zero_extend:DI
+           (match_operand:SI 2 "nonimmediate_operand"))
+         (zero_extend:DI
+           (match_operand:SI 3 "nonimmediate_operand"))))]
+  "TARGET_64BIT
+   && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+   && (MEM_P (operands[2]) || MEM_P (operands[3]))
    && optimize_insn_for_speed_p ()"
-  [(set (match_dup 2) (match_dup 3))
+  [(set (match_dup 4) (match_dup 5))
    (set (match_dup 0)
-       (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
+       (if_then_else:DI (match_dup 1)
+         (zero_extend:DI (match_dup 2))
+         (zero_extend:DI (match_dup 3))))]
+{
+  if (MEM_P (operands[2]))
+    {
+      operands[5] = operands[2];
+      operands[2] = operands[4];
+    }
+  else if (MEM_P (operands[3]))
+    {
+      operands[5] = operands[3];
+      operands[3] = operands[4];
+    }
+  else
+    gcc_unreachable ();
+})
 
 (define_expand "mov<mode>cc"
   [(set (match_operand:X87MODEF 0 "register_operand")
 
 ;; Don't do conditional moves with memory inputs
 (define_peephole2
-  [(match_scratch:MODEF 2 "r")
-   (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
-       (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
-                             [(reg FLAGS_REG) (const_int 0)])
-         (match_dup 0)
-         (match_operand:MODEF 3 "memory_operand")))]
-  "(<MODE>mode != DFmode || TARGET_64BIT)
-   && TARGET_80387 && TARGET_CMOVE
-   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
-   && optimize_insn_for_speed_p ()"
-  [(set (match_dup 2) (match_dup 3))
-   (set (match_dup 0)
-       (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
-
-(define_peephole2
-  [(match_scratch:MODEF 2 "r")
+  [(match_scratch:MODEF 4 "r")
    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
        (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
                              [(reg FLAGS_REG) (const_int 0)])
-         (match_operand:MODEF 3 "memory_operand")
-         (match_dup 0)))]
+         (match_operand:MODEF 2 "nonimmediate_operand")
+         (match_operand:MODEF 3 "nonimmediate_operand")))]
   "(<MODE>mode != DFmode || TARGET_64BIT)
    && TARGET_80387 && TARGET_CMOVE
    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+   && (MEM_P (operands[2]) || MEM_P (operands[3]))
    && optimize_insn_for_speed_p ()"
-  [(set (match_dup 2) (match_dup 3))
+  [(set (match_dup 4) (match_dup 5))
    (set (match_dup 0)
-       (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
+       (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
+{
+  if (MEM_P (operands[2]))
+    {
+      operands[5] = operands[2];
+      operands[2] = operands[4];
+    }
+  else if (MEM_P (operands[3]))
+    {
+      operands[5] = operands[3];
+      operands[3] = operands[4];
+    }
+  else
+    gcc_unreachable ();
+})
 
 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
 ;; the scalar versions to have only XMM registers as operands.
index 66014bd10bd178338aa5bbecd0be5a479a7ad04c..9a3978b7e79e5bb81f537a75856c17ab51a0fb4b 100644 (file)
@@ -1,3 +1,7 @@
+2015-06-18  Uros Bizjak  <ubizjak@gmail.com>
+
+       * gcc.target/i386/cmov9.c: New test.
+
 2015-06-18  Richard Biener  <rguenther@suse.de>
 
        * g++.dg/other/const4.C: New testcase.
@@ -32,7 +36,7 @@
        * gcc.target/i386/noplt-1.c (dg-do): Fix target selector.
        * gcc.target/i386/noplt-2.c (dg-do): Ditto.
        * gcc.target/i386/noplt-3.c (dg-do): Ditto.
-       * gcc.target/i386/noplt-4.c (dg-do): ditto.
+       * gcc.target/i386/noplt-4.c (dg-do): Ditto.
 
 2015-06-17  Jakub Jelinek  <jakub@redhat.com>
 
diff --git a/gcc/testsuite/gcc.target/i386/cmov9.c b/gcc/testsuite/gcc.target/i386/cmov9.c
new file mode 100644 (file)
index 0000000..6f0c54e
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -dp" } */
+/* { dg-final { scan-assembler-not "zero_extendsidi" } } */
+
+unsigned long long foo (int a, unsigned int b, unsigned int c)
+{
+  return a ? b : c;
+}