mirror of git://gcc.gnu.org/git/gcc.git
re PR target/84431 (Suboptimal code for masked shifts (x86/x86-64))
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. testsuite/ChangeLog: PR target/84431 * gcc.target/i386/pr84431.c: New test. From-SVN: r259739
This commit is contained in:
parent
782e476490
commit
6754dfa237
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" } } */
|
||||
Loading…
Reference in New Issue