re PR rtl-optimization/70467 (Useless "and [esp],-1" emitted on AND with uint64_t variable)
PR rtl-optimization/70467 * config/i386/predicates.md (x86_64_hilo_int_operand, x86_64_hilo_general_operand): New predicates. * config/i386/constraints.md (Wd): New constraint. * config/i386/i386.md (mode attr di): Use Wd instead of e. (general_hilo_operand): New mode attr. (add<mode>3, sub<mode>3): Use <general_hilo_operand> instead of <general_operand>. (*add<dwi>3_doubleword, *sub<dwi>3_doubleword): Use x86_64_hilo_general_operand instead of <general_operand>. * gcc.target/i386/pr70467-3.c: New test. * gcc.target/i386/pr70467-4.c: New test. Co-Authored-By: Uros Bizjak <ubizjak@gmail.com> From-SVN: r235816
This commit is contained in:
parent
e7437b594f
commit
31ed166586
7 changed files with 107 additions and 5 deletions
|
@ -1,3 +1,17 @@
|
|||
2016-05-03 Jakub Jelinek <jakub@redhat.com>
|
||||
Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR rtl-optimization/70467
|
||||
* config/i386/predicates.md (x86_64_hilo_int_operand,
|
||||
x86_64_hilo_general_operand): New predicates.
|
||||
* config/i386/constraints.md (Wd): New constraint.
|
||||
* config/i386/i386.md (mode attr di): Use Wd instead of e.
|
||||
(general_hilo_operand): New mode attr.
|
||||
(add<mode>3, sub<mode>3): Use <general_hilo_operand>
|
||||
instead of <general_operand>.
|
||||
(*add<dwi>3_doubleword, *sub<dwi>3_doubleword): Use
|
||||
x86_64_hilo_general_operand instead of <general_operand>.
|
||||
|
||||
2016-05-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/70916
|
||||
|
|
|
@ -270,6 +270,11 @@
|
|||
(and (match_operand 0 "x86_64_zext_immediate_operand")
|
||||
(match_test "GET_MODE (op) != VOIDmode")))
|
||||
|
||||
(define_constraint "Wd"
|
||||
"128-bit integer constant where both the high and low 64-bit word
|
||||
of it satisfies the e constraint."
|
||||
(match_operand 0 "x86_64_hilo_int_operand"))
|
||||
|
||||
(define_constraint "Z"
|
||||
"32-bit unsigned integer constant, or a symbolic reference known
|
||||
to fit that range (for immediate operands in zero-extending x86-64
|
||||
|
|
|
@ -1065,7 +1065,7 @@
|
|||
(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
|
||||
|
||||
;; Immediate operand constraint for double integer modes.
|
||||
(define_mode_attr di [(SI "nF") (DI "e")])
|
||||
(define_mode_attr di [(SI "nF") (DI "Wd")])
|
||||
|
||||
;; Immediate operand constraint for shifts.
|
||||
(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
|
||||
|
@ -1078,6 +1078,15 @@
|
|||
(DI "x86_64_general_operand")
|
||||
(TI "x86_64_general_operand")])
|
||||
|
||||
;; General operand predicate for integer modes, where for TImode
|
||||
;; we need both words of the operand to be general operands.
|
||||
(define_mode_attr general_hilo_operand
|
||||
[(QI "general_operand")
|
||||
(HI "general_operand")
|
||||
(SI "x86_64_general_operand")
|
||||
(DI "x86_64_general_operand")
|
||||
(TI "x86_64_hilo_general_operand")])
|
||||
|
||||
;; General sign extend operand predicate for integer modes,
|
||||
;; which disallows VOIDmode operands and thus it is suitable
|
||||
;; for use inside sign_extend.
|
||||
|
@ -5433,7 +5442,7 @@
|
|||
(define_expand "add<mode>3"
|
||||
[(set (match_operand:SDWIM 0 "nonimmediate_operand")
|
||||
(plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
|
||||
(match_operand:SDWIM 2 "<general_operand>")))]
|
||||
(match_operand:SDWIM 2 "<general_hilo_operand>")))]
|
||||
""
|
||||
"ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
|
||||
|
||||
|
@ -5441,7 +5450,8 @@
|
|||
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
|
||||
(plus:<DWI>
|
||||
(match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
|
||||
(match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
|
||||
(match_operand:<DWI> 2 "x86_64_hilo_general_operand"
|
||||
"ro<di>,r<di>")))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
|
||||
"#"
|
||||
|
@ -6345,7 +6355,7 @@
|
|||
(define_expand "sub<mode>3"
|
||||
[(set (match_operand:SDWIM 0 "nonimmediate_operand")
|
||||
(minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
|
||||
(match_operand:SDWIM 2 "<general_operand>")))]
|
||||
(match_operand:SDWIM 2 "<general_hilo_operand>")))]
|
||||
""
|
||||
"ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
|
||||
|
||||
|
@ -6353,7 +6363,8 @@
|
|||
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
|
||||
(minus:<DWI>
|
||||
(match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
|
||||
(match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
|
||||
(match_operand:<DWI> 2 "x86_64_hilo_general_operand"
|
||||
"ro<di>,r<di>")))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
|
||||
"#"
|
||||
|
|
|
@ -342,6 +342,29 @@
|
|||
return false;
|
||||
})
|
||||
|
||||
;; Return true if VALUE is a constant integer whose low and high words satisfy
|
||||
;; x86_64_immediate_operand.
|
||||
(define_predicate "x86_64_hilo_int_operand"
|
||||
(match_code "const_int,const_wide_int")
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case CONST_INT:
|
||||
return x86_64_immediate_operand (op, mode);
|
||||
|
||||
case CONST_WIDE_INT:
|
||||
gcc_assert (CONST_WIDE_INT_NUNITS (op) == 2);
|
||||
return (x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op, 0)),
|
||||
DImode)
|
||||
&& x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op,
|
||||
1)),
|
||||
DImode));
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
})
|
||||
|
||||
;; Return true if size of VALUE can be stored in a sign
|
||||
;; extended immediate field.
|
||||
(define_predicate "x86_64_immediate_size_operand"
|
||||
|
@ -357,6 +380,14 @@
|
|||
(match_operand 0 "x86_64_immediate_operand"))
|
||||
(match_operand 0 "general_operand")))
|
||||
|
||||
;; Return true if OP's both words are general operands representable
|
||||
;; on x86_64.
|
||||
(define_predicate "x86_64_hilo_general_operand"
|
||||
(if_then_else (match_test "TARGET_64BIT")
|
||||
(ior (match_operand 0 "nonimmediate_operand")
|
||||
(match_operand 0 "x86_64_hilo_int_operand"))
|
||||
(match_operand 0 "general_operand")))
|
||||
|
||||
;; Return true if OP is non-VOIDmode general operand representable
|
||||
;; on x86_64. This predicate is used in sign-extending conversion
|
||||
;; operations that require non-VOIDmode immediate operands.
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
2016-05-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/70467
|
||||
* gcc.target/i386/pr70467-3.c: New test.
|
||||
* gcc.target/i386/pr70467-4.c: New test.
|
||||
|
||||
PR tree-optimization/70916
|
||||
* gcc.c-torture/compile/pr70916.c: New test.
|
||||
|
||||
|
|
19
gcc/testsuite/gcc.target/i386/pr70467-3.c
Normal file
19
gcc/testsuite/gcc.target/i386/pr70467-3.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* PR rtl-optimization/70467 */
|
||||
/* { dg-do compile { target int128 } } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
__uint128_t
|
||||
foo (__uint128_t x)
|
||||
{
|
||||
return x + ((__uint128_t) 123456 << 64);
|
||||
}
|
||||
|
||||
__uint128_t
|
||||
bar (__uint128_t x)
|
||||
{
|
||||
return x - ((__uint128_t) 123456 << 64);
|
||||
}
|
||||
|
||||
/* Make sure there are no unnecessary additions with carry. */
|
||||
/* { dg-final { scan-assembler-not "adcq\[^\n\r\]*%" } } */
|
||||
/* { dg-final { scan-assembler-not "sbbq\[^\n\r\]*%" } } */
|
18
gcc/testsuite/gcc.target/i386/pr70467-4.c
Normal file
18
gcc/testsuite/gcc.target/i386/pr70467-4.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* PR rtl-optimization/70467 */
|
||||
/* { dg-do compile { target int128 } } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
__uint128_t
|
||||
foo (__uint128_t x)
|
||||
{
|
||||
return x + ((__uint128_t) 123456 << 64) + 0x1234567;
|
||||
}
|
||||
|
||||
__uint128_t
|
||||
bar (__uint128_t x)
|
||||
{
|
||||
return x - ((__uint128_t) 123456 << 64) + 0x1234567;
|
||||
}
|
||||
|
||||
/* Make sure the immediates are not loaded into registers first. */
|
||||
/* { dg-final { scan-assembler-not "mov\[lq\]\[ \t\]*.\[0-9-\]" } } */
|
Loading…
Add table
Reference in a new issue