mirror of git://gcc.gnu.org/git/gcc.git
re PR target/57819 (Suboptimal shift patterns)
PR target/57819 * simplify-rtx.c (simplify_unary_operation_1) <case ZERO_EXTEND>: Simplify (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)). * combine.c (make_extraction): Create ZERO_EXTEND or SIGN_EXTEND using simplify_gen_unary instead of gen_rtx_*_EXTEND. * config/i386/i386.md (*jcc_bt<mode>_1): New define_insn_and_split. * gcc.target/i386/pr57819.c: New test. From-SVN: r200775
This commit is contained in:
parent
78d432da45
commit
8140c06592
|
|
@ -1,5 +1,13 @@
|
||||||
2013-07-08 Jakub Jelinek <jakub@redhat.com>
|
2013-07-08 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR target/57819
|
||||||
|
* simplify-rtx.c (simplify_unary_operation_1) <case ZERO_EXTEND>:
|
||||||
|
Simplify (zero_extend:SI (subreg:QI (and:SI (reg:SI)
|
||||||
|
(const_int 63)) 0)).
|
||||||
|
* combine.c (make_extraction): Create ZERO_EXTEND or SIGN_EXTEND
|
||||||
|
using simplify_gen_unary instead of gen_rtx_*_EXTEND.
|
||||||
|
* config/i386/i386.md (*jcc_bt<mode>_1): New define_insn_and_split.
|
||||||
|
|
||||||
PR rtl-optimization/57829
|
PR rtl-optimization/57829
|
||||||
* simplify-rtx.c (simplify_binary_operation_1) <case IOR>: Ensure that
|
* simplify-rtx.c (simplify_binary_operation_1) <case IOR>: Ensure that
|
||||||
mask bits outside of mode are just sign-extension from mode to HWI.
|
mask bits outside of mode are just sign-extension from mode to HWI.
|
||||||
|
|
|
||||||
|
|
@ -7326,7 +7326,8 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
|
||||||
if (pos_rtx != 0
|
if (pos_rtx != 0
|
||||||
&& GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
|
&& GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
|
||||||
{
|
{
|
||||||
rtx temp = gen_rtx_ZERO_EXTEND (pos_mode, pos_rtx);
|
rtx temp = simplify_gen_unary (ZERO_EXTEND, pos_mode, pos_rtx,
|
||||||
|
GET_MODE (pos_rtx));
|
||||||
|
|
||||||
/* If we know that no extraneous bits are set, and that the high
|
/* If we know that no extraneous bits are set, and that the high
|
||||||
bit is not set, convert extraction to cheaper one - either
|
bit is not set, convert extraction to cheaper one - either
|
||||||
|
|
@ -7340,7 +7341,8 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
|
||||||
>> 1))
|
>> 1))
|
||||||
== 0)))
|
== 0)))
|
||||||
{
|
{
|
||||||
rtx temp1 = gen_rtx_SIGN_EXTEND (pos_mode, pos_rtx);
|
rtx temp1 = simplify_gen_unary (SIGN_EXTEND, pos_mode, pos_rtx,
|
||||||
|
GET_MODE (pos_rtx));
|
||||||
|
|
||||||
/* Prefer ZERO_EXTENSION, since it gives more information to
|
/* Prefer ZERO_EXTENSION, since it gives more information to
|
||||||
backends. */
|
backends. */
|
||||||
|
|
|
||||||
|
|
@ -10474,6 +10474,39 @@
|
||||||
PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
|
PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
|
||||||
})
|
})
|
||||||
|
|
||||||
|
;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
|
||||||
|
;; zero extended to SImode.
|
||||||
|
(define_insn_and_split "*jcc_bt<mode>_1"
|
||||||
|
[(set (pc)
|
||||||
|
(if_then_else (match_operator 0 "bt_comparison_operator"
|
||||||
|
[(zero_extract:SWI48
|
||||||
|
(match_operand:SWI48 1 "register_operand" "r")
|
||||||
|
(const_int 1)
|
||||||
|
(match_operand:SI 2 "register_operand" "r"))
|
||||||
|
(const_int 0)])
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))
|
||||||
|
(clobber (reg:CC FLAGS_REG))]
|
||||||
|
"TARGET_USE_BT || optimize_function_for_size_p (cfun)"
|
||||||
|
"#"
|
||||||
|
"&& 1"
|
||||||
|
[(set (reg:CCC FLAGS_REG)
|
||||||
|
(compare:CCC
|
||||||
|
(zero_extract:SWI48
|
||||||
|
(match_dup 1)
|
||||||
|
(const_int 1)
|
||||||
|
(match_dup 2))
|
||||||
|
(const_int 0)))
|
||||||
|
(set (pc)
|
||||||
|
(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
|
||||||
|
(label_ref (match_dup 3))
|
||||||
|
(pc)))]
|
||||||
|
{
|
||||||
|
operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
|
||||||
|
|
||||||
|
PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
|
||||||
|
})
|
||||||
|
|
||||||
;; Avoid useless masking of bit offset operand. "and" in SImode is correct
|
;; Avoid useless masking of bit offset operand. "and" in SImode is correct
|
||||||
;; also for DImode, this is what combine produces.
|
;; also for DImode, this is what combine produces.
|
||||||
(define_insn_and_split "*jcc_bt<mode>_mask"
|
(define_insn_and_split "*jcc_bt<mode>_mask"
|
||||||
|
|
|
||||||
|
|
@ -1470,6 +1470,29 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
|
||||||
|
(zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
|
||||||
|
of mode N. E.g.
|
||||||
|
(zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
|
||||||
|
(and:SI (reg:SI) (const_int 63)). */
|
||||||
|
if (GET_CODE (op) == SUBREG
|
||||||
|
&& GET_MODE_PRECISION (GET_MODE (op))
|
||||||
|
< GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op)))
|
||||||
|
&& GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op)))
|
||||||
|
<= HOST_BITS_PER_WIDE_INT
|
||||||
|
&& GET_MODE_PRECISION (mode)
|
||||||
|
>= GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op)))
|
||||||
|
&& subreg_lowpart_p (op)
|
||||||
|
&& (nonzero_bits (SUBREG_REG (op), GET_MODE (SUBREG_REG (op)))
|
||||||
|
& ~GET_MODE_MASK (GET_MODE (op))) == 0)
|
||||||
|
{
|
||||||
|
if (GET_MODE_PRECISION (mode)
|
||||||
|
== GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op))))
|
||||||
|
return SUBREG_REG (op);
|
||||||
|
return simplify_gen_unary (ZERO_EXTEND, mode, SUBREG_REG (op),
|
||||||
|
GET_MODE (SUBREG_REG (op)));
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
|
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
|
||||||
/* As we do not know which address space the pointer is referring to,
|
/* As we do not know which address space the pointer is referring to,
|
||||||
we can do this only if the target does not support different pointer
|
we can do this only if the target does not support different pointer
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
2013-07-08 Jakub Jelinek <jakub@redhat.com>
|
2013-07-08 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR target/57819
|
||||||
|
* gcc.target/i386/pr57819.c: New test.
|
||||||
|
|
||||||
PR rtl-optimization/57829
|
PR rtl-optimization/57829
|
||||||
* gcc.c-torture/execute/pr57829.c: New test.
|
* gcc.c-torture/execute/pr57829.c: New test.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* PR target/57819 */
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -mtune=core2" } */
|
||||||
|
|
||||||
|
void foo (void);
|
||||||
|
|
||||||
|
__extension__ typedef __INTPTR_TYPE__ intptr_t;
|
||||||
|
|
||||||
|
int
|
||||||
|
test1 (intptr_t x, intptr_t n)
|
||||||
|
{
|
||||||
|
n &= sizeof (intptr_t) * __CHAR_BIT__ - 1;
|
||||||
|
|
||||||
|
if (x & ((intptr_t) 1 << n))
|
||||||
|
foo ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test2 (intptr_t x, intptr_t n)
|
||||||
|
{
|
||||||
|
if (x & ((intptr_t) 1 << ((int) n & (sizeof (intptr_t) * __CHAR_BIT__ - 1))))
|
||||||
|
foo ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test3 (intptr_t x, intptr_t n)
|
||||||
|
{
|
||||||
|
if (x & ((intptr_t) 1 << ((int) n & ((int) sizeof (intptr_t) * __CHAR_BIT__ - 1))))
|
||||||
|
foo ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-not "and\[lq\]\[ \t\]" } } */
|
||||||
Loading…
Reference in New Issue