noce_emit_store_flag feeds the possibly-reversed comparison code to a
store-flag insn, and to emit_store_flag, without checking that the
reversal succeeded. reversed_comparison_code returns UNKNOWN for
UNLT/UNLE/UNGT/UNGE, and for a MODE_CC comparison it cannot trace back
to its COMPARE -- common for a floating-point condition on targets that
compare into a condition-code register. emit_store_flag then reaches
its floating-point path and calls swap_condition (UNKNOWN), which aborts.
This was latent until r17-2519-ga33f26607eb4f3 (noce_try_shifted_store_flag),
the first caller to reach noce_emit_store_flag with REVERSEP set for such
a condition.
Bail out early when the reversal failed.
Bootstrapped and regression tested on aarch64-unknown-linux-gnu with no
regressions.
PR rtl-optimization/126347
gcc/
* ifcvt.cc (noce_emit_store_flag): Return NULL_RTX when the
comparison code is UNKNOWN.
---
gcc/ifcvt.cc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 7c50ab06e2f7..6b169e69741d 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -865,6 +865,11 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x,
bool reversep,
else
code = GET_CODE (cond);
+ /* reversed_comparison_code returns UNKNOWN for an unordered code, or a
+ CC-mode compare it cannot trace; neither path below can use that. */
+ if (code == UNKNOWN)
+ return NULL_RTX;
+
if ((if_info->cond_earliest == if_info->jump || cond_complex)
&& (normalize == 0 || STORE_FLAG_VALUE == normalize))
{
--
2.34.1