diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 142 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr84431.c | 19 |
4 files changed, 174 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edc952c..1433190 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-04-28 Uros Bizjak <ubizjak@gmail.com> + + PR target/84431 + * config/i386/i386.md (*ashl<dwi>3_doubleword_mask): New pattern. + (*ashl<dwi>3_doubleword_mask_1): Ditto. + (*<shift_insn><dwi>3_doubleword_mask): Ditto. + (*<shift_insn><dwi>3_doubleword_mask_1): Ditto. + 2018-04-28 Richard Biener <rguenther@suse.de> * tree-cfg.c (verify_gimple_phi): Take a gphi * argument. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index eacc3bb..d85d346 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -10357,6 +10357,77 @@ "" "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") +(define_insn_and_split "*ashl<dwi>3_doubleword_mask" + [(set (match_operand:<DWI> 0 "register_operand") + (ashift:<DWI> + (match_operand:<DWI> 1 "register_operand") + (subreg:QI + (and:SI + (match_operand:SI 2 "register_operand" "c") + (match_operand:SI 3 "const_int_operand")) 0))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 + && can_create_pseudo_p ()" + "#" + "&& 1" + [(parallel + [(set (match_dup 6) + (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2)) + (lshiftrt:DWIH (match_dup 5) + (minus:QI (match_dup 8) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))]) + (parallel + [(set (match_dup 4) + (ashift:DWIH (match_dup 5) (match_dup 2))) + (clobber (reg:CC FLAGS_REG))])] +{ + split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); + + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + + if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) + emit_insn (gen_andsi3 (operands[2], operands[2], operands[3])); + + operands[2] = gen_lowpart (QImode, operands[2]); + + if (!rtx_equal_p (operands[6], operands[7])) + emit_move_insn (operands[6], operands[7]); +}) + +(define_insn_and_split "*ashl<dwi>3_doubleword_mask_1" + [(set (match_operand:<DWI> 0 "register_operand") + (ashift:<DWI> + (match_operand:<DWI> 1 "register_operand") + (and:QI + (match_operand:QI 2 "register_operand" "c") + (match_operand:QI 3 "const_int_operand")))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 + && can_create_pseudo_p ()" + "#" + "&& 1" + [(parallel + [(set (match_dup 6) + (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2)) + (lshiftrt:DWIH (match_dup 5) + (minus:QI (match_dup 8) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))]) + (parallel + [(set (match_dup 4) + (ashift:DWIH (match_dup 5) (match_dup 2))) + (clobber (reg:CC FLAGS_REG))])] +{ + split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); + + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + + if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) + emit_insn (gen_andqi3 (operands[2], operands[2], operands[3])); + + if (!rtx_equal_p (operands[6], operands[7])) + emit_move_insn (operands[6], operands[7]); +}) + (define_insn "*ashl<mode>3_doubleword" [(set (match_operand:DWI 0 "register_operand" "=&r") (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n") @@ -11038,6 +11109,77 @@ "" [(set_attr "isa" "*,bmi2")]) +(define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask" + [(set (match_operand:<DWI> 0 "register_operand") + (any_shiftrt:<DWI> + (match_operand:<DWI> 1 "register_operand") + (subreg:QI + (and:SI + (match_operand:SI 2 "register_operand" "c") + (match_operand:SI 3 "const_int_operand")) 0))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 + && can_create_pseudo_p ()" + "#" + "&& 1" + [(parallel + [(set (match_dup 4) + (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) + (ashift:DWIH (match_dup 7) + (minus:QI (match_dup 8) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))]) + (parallel + [(set (match_dup 6) + (any_shiftrt:DWIH (match_dup 7) (match_dup 2))) + (clobber (reg:CC FLAGS_REG))])] +{ + split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); + + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + + if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) + emit_insn (gen_andsi3 (operands[2], operands[2], operands[3])); + + operands[2] = gen_lowpart (QImode, operands[2]); + + if (!rtx_equal_p (operands[4], operands[5])) + emit_move_insn (operands[4], operands[5]); +}) + +(define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1" + [(set (match_operand:<DWI> 0 "register_operand") + (any_shiftrt:<DWI> + (match_operand:<DWI> 1 "register_operand") + (and:QI + (match_operand:QI 2 "register_operand" "c") + (match_operand:QI 3 "const_int_operand")))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 + && can_create_pseudo_p ()" + "#" + "&& 1" + [(parallel + [(set (match_dup 4) + (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) + (ashift:DWIH (match_dup 7) + (minus:QI (match_dup 8) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))]) + (parallel + [(set (match_dup 6) + (any_shiftrt:DWIH (match_dup 7) (match_dup 2))) + (clobber (reg:CC FLAGS_REG))])] +{ + split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); + + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + + if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) + emit_insn (gen_andqi3 (operands[2], operands[2], operands[3])); + + if (!rtx_equal_p (operands[4], operands[5])) + emit_move_insn (operands[4], operands[5]); +}) + (define_insn_and_split "*<shift_insn><mode>3_doubleword" [(set (match_operand:DWI 0 "register_operand" "=&r") (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 47da043..ccc4d18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-04-28 Uros Bizjak <ubizjak@gmail.com> + + PR target/84431 + * gcc.target/i386/pr84431.c: New test. + 2018-04-27 Martin Jambor <mjambor@suse.cz> PR ipa/85549 diff --git a/gcc/testsuite/gcc.target/i386/pr84431.c b/gcc/testsuite/gcc.target/i386/pr84431.c new file mode 100644 index 0000000..ee751a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr84431.c @@ -0,0 +1,19 @@ +/* PR target/84431 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#ifdef __SIZEOF_INT128__ +typedef unsigned __int128 U; +typedef signed __int128 S; +# define M 63 +#else +typedef unsigned long long U; +typedef signed long long S; +# define M 31 +#endif + +S f1 (S a, int s) { return a >> (s & M); } +U f2 (U a, int s) { return a >> (s & M); } +U f3 (U a, int s) { return a << (s & M); } + +/* { dg-final { scan-assembler-not "and" } } */ |