https://gcc.gnu.org/g:e7287c2b7b383edb54cfb446dae249ff7a8db047

commit r17-5730-ge7287c2b7b383edb54cfb446dae249ff7a8db047
Author: Stefan Schulze Frielinghaus <[email protected]>
Date:   Thu Oct 29 08:15:09 2026 +0100

    s390: Implement aop optab
    
    For word_mode and SImode the generic optab expander chooses PLUS over
    IOR.  On s390 we optimized heavily towards risbg and friends.  This is
    demonstrated well by the following example:
    
    void test (unsigned int *p, unsigned int x)
    {
      *p = (*p & ~0xffu) | (x & 0xff);
    }
    
    If aop expands into a PLUS we end up with
    
    l       %r1,0(%r2)    // load *p
    llcr    %r3,%r3       // x & 0xff
    nill    %r1,65280     // *p & ~0xffu
    ar      %r1,%r3       // add
    st      %r1,0(%r2)    // store
    br      %r14
    
    and for an IOR with
    
    stc     %r3,3(%r2)    // store
    br      %r14
    
    The culprit here is mainly due to no available carry information on RTL
    level which means the target has to express this in its patterns which
    isn't nearly done as often for a PLUS than for an IOR.  Therefore, for
    the moment expand into an IOR.
    
    gcc/ChangeLog:
    
            * config/s390/s390.md (aop<mode>3): New expander.

Diff:
---
 gcc/config/s390/s390.md | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 440df547321a..389204bfabc7 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -6868,6 +6868,17 @@
      (clobber (reg:CC CC_REGNUM))])]
   "")
 
+;
+; Any-Or-Plus (AOP)
+;
+
+(define_expand "aop<mode>3"
+  [(match_operand:DSI 0 "nonimmediate_operand")
+   (match_operand:DSI 1 "nonimmediate_operand")
+   (match_operand:DSI 2 "general_operand")]
+  ""
+  "emit_insn (gen_ior<mode>3 (operands[0], operands[1], operands[2])); DONE;")
+
 
 (define_expand "cstore<mode>4"
   [(set (match_operand:SI 0 "register_operand" "")

Reply via email to