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" "")
