diff options
author | Aaron Sawdey <acsawdey@linux.ibm.com> | 2021-06-16 10:58:08 -0500 |
---|---|---|
committer | Aaron Sawdey <acsawdey@linux.ibm.com> | 2021-06-17 10:48:17 -0500 |
commit | 00f730ec3a24fd1453b3ee96e8a50a29d5db3ac3 (patch) | |
tree | eabd8d5402670b694e9abb98b1049c3c71586603 /gcc/tree-ssa-phiopt.c | |
parent | caeb8892a556a4a634641c7613fec957359dbd49 (diff) | |
download | gcc-00f730ec3a24fd1453b3ee96e8a50a29d5db3ac3.zip gcc-00f730ec3a24fd1453b3ee96e8a50a29d5db3ac3.tar.gz gcc-00f730ec3a24fd1453b3ee96e8a50a29d5db3ac3.tar.bz2 |
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.
Diffstat (limited to 'gcc/tree-ssa-phiopt.c')
0 files changed, 0 insertions, 0 deletions