Add needed earlyclobber to fusion patterns

The add-logical and add-add fusion patterns all have constraint
alternatives "=0,1,&r,r" for the output (3). The inputs 0 and 1
are used in the first fusion instruction and then either may be
reused as a temp for the output of the first insn which is
input to the second. However, if input 2 is the same as 0 or 1,
it gets clobbered unexpectedly. So the first 2 alts need to be
"=&0,&1,&r,r" instead to indicate that in alts 0 and 1, the
register used for 3 is earlyclobber, hence can't be the same as
input 2.

This was actually encountered in the backport of the add-logical
fusion patch to gcc-11. Some code in go hit this case:

   <runtime.fillAligned+520>:        andc r30,r30,r9
r30 now (~(x|((x&c)+c)))&(~c) --> this is new x
   <runtime.fillAligned+524>:        b <runtime.fillAligned+288>
   <runtime.fillAligned+288>:        addi r31,r31,-1
r31 now m-1
   <runtime.fillAligned+292>:        srd r31,r30,r31
r31 now x>>(m-1)
   <runtime.fillAligned+296>:        subf r30,r31,r30
r30 now x-(x>>(m-1))
   <runtime.fillAligned+300>:        or r30,r30,r30   # mdoom
nop
   <runtime.fillAligned+304>:        not     r3,r30
r3 now ~(x-(x>>(m-1))) -- WHOOPS

The or r30,r30,r30 was meant to be or-ing in the earlier value
of r30 which was overwritten by the output of the subf.

gcc/ChangeLog

	* config/rs6000/genfusion.pl (gen_logical_addsubf): Add
	earlyclobber to alts 0/1.
	(gen_addadd): Add earlyclobber to alts 0/1.
	* config/rs6000/fusion.md: Regenerate file.
This commit is contained in:
Aaron Sawdey 2021-06-16 10:58:08 -05:00
parent caeb8892a5
commit 00f730ec3a
2 changed files with 152 additions and 152 deletions

File diff suppressed because it is too large Load Diff

View File

@ -263,7 +263,7 @@ sub gen_logical_addsubf
;; $ftype fusion pattern generated by gen_logical_addsubf
;; $kind $inner_op -> $outer_name
(define_insn "*fuse_${inner_op}_${outer_name}"
[(set (match_operand:${mode} 3 "${pred}" "=0,1,&${constraint},${constraint}")
[(set (match_operand:${mode} 3 "${pred}" "=&0,&1,&${constraint},${constraint}")
${outer_exp})
(clobber (match_scratch:${mode} 4 "=X,X,X,&r"))]
"(TARGET_P10_FUSION && $target_flag)"
@ -307,7 +307,7 @@ sub gen_addadd
;; ${op}-${op} fusion pattern generated by gen_addadd
(define_insn "*fuse_${op}_${op}"
[(set (match_operand:${mode} 3 "${pred}" "=0,1,&${constraint},${constraint}")
[(set (match_operand:${mode} 3 "${pred}" "=&0,&1,&${constraint},${constraint}")
(plus:${mode}
(plus:${mode} (match_operand:${mode} 0 "${pred}" "${c4}")
(match_operand:${mode} 1 "${pred}" "%${c4}"))