This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR target/21416: Fix MIPS __builtin_isless{,equal}


This patch fixes target/21416, in which we were using signalling
comparisons to implement __builtin_isless and __builtin_islessequal.
It generalises the existing GE/GT code to apply to UNGE and UNGT
as well.

Tested on mips64-elf and applied to mainline.  I think this is
is a regression from 2.95, so I'll apply it to 4.0 as well after
testing has finished.  3.4 predates the macro stuff and will need
a slightly different patch.

Richard


	PR target/21416
	* config/mips/mips.c (mips_emit_compare): Don't reverse UNGE and UNGT
	comparisons.
	* config/mips/mips.md (swapped_fcond): New code macro and attribute.
	(sgt_<mode>, sge_<mode>): Generalize to all members of swapped_fcond,
	including sunge_<mode> and sungt_<mode>.

testsuite/
	PR target/21416
	* gcc.target/mips/fpcmp-[12].c: New tests.

Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.500
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.500 mips.c
--- config/mips/mips.c	7 May 2005 09:48:29 -0000	1.500
+++ config/mips/mips.c	8 May 2005 06:48:59 -0000
@@ -2802,8 +2802,6 @@ mips_emit_compare (enum rtx_code *code, 
       switch (*code)
 	{
 	case NE:
-	case UNGE:
-	case UNGT:
 	case LTGT:
 	case ORDERED:
 	  cmp_code = reverse_condition_maybe_unordered (*code);
Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.315
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.315 mips.md
--- config/mips/mips.md	13 Mar 2005 18:03:25 -0000	1.315
+++ config/mips/mips.md	8 May 2005 06:49:00 -0000
@@ -413,6 +413,10 @@ (define_code_macro any_shift [ashift ash
 ;; generated from the same template.
 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
 
+;; This code macro is used for comparisons that can be implemented
+;; by swapping the operands.
+(define_code_macro swapped_fcond [ge gt unge ungt])
+
 ;; <u> expands to an empty string when doing a signed operation and
 ;; "u" when doing an unsigned operation.
 (define_code_attr u [(sign_extend "") (zero_extend "u")])
@@ -438,6 +442,12 @@ (define_code_attr fcond [(unordered "un"
 			 (eq "eq")
 			 (lt "lt")
 			 (le "le")])
+
+;; Similar, but for swapped conditions.
+(define_code_attr swapped_fcond [(ge "le")
+				 (gt "lt")
+				 (unge "ule")
+				 (ungt "ult")])
 
 ;; .........................
 ;;
@@ -4576,21 +4586,12 @@ (define_insn "s<code>_<mode>"
   [(set_attr "type" "fcmp")
    (set_attr "mode" "FPSW")])
 
-(define_insn "sgt_<mode>"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-	(gt:CC (match_operand:SCALARF 1 "register_operand" "f")
-	       (match_operand:SCALARF 2 "register_operand" "f")))]
-  ""
-  "c.lt.<fmt>\t%Z0%2,%1"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sge_<mode>"
+(define_insn "s<code>_<mode>"
   [(set (match_operand:CC 0 "register_operand" "=z")
-	(ge:CC (match_operand:SCALARF 1 "register_operand" "f")
-	       (match_operand:SCALARF 2 "register_operand" "f")))]
+	(swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
+		          (match_operand:SCALARF 2 "register_operand" "f")))]
   ""
-  "c.le.<fmt>\t%Z0%2,%1"
+  "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
   [(set_attr "type" "fcmp")
    (set_attr "mode" "FPSW")])
 
diff -u /dev/null testsuite/gcc.target/mips/fpcmp-1.c
--- /dev/null	2005-03-29 10:04:47.000000000 +0100
+++ testsuite/gcc.target/mips/fpcmp-1.c	2005-05-07 22:12:37.000000000 +0100
@@ -0,0 +1,6 @@
+/* We used to use c.lt.fmt instead of c.ule.fmt here.  */
+/* { dg-options "-mhard-float -O2" } */
+int f1 (float x, float y) { return __builtin_isless (x, y); }
+int f2 (double x, double y) { return __builtin_isless (x, y); }
+/* { dg-final { scan-assembler "c\\.ule\\.s" } } */
+/* { dg-final { scan-assembler "c\\.ule\\.d" } } */
diff -u /dev/null testsuite/gcc.target/mips/fpcmp-2.c
--- /dev/null	2005-03-29 10:04:47.000000000 +0100
+++ testsuite/gcc.target/mips/fpcmp-2.c	2005-05-07 22:12:18.000000000 +0100
@@ -0,0 +1,6 @@
+/* We used to use c.le.fmt instead of c.ult.fmt here.  */
+/* { dg-options "-mhard-float -O2" } */
+int f1 (float x, float y) { return __builtin_islessequal (x, y); }
+int f2 (double x, double y) { return __builtin_islessequal (x, y); }
+/* { dg-final { scan-assembler "c\\.ult\\.s" } } */
+/* { dg-final { scan-assembler "c\\.ult\\.d" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]