https://gcc.gnu.org/g:e748bc14649a16b25c3655dd393d9844480a5609
commit r16-9241-ge748bc14649a16b25c3655dd393d9844480a5609 Author: Stafford Horne <[email protected]> Date: Sat Jul 4 10:51:59 2026 +0100 or1k: Stop allowing referring to SR_F in SImode and fix cmov We were seeing compiler errors such as: x.c:8:1: error: insn does not satisfy its constraints: 8 | } | ^ (insn 33 28 35 2 (set (reg:SI 34 ?sr_f) (reg:SI 16 r17 [52])) "x.c":6:7 discrim 1 28 {*movsi_internal} (nil)) during RTL pass: postreload This was being caused by previous commit c0694f95f59 ("or1k: Fix ICE in libgcc caused by recent validate_subreg changes") and commit 710581c80b2 ("or1k: Allow SImode for condition flag register") which allow referecing SR_F in SImode to avoid errors during if conversion. We can completely avoid this by reverting the changes to allow referencing SR_F in SImode and fixing the or1k_noce_conversion_profitable_p function to allow cmov expansion even when TARGET_CMOV is not enabled. The *cmov split logic can take care of lowering the *cmov instructions if l.cmov is not supported during the later split passes. gcc/ PR target/126081 * config/or1k/or1k.cc (or1k_hard_regno_mode_ok): Stop allowing SImode for FLAG_REGS. (or1k_can_change_mode_class): Stop allowing SImode for FLAG_REGS. (or1k_noce_conversion_profitable_p): Always check or1k_is_cmov_insn. gcc/testsuite/ PR target/126081 * gcc.target/or1k/pr126081.c: New test. (cherry picked from commit 217a7679f4e50028f62f737c5906e3281c700ddc) Diff: --- gcc/config/or1k/or1k.cc | 14 ++++++++------ gcc/testsuite/gcc.target/or1k/pr126081.c | 8 ++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc index 66fd784f8b91..ccb23dd2aad7 100644 --- a/gcc/config/or1k/or1k.cc +++ b/gcc/config/or1k/or1k.cc @@ -1393,7 +1393,7 @@ or1k_hard_regno_mode_ok (unsigned int regno, machine_mode mode) really single bits within SP[SR]. Also allow condition flag register in SImode to match or1k_can_change_mode_class. */ if (REGNO_REG_CLASS (regno) == FLAG_REGS) - return mode == BImode || mode == SImode; + return mode == BImode; return true; } @@ -1411,7 +1411,7 @@ or1k_can_change_mode_class (machine_mode from, machine_mode to, { /* Allow cnoverting special flags to SI mode subregs. */ if (rclass == FLAG_REGS) - return from == to || (from == BImode && to == SImode); + return from == to; return true; } @@ -1697,15 +1697,17 @@ or1k_is_cmov_insn (rtx_insn *seq) } /* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We detect if the conversion - resulted in a l.cmov instruction and if so we consider it more profitable than - branch instructions. */ + resulted in a l.cmov like instruction and if so we consider it more + profitable than branch instructions. Even if we do not support l.cmov this + allows the *cmov instruction sequnce to be expanded and then later lowered + with the *cmov split logic. */ static bool or1k_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info) { - if (TARGET_CMOV) - return or1k_is_cmov_insn (seq); + if (or1k_is_cmov_insn (seq)) + return true; return default_noce_conversion_profitable_p (seq, if_info); } diff --git a/gcc/testsuite/gcc.target/or1k/pr126081.c b/gcc/testsuite/gcc.target/or1k/pr126081.c new file mode 100644 index 000000000000..b5cce62f3e9a --- /dev/null +++ b/gcc/testsuite/gcc.target/or1k/pr126081.c @@ -0,0 +1,8 @@ +int option_mask32; +void xsocket(int); +enum { OPT_u = 1 << 3 }; + +void nc_main() { + int x = option_mask32 & OPT_u ? 2 : 1; + xsocket(x); +}
