diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2020-05-06 17:33:51 +0200 |
---|---|---|
committer | Uros Bizjak <ubizjak@gmail.com> | 2020-05-06 17:33:51 +0200 |
commit | 7c2879301d3b027a1ba427a5d5c7557decb8a7ab (patch) | |
tree | 88de4ce841571a83a2dba3f013b5d79b2768a4f0 /gcc | |
parent | 1266778548e20de82983b6446f3cb685068cfb1e (diff) | |
download | gcc-7c2879301d3b027a1ba427a5d5c7557decb8a7ab.zip gcc-7c2879301d3b027a1ba427a5d5c7557decb8a7ab.tar.gz gcc-7c2879301d3b027a1ba427a5d5c7557decb8a7ab.tar.bz2 |
i386: Use ADD to implement compares with negated operand [PR94913]
Use carry flag from addition to implement GEU/LTU compares
with negated operand, so e.g.
~x < y
compiles to:
addq %rsi, %rdi
setc %al
instead of:
notq %rdi
cmpq %rsi, %rdi
setb %al
PR target/94913
* config/i386/predicates.md (add_comparison_operator): New predicate.
* config/i386/i386.md (compare->add splitter): New splitters.
testsuite/ChangeLog:
PR target/94913
* gcc.target/i386/pr94913-1.c: New test.
* gcc.target/i386/pr94913-2.c: Ditto.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 35 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr94913-1.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr94913-2.c | 24 |
6 files changed, 95 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9e5a434..bc27083 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-05-06 Uroš Bizjak <ubizjak@gmail.com> + + PR target/94913 + * config/i386/predicates.md (add_comparison_operator): New predicate. + * config/i386/i386.md (compare->add splitter): New splitters. + 2020-05-06 Richard Biener <rguenther@suse.de> * tree-vectorizer.h (vect_transform_slp_perm_load): Adjust. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 911ef7a..5fe851e 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12326,6 +12326,21 @@ (define_split [(set (match_operand:QI 0 "nonimmediate_operand") + (match_operator:QI 1 "add_comparison_operator" + [(not:SWI (match_operand:SWI 2 "register_operand")) + (match_operand:SWI 3 "nonimmediate_operand")]))] + "" + [(parallel + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (plus:SWI (match_dup 2) (match_dup 3)) + (match_dup 2))) + (clobber (scratch:SWI))]) + (set (match_dup 0) + (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))]) + +(define_split + [(set (match_operand:QI 0 "nonimmediate_operand") (match_operator:QI 1 "shr_comparison_operator" [(match_operand:DI 2 "register_operand") (match_operand 3 "const_int_operand")]))] @@ -12521,6 +12536,26 @@ (define_split [(set (pc) (if_then_else + (match_operator 1 "add_comparison_operator" + [(not:SWI (match_operand:SWI 2 "register_operand")) + (match_operand:SWI 3 "nonimmediate_operand")]) + (label_ref (match_operand 0)) + (pc)))] + "" + [(parallel + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (plus:SWI (match_dup 2) (match_dup 3)) + (match_dup 2))) + (clobber (scratch:SWI))]) + (set (pc) + (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]) + (label_ref (match_operand 0)) + (pc)))]) + +(define_split + [(set (pc) + (if_then_else (match_operator 1 "shr_comparison_operator" [(match_operand:DI 2 "register_operand") (match_operand 3 "const_int_operand")]) diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 1a5e221..8d8bcb1 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1293,6 +1293,9 @@ (define_predicate "shr_comparison_operator" (match_code "gtu,leu")) +(define_predicate "add_comparison_operator" + (match_code "geu,ltu")) + ;; Return true if OP is a valid comparison operator in valid mode. (define_predicate "ix86_comparison_operator" (match_operand 0 "comparison_operator") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a3cf68d..ccdbf98 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-05-06 Uroš Bizjak <ubizjak@gmail.com> + + PR target/94913 + * gcc.target/i386/pr94913-1.c: New test. + * gcc.target/i386/pr94913-2.c: Ditto. + 2020-05-06 Richard Biener <rguenther@suse.de> PR tree-optimization/94963 diff --git a/gcc/testsuite/gcc.target/i386/pr94913-1.c b/gcc/testsuite/gcc.target/i386/pr94913-1.c new file mode 100644 index 0000000..f21032d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr94913-1.c @@ -0,0 +1,21 @@ +/* PR target/94913 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +char fooc (unsigned char x, unsigned char y) +{ + return (unsigned char) ~x < y; +} + +short foos (unsigned short x, unsigned short y) +{ + return (unsigned short) ~x < y; +} + +long fooi (unsigned long x, unsigned long y) +{ + return (unsigned long) ~x < y; +} + +/* { dg-final { scan-assembler-not "cmp" } } */ +/* { dg-final { scan-assembler-times "add" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr94913-2.c b/gcc/testsuite/gcc.target/i386/pr94913-2.c new file mode 100644 index 0000000..22bca2b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr94913-2.c @@ -0,0 +1,24 @@ +/* PR target/94913 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void f1 (void); +void f2 (void); + +void fooc (unsigned char x, unsigned char y) +{ + if ((unsigned char) ~x < y) f1 (); else f2 (); +} + +void foos (unsigned short x, unsigned short y) +{ + if ((unsigned short) ~x < y) f1 (); else f2 (); +} + +void fooi (unsigned long x, unsigned long y) +{ + if ((unsigned long) ~x < y) f1 (); else f2 (); +} + +/* { dg-final { scan-assembler-not "cmp" } } */ +/* { dg-final { scan-assembler-times "add" 3 } } */ |