https://gcc.gnu.org/g:e4e4ad7fffd4837e6bd0d5773fbbe9ac0451aef6
commit e4e4ad7fffd4837e6bd0d5773fbbe9ac0451aef6 Author: Michael Meissner <meiss...@linux.ibm.com> Date: Wed Jul 30 00:11:13 2025 -0400 Revert changes Diff: --- gcc/config/rs6000/predicates.md | 11 +- gcc/config/rs6000/rs6000-protos.h | 24 +--- gcc/config/rs6000/rs6000.cc | 37 ++---- gcc/config/rs6000/rs6000.h | 10 +- gcc/config/rs6000/rs6000.md | 158 ++++++++++++++------------ gcc/testsuite/gcc.target/powerpc/pr118541-1.c | 28 ----- gcc/testsuite/gcc.target/powerpc/pr118541-2.c | 26 ----- 7 files changed, 107 insertions(+), 187 deletions(-) diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 7087b69080d8..647e89afb6a7 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1460,11 +1460,14 @@ ;; Return 1 if OP is a comparison operator suitable for floating point ;; vector/scalar comparisons that generate a -1/0 mask. -;; -;; Do not match UNEQ, UNLT, UNLE, UNGT, or UNGE since the fpmask -;; instructions can trap on signaling NaNs. (define_predicate "fpmask_comparison_operator" - (match_code "eq,ne,gt,ge,lt,le")) + (match_code "eq,gt,ge")) + +;; Return 1 if OP is a comparison operator suitable for vector/scalar +;; comparisons that generate a 0/-1 mask (i.e. the inverse of +;; fpmask_comparison_operator). +(define_predicate "invert_fpmask_comparison_operator" + (match_code "ne,unlt,unle")) ;; Return 1 if OP is a comparison operation suitable for integer vector/scalar ;; comparisons that generate a -1/0 mask. diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 2eea755285fe..4619142d197b 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -114,30 +114,8 @@ extern const char *rs6000_sibcall_template (rtx *, unsigned int); extern const char *rs6000_indirect_call_template (rtx *, unsigned int); extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int); extern const char *rs6000_pltseq_template (rtx *, int); - -/* Whether we can reverse the sense of a floating point comparison. - - If the comparison involves UNEQ, LTGT, UNGT, UNGE, UNLT, and UNLE - comparisons we cannot generate instructions that could generate a trap with - a signaling NaN. These comprisons are created using the floating point - relational tests (like isgreater, isless, etc.), and these comparisons must - not trap on any value like a signaling NaN. The fpmask instructions - (XSCMPEQDP, XSCMPGTQP, etc.) that do the comparison and produce 1's or 0's - to allow the XXSEL instruction to do a conditional move. - - However, if we are not generating fpmask instructions, we have to allow - doing the reversals. We need this reversal to handle conditional jumps that - are too far away to jump to directly and we have to reverse the jump, so we - can generate a jump around an unconditional jump. */ - -enum class cond_reverse_fp { - reverse_ok, - no_reverse -}; - extern enum rtx_code rs6000_reverse_condition (machine_mode, - enum rtx_code, - enum cond_reverse_fp); + enum rtx_code); extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); extern rtx rs6000_emit_fp_cror (rtx_code, machine_mode, rtx); extern void rs6000_emit_sCOND (machine_mode, rtx[]); diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 652b76af8e67..f4f0ad80e35e 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -15282,27 +15282,17 @@ rs6000_print_patchable_function_entry (FILE *file, } enum rtx_code -rs6000_reverse_condition (machine_mode mode, - enum rtx_code code, - enum cond_reverse_fp do_fp_reverse) +rs6000_reverse_condition (machine_mode mode, enum rtx_code code) { - /* Do not allow reversing comparisons if this is an IEEE comparison - (i.e. isgreater, etc.) that must not trap. - - We do allow the comparsion to be reversed for explicit jumps when - cond_reverse_fp::reverse_ok is passed. */ + /* Reversal of FP compares takes care -- an ordered compare + becomes an unordered compare and vice versa. */ if (mode == CCFPmode - && (code == UNLT || code == UNLE || code == UNGT || code == UNGE + && (!flag_finite_math_only + || code == UNLT || code == UNLE || code == UNGT || code == UNGE || code == UNEQ || code == LTGT)) - { - if (!flag_finite_math_only - && do_fp_reverse == cond_reverse_fp::no_reverse) - return UNKNOWN; - - return reverse_condition_maybe_unordered (code); - } - - return reverse_condition (code); + return reverse_condition_maybe_unordered (code); + else + return reverse_condition (code); } /* Check if C (as 64bit integer) can be rotated to a constant which constains @@ -15910,17 +15900,14 @@ rs6000_emit_sCOND (machine_mode mode, rtx operands[]) || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE) { rtx not_result = gen_reg_rtx (CCEQmode); - rtx not_op, rev_cmp_rtx; + rtx not_op, rev_cond_rtx; machine_mode cc_mode; - rtx_code rev; cc_mode = GET_MODE (XEXP (condition_rtx, 0)); - rev = rs6000_reverse_condition (cc_mode, cond_code, - cond_reverse_fp::no_reverse); - rev_cmp_rtx = gen_rtx_fmt_ee (rev, SImode, XEXP (condition_rtx, 0), - const0_rtx); - not_op = gen_rtx_COMPARE (CCEQmode, rev_cmp_rtx, const0_rtx); + rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code), + SImode, XEXP (condition_rtx, 0), const0_rtx); + not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx); emit_insn (gen_rtx_SET (not_result, not_op)); condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx); } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 52b2f7bcb95f..cffe2750ba9a 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1804,17 +1804,11 @@ extern scalar_int_mode rs6000_pmode; /* Can the condition code MODE be safely reversed? This is safe in all cases on this port, because at present it doesn't use the - trapping FP comparisons (fcmpo). - - However, this is not safe for IEEE comparisons (i.e. isgreater, etc.) - starting with the power9 because ifcvt.cc will want to create a fp cmove, - and the x{s,v}cmp{eq,gt,ge}{dp,qp} instructions will trap if one of the - arguments is a signalling NaN. */ + trapping FP comparisons (fcmpo). */ #define REVERSIBLE_CC_MODE(MODE) 1 /* Given a condition code and a mode, return the inverse condition. */ -#define REVERSE_CONDITION(CODE, MODE) \ - rs6000_reverse_condition (MODE, CODE, cond_reverse_fp::no_reverse) +#define REVERSE_CONDITION(CODE, MODE) rs6000_reverse_condition (MODE, CODE) /* Target cpu costs. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index eeb377d426ae..5a56ad79a9ee 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -5761,7 +5761,7 @@ "#" "&& 1" [(set (match_dup 6) - (if_then_else:V2DI (match_dup 9) + (if_then_else:V2DI (match_dup 1) (match_dup 7) (match_dup 8))) (set (match_dup 0) @@ -5770,20 +5770,48 @@ (match_dup 4) (match_dup 5)))] { - /* Fix NE to swap true/false values. */ - if (GET_CODE (operands[1]) != NE) - operands[9] = operands[1]; - else - { - operands[9] = gen_rtx_fmt_ee (EQ, CCFPmode, operands[2], operands[3]); - std::swap (operands[4], operands[5]); - } + if (GET_CODE (operands[6]) == SCRATCH) + operands[6] = gen_reg_rtx (V2DImode); + + operands[7] = CONSTM1_RTX (V2DImode); + operands[8] = CONST0_RTX (V2DImode); +} + [(set_attr "length" "8") + (set_attr "type" "vecperm")]) + +;; Handle inverting the fpmask comparisons. +(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9" + [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa") + (if_then_else:SFDF + (match_operator:CCFP 1 "invert_fpmask_comparison_operator" + [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa") + (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")]) + (match_operand:SFDF 4 "vsx_register_operand" "wa,wa") + (match_operand:SFDF 5 "vsx_register_operand" "wa,wa"))) + (clobber (match_scratch:V2DI 6 "=0,&wa"))] + "TARGET_P9_MINMAX" + "#" + "&& 1" + [(set (match_dup 6) + (if_then_else:V2DI (match_dup 9) + (match_dup 7) + (match_dup 8))) + (set (match_dup 0) + (if_then_else:SFDF (ne (match_dup 6) + (match_dup 8)) + (match_dup 5) + (match_dup 4)))] +{ + rtx op1 = operands[1]; + enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); if (GET_CODE (operands[6]) == SCRATCH) operands[6] = gen_reg_rtx (V2DImode); operands[7] = CONSTM1_RTX (V2DImode); operands[8] = CONST0_RTX (V2DImode); + + operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); } [(set_attr "length" "8") (set_attr "type" "vecperm")]) @@ -5797,26 +5825,7 @@ (match_operand:V2DI 4 "all_ones_constant" "") (match_operand:V2DI 5 "zero_constant" "")))] "TARGET_P9_MINMAX" -{ - /* Note, NE should not show up due to the previous define_insn_and_split - converting it into EQ.. */ - switch (GET_CODE (operands[1])) - { - case EQ: - case GT: - case GE: - return "xscmp%V1dp %x0,%x2,%x3"; - - case LT: - return "xscmpgedp %x0,%x3,%x2"; - - case LE: - return "xscmpgtdp %x0,%x3,%x2"; - - default: - gcc_unreachable (); - } -} + "xscmp%V1dp %x0,%x2,%x3" [(set_attr "type" "fpcompare")]) (define_insn "*xxsel<mode>" @@ -5857,7 +5866,7 @@ "#" "&& 1" [(set (match_dup 6) - (if_then_else:V2DI (match_dup 9) + (if_then_else:V2DI (match_dup 1) (match_dup 7) (match_dup 8))) (set (match_dup 0) @@ -5866,20 +5875,48 @@ (match_dup 4) (match_dup 5)))] { - /* Fix NE to swap true/false values. */ - if (GET_CODE (operands[1]) != NE) - operands[9] = operands[1]; - else - { - operands[9] = gen_rtx_fmt_ee (EQ, CCFPmode, operands[2], operands[3]); - std::swap (operands[4], operands[5]); - } + if (GET_CODE (operands[6]) == SCRATCH) + operands[6] = gen_reg_rtx (V2DImode); + + operands[7] = CONSTM1_RTX (V2DImode); + operands[8] = CONST0_RTX (V2DImode); +} + [(set_attr "length" "8") + (set_attr "type" "vecperm")]) + +;; Handle inverting the fpmask comparisons. +(define_insn_and_split "*mov<mode>cc_invert_p10" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v") + (if_then_else:IEEE128 + (match_operator:CCFP 1 "invert_fpmask_comparison_operator" + [(match_operand:IEEE128 2 "altivec_register_operand" "v,v") + (match_operand:IEEE128 3 "altivec_register_operand" "v,v")]) + (match_operand:IEEE128 4 "altivec_register_operand" "v,v") + (match_operand:IEEE128 5 "altivec_register_operand" "v,v"))) + (clobber (match_scratch:V2DI 6 "=0,&v"))] + "TARGET_POWER10 && TARGET_FLOAT128_HW" + "#" + "&& 1" + [(set (match_dup 6) + (if_then_else:V2DI (match_dup 9) + (match_dup 7) + (match_dup 8))) + (set (match_dup 0) + (if_then_else:IEEE128 (ne (match_dup 6) + (match_dup 8)) + (match_dup 5) + (match_dup 4)))] +{ + rtx op1 = operands[1]; + enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); if (GET_CODE (operands[6]) == SCRATCH) operands[6] = gen_reg_rtx (V2DImode); operands[7] = CONSTM1_RTX (V2DImode); operands[8] = CONST0_RTX (V2DImode); + + operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); } [(set_attr "length" "8") (set_attr "type" "vecperm")]) @@ -5893,26 +5930,7 @@ (match_operand:V2DI 4 "all_ones_constant" "") (match_operand:V2DI 5 "zero_constant" "")))] "TARGET_POWER10 && TARGET_FLOAT128_HW" -{ - /* Note, NE should not show up due to the previous define_insn_and_split - converting it into EQ.. */ - switch (GET_CODE (operands[1])) - { - case EQ: - case GT: - case GE: - return "xscmp%V1qp %0,%2,%3"; - - case LT: - return "xscmpgeqp %0,%3,%2"; - - case LE: - return "xscmpgtqp %0,%3,%2"; - - default: - gcc_unreachable (); - } -} + "xscmp%V1qp %0,%2,%3" [(set_attr "type" "fpcompare")]) (define_insn "*xxsel<mode>" @@ -13528,7 +13546,7 @@ ;; If we are comparing the result of two comparisons, this can be done ;; using creqv or crxor. -(define_insn_and_split "*reverse_branch_comparison" +(define_insn_and_split "" [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") (compare:CCEQ (match_operator 1 "branch_comparison_operator" [(match_operand 2 "cc_reg_operand" "y") @@ -13550,25 +13568,19 @@ GET_MODE (operands[3])); if (! positive_1) - { - rtx_code rev = rs6000_reverse_condition (GET_MODE (operands[2]), - GET_CODE (operands[1]), - cond_reverse_fp::reverse_ok); - gcc_assert (rev != UNKNOWN); - operands[1] = gen_rtx_fmt_ee (rev, SImode, operands[2], const0_rtx); - } + operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), + GET_CODE (operands[1])), + SImode, + operands[2], const0_rtx); else if (GET_MODE (operands[1]) != SImode) operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, operands[2], const0_rtx); if (! positive_2) - { - rtx_code rev = rs6000_reverse_condition (GET_MODE (operands[4]), - GET_CODE (operands[3]), - cond_reverse_fp::reverse_ok); - gcc_assert (rev != UNKNOWN); - operands[3] = gen_rtx_fmt_ee (rev, SImode, operands[4], const0_rtx); - } + operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), + GET_CODE (operands[3])), + SImode, + operands[4], const0_rtx); else if (GET_MODE (operands[3]) != SImode) operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, operands[4], const0_rtx); diff --git a/gcc/testsuite/gcc.target/powerpc/pr118541-1.c b/gcc/testsuite/gcc.target/powerpc/pr118541-1.c deleted file mode 100644 index 30901cd1e41d..000000000000 --- a/gcc/testsuite/gcc.target/powerpc/pr118541-1.c +++ /dev/null @@ -1,28 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mdejagnu-cpu=power9 -O2" } */ -/* { dg-require-effective-target powerpc_vsx } */ - -/* PR target/118541 says that the IEEE comparison functions like isgreater - should not optimize floating point conditional moves to use - x{s,v}cmp{eq,gt,ge}{dp,qp} and xxsel since that instruction can cause traps - if one of the arguments is a signaling NaN. */ - -/* Verify isgreater does not generate xscmpgtdp when NaNs are allowed. */ - -double -ieee_compare (double a, double b, double c, double d) -{ - /* - * fcmpu 0,1,2 - * fmr 1,4 - * bnglr 0 - * fmr 1,3 - * blr - */ - - return __builtin_isgreater (a, b) ? c : d; -} - -/* { dg-final { scan-assembler-not {\mxscmpg[te]dp\M} } } */ -/* { dg-final { scan-assembler-not {\mxxsel\M} } } */ -/* { dg-final { scan-assembler {\mxscmpudp\M|\mfcmpu\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr118541-2.c b/gcc/testsuite/gcc.target/powerpc/pr118541-2.c deleted file mode 100644 index 1f36890b775f..000000000000 --- a/gcc/testsuite/gcc.target/powerpc/pr118541-2.c +++ /dev/null @@ -1,26 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mdejagnu-cpu=power9 -O2" } */ -/* { dg-require-effective-target powerpc_vsx } */ - -/* PR target/118541 says that the IEEE comparison functions like isgreater - should not optimize floating point conditional moves to use - x{s,v}cmp{eq,gt,ge}{dp,qp} and xxsel since that instruction can cause traps - if one of the arguments is a signaling NaN. */ - -/* Verify normal > does generate xscmpgtdp when NaNs are allowed. */ - -double -normal_compare (double a, double b, double c, double d) -{ - /* - * xscmpgtdp 1,1,2 - * xxsel 1,4,3,1 - * blr - */ - - return a > b ? c : d; -} - -/* { dg-final { scan-assembler {\mxscmpg[te]dp\M} } } */ -/* { dg-final { scan-assembler {\mxxsel\M} } } */ -/* { dg-final { scan-assembler-not {\mxscmpudp\M|\mfcmpu\M} } } */