Commit 6754dfa2 by Uros Bizjak Committed by Uros Bizjak

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
parent 782e4764
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> 2018-04-28 Richard Biener <rguenther@suse.de>
* tree-cfg.c (verify_gimple_phi): Take a gphi * argument. * tree-cfg.c (verify_gimple_phi): Take a gphi * argument.
......
...@@ -10357,6 +10357,77 @@ ...@@ -10357,6 +10357,77 @@
"" ""
"ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") "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" (define_insn "*ashl<mode>3_doubleword"
[(set (match_operand:DWI 0 "register_operand" "=&r") [(set (match_operand:DWI 0 "register_operand" "=&r")
(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n") (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
...@@ -11038,6 +11109,77 @@ ...@@ -11038,6 +11109,77 @@
"" ""
[(set_attr "isa" "*,bmi2")]) [(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" (define_insn_and_split "*<shift_insn><mode>3_doubleword"
[(set (match_operand:DWI 0 "register_operand" "=&r") [(set (match_operand:DWI 0 "register_operand" "=&r")
(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
......
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> 2018-04-27 Martin Jambor <mjambor@suse.cz>
PR ipa/85549 PR ipa/85549
......
/* 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment