Commit fbf8314b by Vineet Gupta Committed by Claudiu Zissulescu

[ARC] generate signaling FDCMPF for hard float comparisons

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
parent 48f13fb1
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> 2019-12-12 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc.md (iterator SDF): Check TARGET_FP_DP_BASE. * config/arc/arc.md (iterator SDF): Check TARGET_FP_DP_BASE.
...@@ -38,4 +38,5 @@ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ ...@@ -38,4 +38,5 @@ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
/* FPU condition flags. */ /* FPU condition flags. */
CC_MODE (CC_FPU); CC_MODE (CC_FPU);
CC_MODE (CC_FPUE);
CC_MODE (CC_FPU_UNEQ); CC_MODE (CC_FPU_UNEQ);
...@@ -1564,6 +1564,7 @@ get_arc_condition_code (rtx comparison) ...@@ -1564,6 +1564,7 @@ get_arc_condition_code (rtx comparison)
default : gcc_unreachable (); default : gcc_unreachable ();
} }
case E_CC_FPUmode: case E_CC_FPUmode:
case E_CC_FPUEmode:
switch (GET_CODE (comparison)) switch (GET_CODE (comparison))
{ {
case EQ : return ARC_CC_EQ; case EQ : return ARC_CC_EQ;
...@@ -1686,11 +1687,13 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y) ...@@ -1686,11 +1687,13 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
case UNLE: case UNLE:
case UNGT: case UNGT:
case UNGE: case UNGE:
return CC_FPUmode;
case LT: case LT:
case LE: case LE:
case GT: case GT:
case GE: case GE:
return CC_FPUmode; return CC_FPUEmode;
case LTGT: case LTGT:
case UNEQ: case UNEQ:
...@@ -1844,7 +1847,7 @@ arc_init_reg_tables (void) ...@@ -1844,7 +1847,7 @@ arc_init_reg_tables (void)
if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
|| i == (int) CC_Cmode || i == (int) CC_Cmode
|| i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode || 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; arc_mode_class[i] = 1 << (int) C_MODE;
else else
arc_mode_class[i] = 0; arc_mode_class[i] = 0;
...@@ -8401,6 +8404,7 @@ arc_reorg (void) ...@@ -8401,6 +8404,7 @@ arc_reorg (void)
/* Avoid FPU instructions. */ /* Avoid FPU instructions. */
if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode) 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)) || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
continue; continue;
......
...@@ -1531,7 +1531,7 @@ enum arc_function_type { ...@@ -1531,7 +1531,7 @@ enum arc_function_type {
(((MODE) == CC_FP_GTmode || (MODE) == CC_FP_GEmode \ (((MODE) == CC_FP_GTmode || (MODE) == CC_FP_GEmode \
|| (MODE) == CC_FP_UNEQmode || (MODE) == CC_FP_ORDmode \ || (MODE) == CC_FP_UNEQmode || (MODE) == CC_FP_ORDmode \
|| (MODE) == CC_FPXmode || (MODE) == CC_FPU_UNEQmode \ || (MODE) == CC_FPXmode || (MODE) == CC_FPU_UNEQmode \
|| (MODE) == CC_FPUmode) \ || (MODE) == CC_FPUmode || (MODE) == CC_FPUEmode) \
? reverse_condition_maybe_unordered ((CODE)) \ ? reverse_condition_maybe_unordered ((CODE)) \
: reverse_condition ((CODE))) : reverse_condition ((CODE)))
......
...@@ -242,6 +242,18 @@ ...@@ -242,6 +242,18 @@
(set_attr "type" "fpu") (set_attr "type" "fpu")
(set_attr "predicable" "yes")]) (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" (define_insn "*cmpsf_fpu_uneq"
[(set (reg:CC_FPU_UNEQ CC_REG) [(set (reg:CC_FPU_UNEQ CC_REG)
(compare:CC_FPU_UNEQ (compare:CC_FPU_UNEQ
...@@ -338,6 +350,18 @@ ...@@ -338,6 +350,18 @@
(set_attr "type" "fpu") (set_attr "type" "fpu")
(set_attr "predicable" "yes")]) (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" (define_insn "*cmpdf_fpu_uneq"
[(set (reg:CC_FPU_UNEQ CC_REG) [(set (reg:CC_FPU_UNEQ CC_REG)
(compare:CC_FPU_UNEQ (compare:CC_FPU_UNEQ
......
...@@ -439,6 +439,7 @@ ...@@ -439,6 +439,7 @@
|| code == ORDERED || code == UNORDERED); || code == ORDERED || code == UNORDERED);
case E_CC_FPUmode: case E_CC_FPUmode:
case E_CC_FPUEmode:
return 1; return 1;
case E_CC_FPU_UNEQmode: case E_CC_FPU_UNEQmode:
return 1; return 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment