* config/ia64/predicates.md (ia64_cbranch_operator): Accept unordered
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Sep 2013 21:12:20 +0000 (21:12 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Sep 2013 21:12:20 +0000 (21:12 +0000)
comparison operators when -fno-trapping-math is in effect.
* config/ia64/ia64.c (ia64_expand_compare): Add support for unordered
comparison operators in TFmode and assert that unsupported operators
cannot reach here.
(ia64_print_operand): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202814 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/ia64/ia64.c
gcc/config/ia64/predicates.md

index a4dbd39..57fb929 100644 (file)
@@ -1,4 +1,13 @@
-2013-09-20  Jan Hubicka  <jh@suse.cz>
+2013-09-21  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * config/ia64/predicates.md (ia64_cbranch_operator): Accept unordered
+       comparison operators when -fno-trapping-math is in effect.
+       * config/ia64/ia64.c (ia64_expand_compare): Add support for unordered
+       comparison operators in TFmode and assert that unsupported operators
+       cannot reach here.
+       (ia64_print_operand): Likewise.
+
+2013-09-21  Jan Hubicka  <jh@suse.cz>
 
        * x86-tune.def (partial_reg_stall): Disable for CoreI7 and newer.
        (sse_typeless_stores): Enable for core
index a128b19..e12b080 100644 (file)
@@ -1754,7 +1754,7 @@ ia64_expand_compare (rtx *expr, rtx *op0, rtx *op1)
   else if (TARGET_HPUX && GET_MODE (*op0) == TFmode)
     {
       enum qfcmp_magic {
-       QCMP_INV = 1,   /* Raise FP_INVALID on SNaN as a side effect.  */
+       QCMP_INV = 1,   /* Raise FP_INVALID on NaNs as a side effect.  */
        QCMP_UNORD = 2,
        QCMP_EQ = 4,
        QCMP_LT = 8,
@@ -1768,21 +1768,27 @@ ia64_expand_compare (rtx *expr, rtx *op0, rtx *op1)
       switch (code)
        {
          /* 1 = equal, 0 = not equal.  Equality operators do
-            not raise FP_INVALID when given an SNaN operand.  */
+            not raise FP_INVALID when given a NaN operand.  */
        case EQ:        magic = QCMP_EQ;                  ncode = NE; break;
        case NE:        magic = QCMP_EQ;                  ncode = EQ; break;
          /* isunordered() from C99.  */
        case UNORDERED: magic = QCMP_UNORD;               ncode = NE; break;
        case ORDERED:   magic = QCMP_UNORD;               ncode = EQ; break;
          /* Relational operators raise FP_INVALID when given
-            an SNaN operand.  */
+            a NaN operand.  */
        case LT:        magic = QCMP_LT        |QCMP_INV; ncode = NE; break;
        case LE:        magic = QCMP_LT|QCMP_EQ|QCMP_INV; ncode = NE; break;
        case GT:        magic = QCMP_GT        |QCMP_INV; ncode = NE; break;
        case GE:        magic = QCMP_GT|QCMP_EQ|QCMP_INV; ncode = NE; break;
-         /* FUTURE: Implement UNEQ, UNLT, UNLE, UNGT, UNGE, LTGT.
-            Expanders for buneq etc. weuld have to be added to ia64.md
-            for this to be useful.  */
+          /* Unordered relational operators do not raise FP_INVALID
+            when given a NaN operand.  */
+       case UNLT:    magic = QCMP_LT        |QCMP_UNORD; ncode = NE; break;
+       case UNLE:    magic = QCMP_LT|QCMP_EQ|QCMP_UNORD; ncode = NE; break;
+       case UNGT:    magic = QCMP_GT        |QCMP_UNORD; ncode = NE; break;
+       case UNGE:    magic = QCMP_GT|QCMP_EQ|QCMP_UNORD; ncode = NE; break;
+         /* Not supported.  */
+       case UNEQ:
+       case LTGT:
        default: gcc_unreachable ();
        }
 
@@ -5277,6 +5283,9 @@ ia64_print_operand (FILE * file, rtx x, int code)
        case UNGE:
          str = "nlt";
          break;
+       case UNEQ:
+       case LTGT:
+         gcc_unreachable ();
        default:
          str = GET_RTX_NAME (GET_CODE (x));
          break;
index adfb15f..af7bc8e 100644 (file)
            (match_test "op == CONST0_RTX (GET_MODE (op))"))))
 
 ;; Return 1 if OP is a valid comparison operator for "cbranch" instructions.
+;; If we're assuming that FP operations cannot generate user-visible traps,
+;; then we can use the FP unordered-signaling instructions to implement the
+;; FP unordered-quiet comparison predicates.
 (define_predicate "ia64_cbranch_operator"
-  (ior (match_operand 0 "ordered_comparison_operator")
-       (match_code "ordered,unordered")))
+  (if_then_else (match_test "flag_trapping_math")
+               (ior (match_operand 0 "ordered_comparison_operator")
+                     (match_code "ordered,unordered"))
+               (and (match_operand 0 "comparison_operator")
+                     (not (match_code "uneq,ltgt")))))
 
 ;; True if this is a comparison operator, which accepts a normal 8-bit
 ;; signed immediate operand.