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.
This commit is contained in:
parent
1266778548
commit
7c2879301d
6 changed files with 95 additions and 0 deletions
|
@ -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.
|
||||
|
|
|
@ -12324,6 +12324,21 @@
|
|||
|
||||
;; Store-flag instructions.
|
||||
|
||||
(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"
|
||||
|
@ -12518,6 +12533,26 @@
|
|||
|
||||
;; Basic conditional jump instructions.
|
||||
|
||||
(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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
21
gcc/testsuite/gcc.target/i386/pr94913-1.c
Normal file
21
gcc/testsuite/gcc.target/i386/pr94913-1.c
Normal file
|
@ -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 } } */
|
24
gcc/testsuite/gcc.target/i386/pr94913-2.c
Normal file
24
gcc/testsuite/gcc.target/i386/pr94913-2.c
Normal file
|
@ -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 } } */
|
Loading…
Add table
Reference in a new issue