Mikael Holmén via llvm-dev
2016-Mar-04 12:44 UTC
[llvm-dev] PHI node to different register class vs TailDuplication
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); + + // If the register class of the PHI src is wider than the PHI def + // then we can't just use PHI src instead of PHI def in the cloned + // instruction. Instead we insert a copy, copying the PHI src to a + // register of the wanted register class. + if (!RC->hasSubClassEq(SrcRC)) { + unsigned NewDef = MRI->createVirtualRegister(RC); + + BuildMI(*PredBB, PredBB->instr_end(), DebugLoc(), + TII->get(TargetOpcode::COPY), NewDef).addReg(SrcReg); + SrcReg = NewDef; + } + LocalVRMap.insert(std::make_pair(DefReg, SrcReg)); Any thoughts on this? /Mikael
Krzysztof Parzyszek via llvm-dev
2016-Mar-04 19:09 UTC
[llvm-dev] PHI node to different register class vs TailDuplication
On 3/4/2016 6:44 AM, Mikael Holmén via llvm-dev wrote:> > Is such a PHI node ok?That doesn't seem to be well documented. The PHI nodes are described as "representing an assignment", but what the "assignment" could be is not clear. Even if there exists an instruction that could copy registers between register classes, if you cannot substitute the output operand with one of the input operands in any use of the output, the PHI would seem to be malformed. At least, that is my interpretation. -Krzysztof -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Matthias Braun via llvm-dev
2016-Mar-05 00:36 UTC
[llvm-dev] PHI node to different register class vs TailDuplication
A PHI can be thought of - and will be lowered to - COPY instructions at the end of the respective predecessor blocks. So what you need in the example is that a COPY instruction from class "aNlh_0_7" to class "rN" is valid and that a COPY from class "aNlh_rN" to class "rN" is valid. - Matthias> On Mar 4, 2016, at 11:09 AM, Krzysztof Parzyszek via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > On 3/4/2016 6:44 AM, Mikael Holmén via llvm-dev wrote: >> >> Is such a PHI node ok? > > That doesn't seem to be well documented. The PHI nodes are described as "representing an assignment", but what the "assignment" could be is not clear. Even if there exists an instruction that could copy registers between register classes, if you cannot substitute the output operand with one of the input operands in any use of the output, the PHI would seem to be malformed. At least, that is my interpretation. > > -Krzysztof > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev