https://gcc.gnu.org/g:d33d3552eb807d64d05f0732ff9003bfae706f03
commit r17-4703-gd33d3552eb807d64d05f0732ff9003bfae706f03 Author: Roger Sayle <[email protected]> Date: Sun Sep 27 14:39:45 2026 -0600 [PR target/127267] Improve code on iq2000 port for AOR optabs and lowpart IOR with 0x0 I'm submitting this on Roger's behalf. After debugging the execution fails originally attributed to Roger's patch for p127267, I'm of the opinion Roger's code is fine and that we've go some kind of linker issue going on. The details are in the BZ. Roger's patch tries to accomplish a few things. First it defines the aop optab to steer the iq2000 port to IOR rather than PLUS when they're equiavlent. That probably makes sense. In the process the patch improves the generated code for an IOR when the low bits are zero. For the case of loading a constant, we just emit the LUI for the high part and we're done. In the case of an IOR against zero, it turns into a copy. His patch also fixes up an parenthesis error in SMALL_INT handling. This fixes the poor code generation noted in pr127267. I suspect (but can not confirm) that the 20040705-1 execution failure is likely the same kind of linker bug that I just chased down. In fact, it makes any execution issues on the iq2000 port suspect (and I've had a long time suspicion that something wasn't quite right on the iq2000 port given is sporadic failures. PR target/127267 gcc/ * config/iq2000/iq2000.h (SMALL_INT): Fix trivial parenthesis goof. * config/iq2000/iq2000.cc (iq2000_move_1word): Eliminate useless IOR with 0x0 operand. * config/iq2000/iq2000.md (aopsi3): New expander. (32 bit integer move splitter): Turn low part IOR into a copy when the constant is zero. Diff: --- gcc/config/iq2000/iq2000.cc | 2 ++ gcc/config/iq2000/iq2000.h | 2 +- gcc/config/iq2000/iq2000.md | 13 +++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gcc/config/iq2000/iq2000.cc b/gcc/config/iq2000/iq2000.cc index 9945423affc8..2df80e11af1f 100644 --- a/gcc/config/iq2000/iq2000.cc +++ b/gcc/config/iq2000/iq2000.cc @@ -678,6 +678,8 @@ iq2000_move_1word (rtx operands[], rtx_insn *insn, int unsignedp) ret = "ori\t%0,%%0,%x1\t\t\t# %1"; else if (SMALL_INT (op1)) ret = "addiu\t%0,%%0,%1\t\t\t# %1"; + else if (CONST_INT_P (op1) && (INTVAL (op1) & 0xffff) == 0) + ret = "lui\t%0,%X1\t\t\t# %1"; else ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1"; } diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index b2a960a2909f..82f72db370f8 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -629,7 +629,7 @@ enum delay_type #define GR_REG_CLASS_P(CLASS) \ ((CLASS) == GR_REGS) -#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) +#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) (INTVAL (X)) + 0x8000 < 0x10000) #define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (INTVAL (X)) < 0x10000) /* Certain machines have the property that some registers cannot be diff --git a/gcc/config/iq2000/iq2000.md b/gcc/config/iq2000/iq2000.md index ab9709a98df0..1872553adc5b 100644 --- a/gcc/config/iq2000/iq2000.md +++ b/gcc/config/iq2000/iq2000.md @@ -425,6 +425,14 @@ "nor\\t%0,%z1,%z2" [(set_attr "type" "arith") (set_attr "mode" "SI")]) + +;; Expand any_or_plus (AOP) as iorsi3 +(define_expand "aopsi3" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") + (match_operand:SI 2 "uns_arith_operand" "d,K")))] + "" + "") ;; ;; .................... @@ -686,6 +694,11 @@ & BITMASK_UPPER16, SImode)); operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16); + if (operands[3] == const0_rtx) + { + emit_insn (gen_rtx_SET (operands[0], operands[2])); + DONE; + } }") ;; Unlike most other insns, the move insns can't be split with
