-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[TwoAddressInstruction] Check if segment was found when updating subreg LIs #65916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TwoAddressInstruction] Check if segment was found when updating subreg LIs #65916
Conversation
…eg LIs This patch fixes a crash I was seeing when working with subregisters in a separate upcoming patch. Some of the RVV tests have -early-live-intervals enabled, which triggers this subregister liveness updating code in TwoAddressInstruction. The INSERT_SUBREG in the test case gets converted to a COPY, so it tries to update the subranges for %1 below: ********** INTERVALS ********** V8 [0B,16r:0) 0@0B-phi %0 [16r,32r:0) 0@16r weight:0.000000e+00 %1 [32r,48r:0) 0@32r L000000000000003C [32r,48r:0) 0@32r L00000000000003C0 [32r,32d:0) 0@32r weight:0.000000e+00 %2 EMPTY weight:0.000000e+00 %3 [48r,48d:0) 0@48r weight:0.000000e+00 0B bb.0: liveins: $v8 16B %0:vr = COPY $v8 32B undef %1.sub_vrm1_0:vrm8 = COPY %0:vr 48B dead %3:vrm4 = COPY %1.sub_vrm4_0:vrm8 64B PseudoRET The subrange for %1 L00000000000003C0 [32r,32d:0) doesn't overlap with sub_vrm1_0's lane mask, so it tries to merge 0@32r. It calls FindSegmentContaining(32B), 32B being the instruction index for the INSERT_SUBREG-turned-COPY. But 32B isn't actually in [32r,32d:0) so it returns end(). The code wasn't checking for end() though so it crashed when dereferencing DefSeg. I'm not familiar with this area in the slightest, but I presume we wanted to find the segment at 32r? And in this test case there's no other segment in the subrange anyway, so we need to check if DefSeg exists. I also did a quick check, nothing in llvm-check-codegen seems to trigger this code. Not sure if that will change if -early-live-intervals is enabled by default.
Hi @lukel97 I do some experiment which recompute the LiveInterval even it has subrange inside TwoAddressInstructionPass pass.
Should they achieve the same result? |
@BeMg Thanks for running that, I think they should be the same. The only subrange in |
…it should always have another segment after it
Similar to llvm#65598, if we're using a vslideup to insert a fixed length vector into another vector, then we can work out the minimum number of registers it will need to slide up across given the minimum VLEN, and shrink the type operated on to reduce LMUL accordingly. This is somewhat dependent on llvm#65916, since it introduces a subregister copy that triggers a crash with -early-live-intervals in one of the tests.
This patch fixes a crash I was seeing when working with subregisters in a
separate upcoming patch. Some of the RVV tests have -early-live-intervals
enabled, which triggers this subregister liveness updating code in
TwoAddressInstruction.
The INSERT_SUBREG in the test case gets converted to a COPY, so it tries to
update the subranges for %1 below:
********** INTERVALS **********
V8 [0B,16r:0) 0@0B-phi
%0 [16r,32r:0) 0@16r weight:0.000000e+00
%1 [32r,48r:0) 0@32r L000000000000003C [32r,48r:0) 0@32r L00000000000003C0 [32r,32d:0) 0@32r weight:0.000000e+00
%2 EMPTY weight:0.000000e+00
%3 [48r,48d:0) 0@48r weight:0.000000e+00
0B bb.0:
liveins: $v8
16B %0:vr = COPY $v8
32B undef %1.sub_vrm1_0:vrm8 = COPY %0:vr
48B dead %3:vrm4 = COPY %1.sub_vrm4_0:vrm8
64B PseudoRET
The subrange for %1 L00000000000003C0 [32r,32d:0) doesn't overlap with
sub_vrm1_0's lane mask, so it tries to merge 0@32r. It calls
FindSegmentContaining(32B), 32B being the instruction index for the
INSERT_SUBREG-turned-COPY. But 32B isn't actually in [32r,32d:0) so it returns
end(). The code wasn't checking for end() though so it crashed when
dereferencing DefSeg.
I'm not familiar with this area, but my guess is that we need to handle the case where a subrange only has one segment, e.g. where there were no previous defs before the insert_subregister.
I also did a quick check, nothing in llvm-check-codegen seems to trigger this
code. Not sure if that will change if -early-live-intervals is enabled by
default.