This is an archive of the discontinued LLVM Phabricator instance.

PHI-def LIveInterval's LaneMask can be calculated by subranges LaneMask when Reg has SubRanges.
Needs ReviewPublic

Authored by Michael-Zhang-21 on Mar 2 2023, 11:21 PM.

Details

Summary

When doing register coalescing for copys from reg to subreg like this:

%72.ssub_1:vregs = COPY %239:svregs

the %239 LiveRange is conflicting with %72.ssub_0 not %72.ssub_1, meaning the two regs are conflicting in different Lanes, which should return CR_Replace.

But the conflicting Segment of %72 was calcuated as 0xFFFFFFFF because %239 doesnot have a subreg Thus, the SubIdx of %72 is 0 and LaneMask is set to 0xFFFFFFFF, which will lead the conflict LaneMask with %239.

I think the LaneMask of PHI-def LiveRange should caculated by its subrange's LaneMask when the Reg has SubRanges. Because the Reg is Live in some subrange, It should have the LaneMask of this SubRange. When the VNI is Live all the SubRanges, Reg's LaneMask should be the Union of LaneMask of Subranges.

In New method, the LaneMask of %72's PHI-def Segment is the same as the subrange's LaneMask. The %72 and %239 will be conflicting in different Lanes and replace CR_Replace.

original question:
When doing register coalescing for copys from reg to subreg like this:
%72.ssub_1:vregs = COPY %239:svregs
If the liverange of %239 conflicts with the liverange of %72, but not for %72.ssub_1.

I have tried set SubRangeJoin to true, this COPY can be coalesced.

So can this attribute be modified by subtarget? Is there any potential problems when set this to true?
Hopeful to get some suggestion. Thanks.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptMar 2 2023, 11:21 PM
Michael-Zhang-21 requested review of this revision.Mar 2 2023, 11:21 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 2 2023, 11:21 PM

I don't think this is correct.
Here we are merging the main live-ranges, so if we set the join subrange flag we may not check the right thing. In particular, the LaneBitmask in this call is incorrect, unless I am mistaken, for a subrange check.

Michael-Zhang-21 updated this revision to Diff 522100.EditedMay 15 2023, 3:21 AM

1、SubRangeJoin cannot be set to true in JoinVirtRegs function. Becuase it will check Live Ranges of a virtual register. When set to true, virtual reg with subranges will all be set to CR_Replace without LaneMask conflicting check. Thus, SubRangeJoin can not be set by Target.

2、I met a IR like this:
3504B bb.16.for.body62:
; predecessors: %bb.15, %bb.16

successors: %bb.17(0x04000000), %bb.16(0x7c000000); %bb.17(3.12%), %bb.16(96.88%)

...
3872B %72.ssub_0:v64_regs = Vector_Calc_Op %72.ssub_0:v64_regs
3904B %239:v32_regs = Vector_Calc_Op %239:v32_regs
4256B BNE %263:scalar_regs, $r0, %bb.16

4272B bb.17.for.cond71.preheader:
; predecessors: %bb.16

	  successors: %bb.19; %bb.19(100.00%)

4304B %72.ssub_1:v64_regs = COPY %239:v32_regs
4320B %237:v64_regs = IMPLICIT_DEF
4336B %238:v64_regs = COPY %72:v64_regs

Here, we are doing JoinVirtRegs function for this MI: 4304B %72.ssub_1:v64_regs = COPY %239:v32_regs.
Although %72 and %239 has conflicting LR, But they are conflicting in different Lanes. Only ssub0 of %72 is conflicting in 3872B, but not the ssub1 of %72 which is what we care about.
The reason why it fails is that PHI-def LR's LaneMask is set to 0xFFFFFFFF. But in this case, the VNI is not Live in all SubRanges. When considering about the LaneMask of this PHI-def LR, we can caculate the LaneMask which VNI is just living in. Other Subranges should have nothing with this VNI.

After modification, the IR looks like this :
3504B bb.16.for.body62:
; predecessors: %bb.15, %bb.16

	  successors: %bb.17(0x04000000), %bb.16(0x7c000000); %bb.17(3.12%), %bb.16(96.88%)

...
3872B %72.ssub_0:v64_regs = Vector_Calc_Op %72.ssub_0:v64_regs
3904B %72.ssub_1:v64_regs = Vector_Calc_Op %72.ssub_1:v64_regs
4256B BNE %263:scalar_regs, $r0, %bb.16

...
4272B bb.17.for.cond71.preheader:
; predecessors: %bb.16

	  successors: %bb.19; %bb.19(100.00%)

4320B %237:v64_regs = IMPLICIT_DEF
4336B %238:v64_regs = COPY %72:v64_regs

Please review

3、Met a case in AMDGPU: llvm/test/CodeGen/AMDGPU/coalescer-subranges-prune-kill-copy.mir
IR:

bb.0:
  undef %0.sub0:vreg_128 = IMPLICIT_DEF
  %0.sub1:vreg_128 = IMPLICIT_DEF
  %1:vreg_128 = COPY %0
  %2:vreg_128 = COPY killed %0
  S_BRANCH %bb.2

Analysis:
%1 and %2 should be identical values.
But in JoinVals::followCopyChain, %0 has subranges. The program will return in if (LRQ.valueIn() && ValueIn != LRQ.valueIn()) condition.
But the function returns TrackReg which is %1 and %2 respectively.
When %0 doesnot have subranges, func will return SrcReg, %0.
I think in subranges branch, it should return the final def values, which is SrcReg and VNI should be updated with LRQ.valueIn().

Michael-Zhang-21 retitled this revision from Can SubRangeJoin, attribute of JoinVals, be modified by target? Why is this attribute set to false now? to PHI-def LIveInterval's LaneMask can be calculated by subranges LaneMask when Reg has SubRanges..May 16 2023, 11:53 PM
Michael-Zhang-21 edited the summary of this revision. (Show Details)
Michael-Zhang-21 edited the summary of this revision. (Show Details)May 17 2023, 12:00 AM

I don't think this is correct.
Here we are merging the main live-ranges, so if we set the join subrange flag we may not check the right thing. In particular, the LaneBitmask in this call is incorrect, unless I am mistaken, for a subrange check.

Thanks for your comments. I figured out that the SubRangeJoin can not be set true when Joining MainRanges.
In order to handle the problem, conflicting subrange with mainrange, I have modified the method of LaneMask calculation for PHI-def LiveRange. Details have been illustrated.

Hopeful to get some remarks of this change. Thx

Hey!

Could you re-upload the patch with the full context please?

Thanks,
-Quentin

Hey!

Could you re-upload the patch with the full context please?

Thanks,
-Quentin

Please see the patch:
https://reviews.llvm.org/D152066

Please see the patch:
https://reviews.llvm.org/D152066

It's still missing the context.

  • Re-create your diff with -U99999
  • Click Update Diff in the top right corner
arsenm added a subscriber: arsenm.Jun 6 2023, 6:19 AM

Needs testcase

This comment was removed by Michael-Zhang-21.
This comment was removed by Michael-Zhang-21.

update patch diff again.

Please see the patch:
https://reviews.llvm.org/D152066

It's still missing the context.

  • Re-create your diff with -U99999
  • Click Update Diff in the top right corner

thanks for your guidance.
I need to fix the failed cases first.

Needs testcase

ok. As the testcase is found on our own target, I need time to prepare some testcases on open targets.