I did the change suggested by Uli in the *insv_rnsbg_srl pattern. Tested on s390 and s390x with z196 and zEC12.
Please apply to mainline. Thanks! Bye, -Andreas- gcc/config/s390/s390.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) Index: gcc/config/s390/s390.md =================================================================== *** gcc/config/s390/s390.md.orig --- gcc/config/s390/s390.md *************** *** 3534,3539 **** --- 3534,3594 ---- "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3" [(set_attr "op_type" "RIE")]) + ;; These two are generated by combine for s.bf &= val. + ;; ??? For bitfields smaller than 32-bits, we wind up with SImode + ;; shifts and ands, which results in some truly awful patterns + ;; including subregs of operations. Rather unnecessisarily, IMO. + ;; Instead of + ;; + ;; (set (zero_extract:DI (reg/v:DI 50 [ s ]) + ;; (const_int 24 [0x18]) + ;; (const_int 0 [0])) + ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ]) + ;; (const_int 40 [0x28])) 4) + ;; (reg:SI 4 %r4 [ y+4 ])) 0)) + ;; + ;; we should instead generate + ;; + ;; (set (zero_extract:DI (reg/v:DI 50 [ s ]) + ;; (const_int 24 [0x18]) + ;; (const_int 0 [0])) + ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ]) + ;; (const_int 40 [0x28])) + ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0))) + ;; + ;; by noticing that we can push down the outer paradoxical subreg + ;; into the operation. + + (define_insn "*insv_rnsbg_noshift" + [(set (zero_extract:DI + (match_operand:DI 0 "nonimmediate_operand" "+d") + (match_operand 1 "const_int_operand" "") + (match_operand 2 "const_int_operand" "")) + (and:DI + (match_dup 0) + (match_operand:DI 3 "nonimmediate_operand" "d"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_Z10 + && INTVAL (operands[1]) + INTVAL (operands[2]) == 64" + "rnsbg\t%0,%3,%2,63,0" + [(set_attr "op_type" "RIE")]) + + (define_insn "*insv_rnsbg_srl" + [(set (zero_extract:DI + (match_operand:DI 0 "nonimmediate_operand" "+d") + (match_operand 1 "const_int_operand" "") + (match_operand 2 "const_int_operand" "")) + (and:DI + (lshiftrt:DI + (match_dup 0) + (match_operand 3 "const_int_operand" "")) + (match_operand:DI 4 "nonimmediate_operand" "d"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_Z10 + && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])" + "rnsbg\t%0,%4,%2,%2+%1-1,%3" + [(set_attr "op_type" "RIE")]) + (define_insn "*insv<mode>_mem_reg" [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S") (match_operand 1 "const_int_operand" "n,n")