The compiler, configured with --enable-checking=yes,rtl,extra ICEs with: internal compiler error: RTL check: expected elt 0 type 'e' or 'u', have 'E' (rtx unspec) in try_combine, at combine.cc:3237
This is 3236 /* Just replace the CC reg with a new mode. */ 3237 SUBST (XEXP (*cc_use_loc, 0), newpat_dest); 3238 undobuf.other_insn = cc_use_insn; in combine.cc, where *cc_use_loc is (unspec:DI [ (reg:CC 17 flags) ] UNSPEC_PUSHFL) combine assumes CC must be used inside of a comparison and uses XEXP (..., 0) without checking on the RTX type of the argument. Undo the combination if *cc_use_loc is not COMPARISON_P. Also remove buggy and now redundant check for (const 0) RTX as part of the comparison. PR rtl-optimization/112560 gcc/ChangeLog: * combine.cc (try_combine): Reject the combination if *cc_use_loc is not COMPARISON_P. Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}. OK for trunk? Uros.
diff --git a/gcc/combine.cc b/gcc/combine.cc index a4479f8d836..6dac9ffca85 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -3184,11 +3184,21 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, && (cc_use_loc = find_single_use (SET_DEST (newpat), i3, &cc_use_insn))) { - compare_code = orig_compare_code = GET_CODE (*cc_use_loc); - if (is_a <scalar_int_mode> (GET_MODE (i2dest), &mode)) - compare_code = simplify_compare_const (compare_code, mode, - &op0, &op1); - target_canonicalize_comparison (&compare_code, &op0, &op1, 1); + if (COMPARISON_P (*cc_use_loc)) + { + compare_code = orig_compare_code = GET_CODE (*cc_use_loc); + if (is_a <scalar_int_mode> (GET_MODE (i2dest), &mode)) + compare_code = simplify_compare_const (compare_code, mode, + &op0, &op1); + target_canonicalize_comparison (&compare_code, &op0, &op1, 1); + } + else + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "CC register not used in comparison.\n"); + undo_all (); + return 0; + } } /* Do the rest only if op1 is const0_rtx, which may be the @@ -3221,9 +3231,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, } #endif /* Cases for modifying the CC-using comparison. */ - if (compare_code != orig_compare_code - /* ??? Do we need to verify the zero rtx? */ - && XEXP (*cc_use_loc, 1) == const0_rtx) + if (compare_code != orig_compare_code) { /* Replace cc_use_loc with entire new RTX. */ SUBST (*cc_use_loc,