From a5224bb7cbe718679e383eed773903c8f0c4ea2c Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 18 Jun 2015 21:26:26 +0200 Subject: [PATCH] i386.md (*movsicc_noc_zext): New insn. * 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 | 6 ++ gcc/config/i386/i386.md | 119 ++++++++++++++++++-------- gcc/testsuite/ChangeLog | 6 +- gcc/testsuite/gcc.target/i386/cmov9.c | 8 ++ 4 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/cmov9.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9fdc1076c15..25628faad67 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-06-18 Uros Bizjak + + * 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 * config/rs6000/rs6000.h (WORD_REGISTER_OPERATIONS): Delete. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b409c17266d..d75b2e119c3 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -16746,6 +16746,22 @@ [(set_attr "type" "icmov") (set_attr "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 @@ -16797,30 +16813,65 @@ ;; 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 "movcc" [(set (match_operand:X87MODEF 0 "register_operand") @@ -16922,34 +16973,34 @@ ;; 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 != 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 != 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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 66014bd10bd..9a3978b7e79 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-06-18 Uros Bizjak + + * gcc.target/i386/cmov9.c: New test. + 2015-06-18 Richard Biener * 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 diff --git a/gcc/testsuite/gcc.target/i386/cmov9.c b/gcc/testsuite/gcc.target/i386/cmov9.c new file mode 100644 index 00000000000..6f0c54e9120 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cmov9.c @@ -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; +} -- 2.30.2