Hi,
We're having an issue with TailDuplication in our out-of-tree target and it's this PHI-node that seems to be the cause of the trouble:
%vreg2<def> = PHI %vreg0, <BB#2>, %vreg1, <BB#3>; rN:%vreg2 aNlh_0_7:%vreg0 aNlh_rN:%vreg1
Note that the defined %vreg2 has register class "rN" while the read %vreg0 has register class "aNlh_0_7". "rN" and "aNlh_0_7" are disjoint.
Is such a PHI node ok?
If it is, then there is a bug in TailDuplication.
Before TailDuplication we have:
BB#2: derived from LLVM BB %bb2
Predecessors according to CFG: BB#1
%vreg12<def> = mv16Sym <ga:@a>; rN:%vreg12
%vreg13<def> = mv_nimm6_ar16 0; aNlh_rN:%vreg13
mv_ar16_r16_rmod1 %vreg13<kill>, %vreg12<kill>; aNlh_rN:%vreg13 rN:%vreg12
brr_uncond <BB#4>;
Successors according to CFG: BB#4(?%)
BB#4: derived from LLVM BB %bb4
Predecessors according to CFG: BB#2 BB#3
%vreg2<def> = PHI %vreg0, <BB#2>, %vreg1, <BB#3>; rN:%vreg2 aNlh_0_7:%vreg0 aNlh_rN:%vreg1
mv_a32_r16_rmod1 %vreg3, %vreg2; aN32_0_7:%vreg3 rN:%vreg2
brr_uncond <BB#6>;
Successors according to CFG: BB#6(?%)
Then TailDuplication runs
Tail-duplicating into PredBB: BB#2: derived from LLVM BB %bb2
[...]
From Succ: BB#4: derived from LLVM BB %bb4
and we get:
BB#2: derived from LLVM BB %bb2
Predecessors according to CFG: BB#1
%vreg12<def> = mv16Sym <ga:@a>; rN:%vreg12
%vreg13<def> = mv_nimm6_ar16 0; aNlh_rN:%vreg13
mv_ar16_r16_rmod1 %vreg13<kill>, %vreg12<kill>; aNlh_rN:%vreg13 rN:%vreg12
mv_a32_r16_rmod1 %vreg3, %vreg0; aN32_0_7:%vreg3 aNlh_0_7:%vreg0
%vreg18<def> = COPY %vreg0; rN:%vreg18 aNlh_0_7:%vreg0
brr_uncond <BB#6>;
Successors according to CFG: BB#6(0x80000000 / 0x80000000 = 100.00%)
The problem here is the duplicated instruction
mv_a32_r16_rmod1 %vreg3, %vreg0; aN32_0_7:%vreg3 aNlh_0_7:%vreg0
since %vreg0 has register class "aNlh_0_7" but the instruction expects a disjoint register class, "rN".
During duplication TailDuplication copied the instruction and then simply replaced %vreg2 with %vreg0 since they are connected through a PHI, but since the register classes differ, the resulting code is wrong.
I've managed to get around this by inserting a COPY in TailDuplication but I don't know what the proper fix is to this.
In TailDuplicatePass::ProcessPHI:
const TargetRegisterClass *RC = MRI->getRegClass(DefReg);
+ const TargetRegisterClass *SrcRC = MRI->getRegClass(SrcReg);