Hi, Gentle ping this: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/587253.html
Thanks On 10/1/2022 上午 11:14, HAO CHEN GUI wrote: > Hi, > > Gentle ping this: > > https://gcc.gnu.org/pipermail/gcc-patches/2021-December/587253.html > > Thanks > > On 21/12/2021 下午 4:19, HAO CHEN GUI wrote: >> Hi, >> This patch fixes the ICE in PR100736. It adds a reverse condition >> comparison when the >> condition code can be reversed and finite-math-only is set. >> >> Bootstrapped and tested on powerpc64-linux BE and LE with no regressions. >> Is this okay for trunk? >> Any recommendations? Thanks a lot. >> >> ChangeLog >> 2021-12-20 Haochen Gui <guih...@linux.ibm.com> >> >> gcc/ >> * config/rs6000/altivec.md (bcd<bcd_add_sub>_test_<mode>): Named. >> (bcd<bcd_add_sub>_<code>_<mode>): Reverse compare condition if >> finite-math-only is set. >> * config/rs6000/rs6000-protos.c (rs6000_reverse_compare): Defined. >> * config/rs6000/rs6000.c (rs6000_emit_sCOND): Refactored. Call >> rs6000_reverse_compare if the condition code can be reversed. >> (rs6000_reverse_compare): Implemented. >> >> gcc/testsuite/ >> * gcc.target/powerpc/pr100736.h: New. >> * gcc.target/powerpc/pr100736.finite.c: New. >> * gcc.target/powerpc/pr100736.infinite.c: New. >> >> >> patch.diff >> diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md >> index ef432112333..cc40edc5381 100644 >> --- a/gcc/config/rs6000/altivec.md >> +++ b/gcc/config/rs6000/altivec.md >> @@ -4412,7 +4412,7 @@ (define_insn "bcd<bcd_add_sub>_<mode>" >> ;; UNORDERED test on an integer type (like V1TImode) is not defined. The >> type >> ;; probably should be one that can go in the VMX (Altivec) registers, so we >> ;; can't use DDmode or DFmode. >> -(define_insn "*bcd<bcd_add_sub>_test_<mode>" >> +(define_insn "bcd<bcd_add_sub>_test_<mode>" >> [(set (reg:CCFP CR6_REGNO) >> (compare:CCFP >> (unspec:V2DF [(match_operand:VBCD 1 "register_operand" "v") >> @@ -4539,6 +4539,18 @@ (define_expand "bcd<bcd_add_sub>_<code>_<mode>" >> "TARGET_P8_VECTOR" >> { >> operands[4] = CONST0_RTX (V2DFmode); >> + emit_insn (gen_bcd<bcd_add_sub>_test_<mode> (operands[0], operands[1], >> + operands[2], operands[3], >> + operands[4])); >> + rtx cr6 = gen_rtx_REG (CCFPmode, CR6_REGNO); >> + rtx condition_rtx = gen_rtx_<CODE> (SImode, cr6, const0_rtx); >> + if (flag_finite_math_only) >> + { >> + condition_rtx = rs6000_reverse_compare (condition_rtx); >> + PUT_MODE (condition_rtx, SImode); >> + } >> + emit_insn (gen_rtx_SET (operands[0], condition_rtx)); >> + DONE; >> }) >> >> (define_insn "*bcdinvalid_<mode>" >> diff --git a/gcc/config/rs6000/rs6000-protos.h >> b/gcc/config/rs6000/rs6000-protos.h >> index 14f6b313105..9b93e26bec2 100644 >> --- a/gcc/config/rs6000/rs6000-protos.h >> +++ b/gcc/config/rs6000/rs6000-protos.h >> @@ -114,6 +114,7 @@ extern enum rtx_code rs6000_reverse_condition >> (machine_mode, >> 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[]); >> +extern rtx rs6000_reverse_compare (rtx); >> extern void rs6000_emit_cbranch (machine_mode, rtx[]); >> extern char * output_cbranch (rtx, const char *, int, rtx_insn *); >> extern const char * output_probe_stack_range (rtx, rtx, rtx); >> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c >> index 5e129986516..2f3dd311396 100644 >> --- a/gcc/config/rs6000/rs6000.c >> +++ b/gcc/config/rs6000/rs6000.c >> @@ -15653,19 +15653,14 @@ rs6000_emit_fp_cror (rtx_code code, machine_mode >> mode, rtx x) >> return cc; >> } >> >> -void >> -rs6000_emit_sCOND (machine_mode mode, rtx operands[]) >> +rtx >> +rs6000_reverse_compare (rtx condition_rtx) >> { >> - rtx condition_rtx = rs6000_generate_compare (operands[1], mode); >> rtx_code cond_code = GET_CODE (condition_rtx); >> - >> - if (FLOAT_MODE_P (mode) && HONOR_NANS (mode) >> - && !(FLOAT128_VECTOR_P (mode) && !TARGET_FLOAT128_HW)) >> - ; >> - else if (cond_code == NE >> - || cond_code == GE || cond_code == LE >> - || cond_code == GEU || cond_code == LEU >> - || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE) >> + if (cond_code == NE >> + || cond_code == GE || cond_code == LE >> + || cond_code == GEU || cond_code == LEU >> + || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE) >> { >> rtx not_result = gen_reg_rtx (CCEQmode); >> rtx not_op, rev_cond_rtx; >> @@ -15679,6 +15674,19 @@ rs6000_emit_sCOND (machine_mode mode, rtx >> operands[]) >> emit_insn (gen_rtx_SET (not_result, not_op)); >> condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx); >> } >> + return condition_rtx; >> +} >> + >> +void >> +rs6000_emit_sCOND (machine_mode mode, rtx operands[]) >> +{ >> + rtx condition_rtx = rs6000_generate_compare (operands[1], mode); >> + >> + if (FLOAT_MODE_P (mode) && HONOR_NANS (mode) >> + && !(FLOAT128_VECTOR_P (mode) && !TARGET_FLOAT128_HW)) >> + ; >> + else >> + condition_rtx = rs6000_reverse_compare (condition_rtx); >> >> machine_mode op_mode = GET_MODE (XEXP (operands[1], 0)); >> if (op_mode == VOIDmode) >> diff --git a/gcc/testsuite/gcc.target/powerpc/pr100736.finite.c >> b/gcc/testsuite/gcc.target/powerpc/pr100736.finite.c >> new file mode 100644 >> index 00000000000..43c85d4a2c1 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/powerpc/pr100736.finite.c >> @@ -0,0 +1,8 @@ >> +/* { dg-do compile { target lp64 } } */ >> +/* { dg-require-effective-target powerpc_p8vector_ok } */ >> +/* { dg-options "-mdejagnu-cpu=power8 -O2 -ffinite-math-only" } */ >> + >> +/* Source code for the test in pr100736.h */ >> +#include "pr100736.h" >> + >> +/* { dg-final { scan-assembler {\mcrnot\M} } } */ >> diff --git a/gcc/testsuite/gcc.target/powerpc/pr100736.h >> b/gcc/testsuite/gcc.target/powerpc/pr100736.h >> new file mode 100644 >> index 00000000000..b1b3dc08247 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/powerpc/pr100736.h >> @@ -0,0 +1,12 @@ >> +/* This test code is included into pr100736.infinite.c and pr100736.finite.c >> + The two files have the tests for finite-math-only set and not set. >> + >> + finite-math-only: bcdsub.;crnot;mfcr;rlwinm. >> + not set: bcdsub.;cror;mfcr;rlwinm. */ >> + >> +typedef __attribute__ ((altivec (vector__))) unsigned char v; >> + >> +int foo (v a, v b) >> +{ >> + return __builtin_vec_bcdsub_ge (a, b, 0); >> +} >> diff --git a/gcc/testsuite/gcc.target/powerpc/pr100736.infinite.c >> b/gcc/testsuite/gcc.target/powerpc/pr100736.infinite.c >> new file mode 100644 >> index 00000000000..881f18794f5 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/powerpc/pr100736.infinite.c >> @@ -0,0 +1,8 @@ >> +/* { dg-do compile { target lp64 } } */ >> +/* { dg-require-effective-target powerpc_p8vector_ok } */ >> +/* { dg-options "-mdejagnu-cpu=power8 -O2" } */ >> + >> +/* Source code for the test in pr100736.h */ >> +#include "pr100736.h" >> + >> +/* { dg-final { scan-assembler {\mcror\M} } } */