[ARC] generate signaling FDCMPF for hard float comparisons
authorVineet Gupta <vgupta@synopsys.com>
Thu, 12 Dec 2019 08:42:21 +0000 (08:42 +0000)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Thu, 12 Dec 2019 08:42:21 +0000 (09:42 +0100)
PR 92846:
ARC gcc generates FDCMP instructions which raises Invalid operation for
signaling NaN only. This causes glibc iseqsig() primitives to fail (in
the current ongoing glibc port to ARC)

So break up the hard float compares into tw categories and for unordered
compares generate the FDCMPF instructions which raised exception for
either NaNs.

With this fix testsuite/gcc.dg/torture/pr52451.c passes for ARC.

Also no regressions for the glibc math testsuite, only 6 additional
passes for test*iseqsig

gcc/
xxxx-xx-xx  Vineet Gupta  <vgupta@synopsys.com>

* config/arc/arc-modes.def (CC_FPUE): New Mode CC_FPUE which
helps codegen generate exceptions even for quiet NaN.
* config/arc/arc.c (arc_init_reg_tables): Handle New CC_FPUE mode.
(get_arc_condition_code): Likewise.
(arc_select_cc_mode): LT, LE, GT, GE to use the New CC_FPUE mode.
* config/arc/arc.h (REVERSE_CONDITION): Handle New CC_FPUE mode.
* config/arc/predicates.md (proper_comparison_operator): Likewise.
* config/arc/fpu.md (cmpsf_fpu_trap): New Pattern for CC_FPUE.
(cmpdf_fpu_trap): Likewise.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
From-SVN: r279274

gcc/ChangeLog
gcc/config/arc/arc-modes.def
gcc/config/arc/arc.c
gcc/config/arc/arc.h
gcc/config/arc/fpu.md
gcc/config/arc/predicates.md

index b0e8e39c6333a9b43af046cc87e0d0e46b228176..c9eb4224d0165f20ff5a6faa90b2302bdbd921d8 100644 (file)
@@ -1,3 +1,15 @@
+2019-12-12  Vineet Gupta  <vgupta@synopsys.com>
+
+       * config/arc/arc-modes.def (CC_FPUE): New Mode CC_FPUE which
+       helps codegen generate exceptions even for quiet NaN.
+       * config/arc/arc.c (arc_init_reg_tables): Handle New CC_FPUE mode.
+       (get_arc_condition_code): Likewise.
+       (arc_select_cc_mode): LT, LE, GT, GE to use the New CC_FPUE mode.
+       * config/arc/arc.h (REVERSE_CONDITION): Handle New CC_FPUE mode.
+       * config/arc/predicates.md (proper_comparison_operator): Likewise.
+       * config/arc/fpu.md (cmpsf_fpu_trap): New Pattern for CC_FPUE.
+       (cmpdf_fpu_trap): Likewise.
+
 2019-12-12  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * config/arc/arc.md (iterator SDF): Check TARGET_FP_DP_BASE.
index 36a2f4abfb25a7e72bcedd642fcd221ba8904248..d16b6a289a15b807e397fe36f116e3e45bd8afe7 100644 (file)
@@ -38,4 +38,5 @@ VECTOR_MODES (INT, 16);       /* V16QI V8HI V4SI V2DI */
 
 /* FPU condition flags.  */
 CC_MODE (CC_FPU);
+CC_MODE (CC_FPUE);
 CC_MODE (CC_FPU_UNEQ);
index 28305f459dcdeb1d8a55f7f65b82ec365ea4b69c..cbb95d6e9043cc8556726219fa2f4e2037eed851 100644 (file)
@@ -1564,6 +1564,7 @@ get_arc_condition_code (rtx comparison)
        default : gcc_unreachable ();
        }
     case E_CC_FPUmode:
+    case E_CC_FPUEmode:
       switch (GET_CODE (comparison))
        {
        case EQ        : return ARC_CC_EQ;
@@ -1686,11 +1687,13 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
       case UNLE:
       case UNGT:
       case UNGE:
+       return CC_FPUmode;
+
       case LT:
       case LE:
       case GT:
       case GE:
-       return CC_FPUmode;
+       return CC_FPUEmode;
 
       case LTGT:
       case UNEQ:
@@ -1844,7 +1847,7 @@ arc_init_reg_tables (void)
          if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
              || i == (int) CC_Cmode
              || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
-             || i == CC_FPUmode || i == CC_FPU_UNEQmode)
+             || i == CC_FPUmode || i == CC_FPUEmode || i == CC_FPU_UNEQmode)
            arc_mode_class[i] = 1 << (int) C_MODE;
          else
            arc_mode_class[i] = 0;
@@ -8401,6 +8404,7 @@ arc_reorg (void)
 
          /* Avoid FPU instructions.  */
          if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
+             || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUEmode)
              || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
            continue;
 
index 4d7ac3281b417489f90128923038493735ffca3f..c08ca3d0d432ec793ddfba0bc0e5fc2ed994e45c 100644 (file)
@@ -1531,7 +1531,7 @@ enum arc_function_type {
   (((MODE) == CC_FP_GTmode || (MODE) == CC_FP_GEmode            \
     || (MODE) == CC_FP_UNEQmode || (MODE) == CC_FP_ORDmode      \
     || (MODE) == CC_FPXmode || (MODE) == CC_FPU_UNEQmode        \
-    || (MODE) == CC_FPUmode)                                    \
+    || (MODE) == CC_FPUmode || (MODE) == CC_FPUEmode)           \
    ? reverse_condition_maybe_unordered ((CODE))                         \
    : reverse_condition ((CODE)))
 
index 6289e9c3f593f7a240c8c581e250f30540a3a550..6729795de542bf720c6b2ae7d3883b462791d77b 100644 (file)
    (set_attr "type" "fpu")
    (set_attr "predicable" "yes")])
 
+(define_insn "*cmpsf_fpu_trap"
+  [(set (reg:CC_FPUE CC_REG)
+       (compare:CC_FPUE (match_operand:SF 0 "register_operand"  "r,  r,r")
+                       (match_operand:SF 1 "nonmemory_operand" "r,CfZ,F")))]
+  "TARGET_FP_SP_BASE"
+  "fscmpf%?\\t%0,%1"
+  [(set_attr "length" "4,4,8")
+   (set_attr "iscompact" "false")
+   (set_attr "cond" "set")
+   (set_attr "type" "fpu")
+   (set_attr "predicable" "yes")])
+
 (define_insn "*cmpsf_fpu_uneq"
   [(set (reg:CC_FPU_UNEQ CC_REG)
        (compare:CC_FPU_UNEQ
    (set_attr "type" "fpu")
    (set_attr "predicable" "yes")])
 
+(define_insn "*cmpdf_fpu_trap"
+  [(set (reg:CC_FPUE CC_REG)
+       (compare:CC_FPUE (match_operand:DF 0 "even_register_operand"  "r")
+                       (match_operand:DF 1 "even_register_operand"  "r")))]
+  "TARGET_FP_DP_BASE"
+  "fdcmpf%? %0, %1"
+  [(set_attr "length" "4")
+   (set_attr "iscompact" "false")
+   (set_attr "cond" "set")
+   (set_attr "type" "fpu")
+   (set_attr "predicable" "yes")])
+
 (define_insn "*cmpdf_fpu_uneq"
   [(set (reg:CC_FPU_UNEQ CC_REG)
        (compare:CC_FPU_UNEQ
index e0013b32f0f57e5d1a5ecada1bbec16d81c3904b..4d2ad7ba67896211d60fe0874cffbc78037c5500 100644 (file)
              || code == ORDERED || code == UNORDERED);
 
     case E_CC_FPUmode:
+    case E_CC_FPUEmode:
       return 1;
     case E_CC_FPU_UNEQmode:
       return 1;