aarch64: Don't raise FE_INVALID for -__builtin_isgreater [PR93133]
AIUI, the main purpose of REVERSE_CONDITION is to take advantage of any integer vs. FP information encoded in the CC mode, particularly when handling LT, LE, GE and GT. For integer comparisons we can safely map LT->GE, LE->GT, GE->LT and GT->LE, but for float comparisons this would usually be invalid without -ffinite-math-only. The aarch64 definition of REVERSE_CONDITION used reverse_condition_maybe_unordered for FP comparisons, which had the effect of converting an unordered-signalling LT, LE, GE or GT into a quiet UNGE, UNGT, UNLT or UNLE. And it would do the same in reverse: convert a quiet UN* into an unordered-signalling comparison. This would be safe in practice (although a little misleading) if we always used a compare:CCFP or compare:CCFPE to do the comparison and then used (gt (reg:CCFP/CCFPE CC_REGNUM) (const_int 0)) etc. to test the result. In that case any signal is raised by the compare and the choice of quiet vs. signalling relations doesn't matter when testing the result. The problem is that we also want to use GT directly on float registers, where any signal is raised by the comparison operation itself and so must follow the normal rtl rules (GT signalling, UNLE quiet). I think the safest fix is to make REVERSIBLE_CC_MODE return false for FP comparisons. We can then use the default REVERSE_CONDITION for integer comparisons and the usual conservatively-correct reversed_comparison_code_parts behaviour for FP comparisons. Unfortunately reversed_comparison_code_parts doesn't yet handle -ffinite-math-only, but that's probably GCC 11 material. A downside is that: int f (float x, float y) { return !(x < y); } now generates: fcmpe s0, s1 cset w0, mi eor w0, w0, 1 ret without -ffinite-math-only. Maybe for GCC 11 we should define rtx codes for all IEEE comparisons, so that we don't have this kind of representational gap. Changing REVERSE_CONDITION itself is pretty easy. However, the macro was also used in the ccmp handling, which relied on being able to reverse all comparisons. The patch adds new reversed patterns for cases in which the original condition needs to be kept. The test is based on gcc.dg/torture/pr91323.c. It might well fail on other targets that have similar bugs; please XFAIL as appropriate if you don't want to fix the target for GCC 10. 2020-01-17 Richard Sandiford <richard.sandiford@arm.com> gcc/ * config/aarch64/aarch64.h (REVERSIBLE_CC_MODE): Return false for FP modes. (REVERSE_CONDITION): Delete. * config/aarch64/iterators.md (CC_ONLY): New mode iterator. (CCFP_CCFPE): Likewise. (e): New mode attribute. * config/aarch64/aarch64.md (ccmp<GPI:mode>): Rename to... (@ccmp<CC_ONLY:mode><GPI:mode>): ...this, using CC_ONLY instead of CC. (fccmp<GPF:mode>, fccmpe<GPF:mode>): Merge into... (@ccmp<CCFP_CCFPE:mode><GPF:mode>): ...this combined pattern. (@ccmp<CC_ONLY:mode><GPI:mode>_rev): New pattern. (@ccmp<CCFP_CCFPE:mode><GPF:mode>_rev): Likewise. * config/aarch64/aarch64.c (aarch64_gen_compare_reg): Update name of generator from gen_ccmpdi to gen_ccmpccdi. (aarch64_gen_ccmp_next): Use code_for_ccmp. If we want to reverse the previous comparison but aren't able to, use the new ccmp_rev patterns instead.
Showing
gcc/testsuite/gcc.dg/torture/pr93133.c
0 → 100644
Please
register
or
sign in
to comment