aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-05-03 13:45:04 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-05-03 13:45:04 +0200
commit31ed166586451e3955d0da9c7931c71da968eee4 (patch)
tree1ce1e1bae4e7829ce25014d49a2a894842c9b7d1 /gcc
parente7437b594f9c54bc07a2ef0bda9801ce62b1eab7 (diff)
downloadgcc-31ed166586451e3955d0da9c7931c71da968eee4.zip
gcc-31ed166586451e3955d0da9c7931c71da968eee4.tar.gz
gcc-31ed166586451e3955d0da9c7931c71da968eee4.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/i386/constraints.md5
-rw-r--r--gcc/config/i386/i386.md21
-rw-r--r--gcc/config/i386/predicates.md31
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70467-3.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70467-4.c18
7 files changed, 107 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f2952eb..9b1b95b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,18 @@
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
* tree-if-conv.c (constant_or_ssa_name): Removed.
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 93d136b..ccebee7 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c409872..940dc20 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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)"
"#"
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index c1541b5..b3a471d 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0941f39..7a89868 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.target/i386/pr70467-3.c b/gcc/testsuite/gcc.target/i386/pr70467-3.c
new file mode 100644
index 0000000..4d2a6cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70467-3.c
@@ -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\]*%" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr70467-4.c b/gcc/testsuite/gcc.target/i386/pr70467-4.c
new file mode 100644
index 0000000..91f9b6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70467-4.c
@@ -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-\]" } } */