The C comparison operators <, >, <=, >= (as opposed to the isgreater, etc. macros) are specified to raise the invalid exception on comparisons involving a NaN (quiet or signaling). However, gcc on s390 is generating e.g. the cebr (Short BFP COMPARE) instruction rather than kebr (Short BFP COMPARE AND SIGNAL). The first one does not raise the invalid exception unless it encounters a signaling NaN. The latter one raise the invalid exception if one operand is quiet or signaling NaN. I haven't checked if invalid is raised if gcc is using vector instructions.
Created attachment 39781 [details] another test-case Following simplified test-case ICEs on 5.1.0+: $ g++ pr77919-2.cpp -c -O1 -std=c++11 -fpermissive: 0xa1274b copy_to_mode_reg(machine_mode, rtx_def*) /home/marxin/BIG/Programming/gcc/gcc/explow.c:601 0x915d63 precompute_register_parameters /home/marxin/BIG/Programming/gcc/gcc/calls.c:921 0x915d63 expand_call(tree_node*, rtx_def*, int) /home/marxin/BIG/Programming/gcc/gcc/calls.c:3120 0xa28c4c expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) /home/marxin/BIG/Programming/gcc/gcc/expr.c:10594 0x92918a expand_expr /home/marxin/BIG/Programming/gcc/gcc/expr.h:256 0x92918a expand_call_stmt /home/marxin/BIG/Programming/gcc/gcc/cfgexpand.c:2660 0x92918a expand_gimple_stmt_1 /home/marxin/BIG/Programming/gcc/gcc/cfgexpand.c:3548 0x92918a expand_gimple_stmt /home/marxin/BIG/Programming/gcc/gcc/cfgexpand.c:3714 0x92a87e expand_gimple_basic_block /home/marxin/BIG/Programming/gcc/gcc/cfgexpand.c:5720 0x9309b6 execute /home/marxin/BIG/Programming/gcc/gcc/cfgexpand.c:6335
Comment on attachment 39781 [details] another test-case Sorry, wrong PR.
Author: iii Date: Mon Sep 30 17:40:02 2019 New Revision: 276360 URL: https://gcc.gnu.org/viewcvs?rev=276360&root=gcc&view=rev Log: S/390: Remove code duplication in vec_unordered<mode> vec_unordered<mode> is vec_ordered<mode> plus a negation at the end. Reuse vec_unordered<mode> logic. gcc/ChangeLog: 2019-09-30 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * config/s390/vector.md (vec_unordered<mode>): Call gen_vec_ordered<mode>. Modified: trunk/gcc/ChangeLog trunk/gcc/config/s390/vector.md
Author: iii Date: Tue Oct 1 14:03:08 2019 New Revision: 276408 URL: https://gcc.gnu.org/viewcvs?rev=276408&root=gcc&view=rev Log: S/390: Implement vcond expander for V1TI,V1TF Currently gcc does not emit wf{c,k}* instructions when comparing long double values. Middle-end actually adds them in the first place, but then veclower pass replaces them with floating point register pair operations, because the corresponding expander is missing. gcc/ChangeLog: 2019-10-01 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * config/s390/vector.md (V_HW): Add V1TI in order to make vcond$a$b generate vcondv1tiv1tf. Modified: trunk/gcc/ChangeLog trunk/gcc/config/s390/vector.md
Author: iii Date: Tue Oct 1 14:04:08 2019 New Revision: 276409 URL: https://gcc.gnu.org/viewcvs?rev=276409&root=gcc&view=rev Log: S/390: Remove code duplication in vec_* comparison expanders s390.md uses a lot of near-identical expanders that perform dispatching to other expanders based on operand types. Since the following patch would require even more of these, avoid copy-pasting the code by generating these expanders using an iterator. gcc/ChangeLog: 2019-10-01 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * config/s390/s390.c (s390_expand_vec_compare): Use gen_vec_cmpordered and gen_vec_cmpunordered. * config/s390/vector.md (vec_cmpuneq, vec_cmpltgt, vec_ordered, vec_unordered): Delete. (vec_ordered<mode>): Rename to vec_cmpordered<mode>. (vec_unordered<mode>): Rename to vec_cmpunordered<mode>. (VEC_CMP_EXPAND): New iterator for the generic dispatcher. (vec_cmp<code>): Generic dispatcher. Modified: trunk/gcc/ChangeLog trunk/gcc/config/s390/s390.c trunk/gcc/config/s390/vector.md
Author: iii Date: Mon Oct 7 14:59:00 2019 New Revision: 276659 URL: https://gcc.gnu.org/viewcvs?rev=276659&root=gcc&view=rev Log: Allow COND_EXPR and VEC_COND_EXPR condtions to trap Right now gimplifier does not allow VEC_COND_EXPR's condition to trap and introduces a temporary if this could happen, for example, generating _5 = _4 > { 2.0e+0, 2.0e+0, 2.0e+0, 2.0e+0 }; _6 = VEC_COND_EXPR <_5, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; from GENERIC VEC_COND_EXPR < (*b > { 2.0e+0, 2.0e+0, 2.0e+0, 2.0e+0 }) , { -1, -1, -1, -1 } , { 0, 0, 0, 0 } > This is not necessary and makes the resulting GIMPLE harder to analyze. Change the gimplifier so as to allow COND_EXPR and VEC_COND_EXPR conditions to trap. This patch takes special care to avoid introducing trapping comparisons in GIMPLE_COND. They are not allowed, because they would require 3 outgoing edges (then, else and EH), which is awkward to say the least. Therefore, computations of such conditions should live in their own basic blocks. gcc/ChangeLog: 2019-10-07 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * gimple-expr.c (gimple_cond_get_ops_from_tree): Assert that the caller passes a non-trapping condition. (is_gimple_condexpr): Allow trapping conditions. (is_gimple_condexpr_1): New helper function. (is_gimple_condexpr_for_cond): New function, acts like old is_gimple_condexpr. * gimple-expr.h (is_gimple_condexpr_for_cond): New function. * gimple.c (gimple_could_trap_p_1): Handle COND_EXPR and VEC_COND_EXPR. Fix an issue with statements like i = (fp < 1.). * gimplify.c (gimplify_cond_expr): Use is_gimple_condexpr_for_cond. (gimplify_expr): Allow is_gimple_condexpr_for_cond. * tree-eh.c (operation_could_trap_p): Assert on COND_EXPR and VEC_COND_EXPR. (tree_could_trap_p): Handle COND_EXPR and VEC_COND_EXPR. * tree-ssa-forwprop.c (forward_propagate_into_gimple_cond): Use is_gimple_condexpr_for_cond, remove pointless tmp check (forward_propagate_into_cond): Remove pointless tmp check. Modified: trunk/gcc/ChangeLog trunk/gcc/gimple-expr.c trunk/gcc/gimple-expr.h trunk/gcc/gimple.c trunk/gcc/gimplify.c trunk/gcc/tree-eh.c trunk/gcc/tree-ssa-forwprop.c
Author: iii Date: Mon Oct 7 15:01:15 2019 New Revision: 276660 URL: https://gcc.gnu.org/viewcvs?rev=276660&root=gcc&view=rev Log: Introduce can_vcond_compare_p function z13 supports only non-signaling vector comparisons. This means we cannot vectorize LT, LE, GT, GE and LTGT when compiling for z13. However, we cannot express this restriction today: the code only checks whether vcond$a$b optab exists, but this does not say anything about the operation. Introduce a function that checks whether back-end supports vector comparisons with individual rtx codes by matching vcond expander's third argument with a fake comparison with the corresponding rtx code. gcc/ChangeLog: 2019-10-07 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * optabs-tree.c (vcond_icode_p): New function. (vcond_eq_icode_p): Likewise. (expand_vec_cond_expr_p): Use vcond_icode_p and vcond_eq_icode_p. * optabs.c (can_vcond_compare_p): New function. * optabs.h (can_vcond_compare_p): Likewise. Modified: trunk/gcc/ChangeLog trunk/gcc/optabs-tree.c trunk/gcc/optabs.c trunk/gcc/optabs.h
Author: iii Date: Thu Oct 10 17:00:29 2019 New Revision: 276842 URL: https://gcc.gnu.org/viewcvs?rev=276842&root=gcc&view=rev Log: [PATCH 1/3] S/390: Do not use signaling vector comparisons on z13 z13 supports only non-signaling vector comparisons. This means we cannot vectorize LT, LE, GT, GE and LTGT when compiling for z13. Notify middle-end about this by using more restrictive operator predicate in vcond<V_HW:mode><V_HW2:mode>. gcc/ChangeLog: 2019-10-10 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * config/s390/vector.md (vcond_comparison_operator): New predicate. (vcond<V_HW:mode><V_HW2:mode>): Use vcond_comparison_operator. Modified: trunk/gcc/ChangeLog trunk/gcc/config/s390/vector.md
Author: iii Date: Fri Oct 11 09:00:26 2019 New Revision: 276871 URL: https://gcc.gnu.org/viewcvs?rev=276871&root=gcc&view=rev Log: S/390: Use signaling FP comparison instructions dg-torture.exp=inf-compare-1.c is failing, because (qNaN > +Inf) comparison is compiled to CDB instruction, which does not signal an invalid operation exception. KDB should have been used instead. This patch introduces a new CCmode and a new pattern in order to generate signaling instructions in this and similar cases. gcc/ChangeLog: 2019-10-11 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * config/s390/2827.md: Add new opcodes. * config/s390/2964.md: Likewise. * config/s390/3906.md: Likewise. * config/s390/8561.md: Likewise. * config/s390/s390-builtins.def (s390_vfchesb): Use the new vec_cmpgev4sf_quiet_nocc. (s390_vfchedb): Use the new vec_cmpgev2df_quiet_nocc. (s390_vfchsb): Use the new vec_cmpgtv4sf_quiet_nocc. (s390_vfchdb): Use the new vec_cmpgtv2df_quiet_nocc. (vec_cmplev4sf): Use the new vec_cmplev4sf_quiet_nocc. (vec_cmplev2df): Use the new vec_cmplev2df_quiet_nocc. (vec_cmpltv4sf): Use the new vec_cmpltv4sf_quiet_nocc. (vec_cmpltv2df): Use the new vec_cmpltv2df_quiet_nocc. * config/s390/s390-modes.def (CCSFPS): New mode. * config/s390/s390.c (s390_match_ccmode_set): Support CCSFPS. (s390_select_ccmode): Return CCSFPS for LT, LE, GT, GE and LTGT. (s390_branch_condition_mask): Reuse CCS for CCSFPS. (s390_expand_vec_compare): Use non-signaling patterns where necessary. (s390_reverse_condition): Support CCSFPS. * config/s390/s390.md (*cmp<mode>_ccsfps): New pattern. * config/s390/vector.md: (VFCMP_HW_OP): Remove. (asm_fcmp_op): Likewise. (*smaxv2df3_vx): Use pattern for quiet comparison. (*sminv2df3_vx): Likewise. (*vec_cmp<VFCMP_HW_OP:code><mode>_nocc): Remove. (*vec_cmpeq<mode>_quiet_nocc): New pattern. (vec_cmpgt<mode>_quiet_nocc): Likewise. (vec_cmplt<mode>_quiet_nocc): New expander. (vec_cmpge<mode>_quiet_nocc): New pattern. (vec_cmple<mode>_quiet_nocc): New expander. (*vec_cmpeq<mode>_signaling_nocc): New pattern. (*vec_cmpgt<mode>_signaling_nocc): Likewise. (*vec_cmpgt<mode>_signaling_finite_nocc): Likewise. (*vec_cmpge<mode>_signaling_nocc): Likewise. (*vec_cmpge<mode>_signaling_finite_nocc): Likewise. (vec_cmpungt<mode>): New expander. (vec_cmpunge<mode>): Likewise. (vec_cmpuneq<mode>): Use quiet patterns. (vec_cmpltgt<mode>): Allow only on z14+. (vec_cmpordered<mode>): Use quiet patterns. (vec_cmpunordered<mode>): Likewise. (VEC_CMP_EXPAND): Add ungt and unge. gcc/testsuite/ChangeLog: 2019-10-11 Ilya Leoshkevich <iii@linux.ibm.com> * gcc.target/s390/vector/vec-scalar-cmp-1.c: Adjust expectations. Modified: trunk/gcc/ChangeLog trunk/gcc/config/s390/2827.md trunk/gcc/config/s390/2964.md trunk/gcc/config/s390/3906.md trunk/gcc/config/s390/8561.md trunk/gcc/config/s390/s390-builtins.def trunk/gcc/config/s390/s390-modes.def trunk/gcc/config/s390/s390.c trunk/gcc/config/s390/s390.md trunk/gcc/config/s390/vector.md trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.target/s390/vector/vec-scalar-cmp-1.c
Created attachment 47018 [details] preprocessed source
Author: iii Date: Fri Oct 11 09:03:00 2019 New Revision: 276872 URL: https://gcc.gnu.org/viewcvs?rev=276872&root=gcc&view=rev Log: S/390: Test signaling FP comparison instructions gcc/testsuite/ChangeLog: 2019-10-11 Ilya Leoshkevich <iii@linux.ibm.com> PR target/77918 * gcc.target/s390/s390.exp: Enable Fortran tests. * gcc.target/s390/zvector/autovec-double-quiet-eq.c: New test. * gcc.target/s390/zvector/autovec-double-quiet-ge.c: New test. * gcc.target/s390/zvector/autovec-double-quiet-gt.c: New test. * gcc.target/s390/zvector/autovec-double-quiet-le.c: New test. * gcc.target/s390/zvector/autovec-double-quiet-lt.c: New test. * gcc.target/s390/zvector/autovec-double-quiet-ordered.c: New test. * gcc.target/s390/zvector/autovec-double-quiet-uneq.c: New test. * gcc.target/s390/zvector/autovec-double-quiet-unordered.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-eq-z13-finite.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-eq-z13.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-eq.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-ge-z13-finite.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-ge-z13.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-ge.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-gt-z13-finite.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-gt-z13.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-gt.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-le-z13-finite.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-le-z13.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-le.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-lt-z13-finite.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-lt-z13.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-lt.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-ltgt-z13-finite.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-ltgt-z13.c: New test. * gcc.target/s390/zvector/autovec-double-signaling-ltgt.c: New test. * gcc.target/s390/zvector/autovec-double-smax-z13.F90: New test. * gcc.target/s390/zvector/autovec-double-smax.F90: New test. * gcc.target/s390/zvector/autovec-double-smin-z13.F90: New test. * gcc.target/s390/zvector/autovec-double-smin.F90: New test. * gcc.target/s390/zvector/autovec-float-quiet-eq.c: New test. * gcc.target/s390/zvector/autovec-float-quiet-ge.c: New test. * gcc.target/s390/zvector/autovec-float-quiet-gt.c: New test. * gcc.target/s390/zvector/autovec-float-quiet-le.c: New test. * gcc.target/s390/zvector/autovec-float-quiet-lt.c: New test. * gcc.target/s390/zvector/autovec-float-quiet-ordered.c: New test. * gcc.target/s390/zvector/autovec-float-quiet-uneq.c: New test. * gcc.target/s390/zvector/autovec-float-quiet-unordered.c: New test. * gcc.target/s390/zvector/autovec-float-signaling-eq.c: New test. * gcc.target/s390/zvector/autovec-float-signaling-ge.c: New test. * gcc.target/s390/zvector/autovec-float-signaling-gt.c: New test. * gcc.target/s390/zvector/autovec-float-signaling-le.c: New test. * gcc.target/s390/zvector/autovec-float-signaling-lt.c: New test. * gcc.target/s390/zvector/autovec-float-signaling-ltgt.c: New test. * gcc.target/s390/zvector/autovec-fortran.h: New test. * gcc.target/s390/zvector/autovec-long-double-signaling-ge.c: New test. * gcc.target/s390/zvector/autovec-long-double-signaling-gt.c: New test. * gcc.target/s390/zvector/autovec-long-double-signaling-le.c: New test. * gcc.target/s390/zvector/autovec-long-double-signaling-lt.c: New test. * gcc.target/s390/zvector/autovec.h: New test. Added: trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-eq.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-ge.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-gt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-le.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-lt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-ordered.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-unordered.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-eq-z13-finite.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-eq-z13.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-eq.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-ge-z13-finite.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-ge-z13.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-ge.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-gt-z13-finite.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-gt-z13.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-gt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-le-z13-finite.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-le-z13.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-le.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-lt-z13-finite.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-lt-z13.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-lt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-ltgt-z13-finite.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-ltgt-z13.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-signaling-ltgt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-smax-z13.F90 trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-smax.F90 trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-smin-z13.F90 trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-double-smin.F90 trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-eq.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-ge.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-gt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-le.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-lt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-ordered.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-unordered.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-signaling-eq.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-signaling-ge.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-signaling-gt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-signaling-le.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-signaling-lt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-float-signaling-ltgt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-fortran.h trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-long-double-signaling-ge.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-long-double-signaling-gt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-long-double-signaling-le.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec-long-double-signaling-lt.c trunk/gcc/testsuite/gcc.target/s390/zvector/autovec.h Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.target/s390/s390.exp
ups wrong bug sry
Should this PR be closed now?
I've tested this patch with help of glibc testsuite. Therefore I've disabled the current workaround: <glibc>/sysdeps/s390/fpu/fix-fp-int-compare-invalid.h: #define FIX_COMPARE_INVALID 0 All tests passed. As information: Without this patch there were fails like: math/test-ldouble-iseqsig.out: testing long double (without inline functions) Failure: iseqsig (-0, qNaN): Exception "Invalid operation" not set Failure: iseqsig (-0, -qNaN): Exception "Invalid operation" not set ... As soon as gcc 10 is released, I will post a glibc-patch which conditionally disables the current workaround. Thanks.
The glibc patch does not need to wait for GCC 10 to be released (we're not concerned with old development versions of GCC in glibc, __GNUC_PREREQ (10, 0) can be used for anything fixed in GCC 10 without regard for when exactly the fix went in).
Just as information, this glibc commit will be first available with glibc 2.31 release: "S390: Fp comparison are now raising FE_INVALID with gcc 10." https://sourceware.org/git/?p=glibc.git;a=commit;h=64bca76f42a82e6a9ea2b0166deab7aa2b7efbea