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.

Attached is what I pushed to the trunk on Roger's behalf.

Jeff
commit d33d3552eb807d64d05f0732ff9003bfae706f03
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 --git a/gcc/config/iq2000/iq2000.cc b/gcc/config/iq2000/iq2000.cc
index 9945423affc..2df80e11af1 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 b2a960a2909..82f72db370f 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 ab9709a98df..1872553adc5 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

Reply via email to