Tail duplication can mix incompatible registers in phi nodes

Do not tail duplicate blocks where the successor has a phi node,
and the corresponding value in that phi node uses a subregister.

http://reviews.llvm.org/D13922

llvm-svn: 250877
This commit is contained in:
Krzysztof Parzyszek 2015-10-21 02:40:06 +00:00
parent 55765ca54a
commit fdb7b693a7
2 changed files with 49 additions and 0 deletions

View File

@ -607,6 +607,27 @@ TailDuplicatePass::shouldTailDuplicate(const MachineFunction &MF,
return false;
}
// Check if any of the successors of TailBB has a PHI node in which the
// value corresponding to TailBB uses a subregister.
// If a phi node uses a register paired with a subregister, the actual
// "value type" of the phi may differ from the type of the register without
// any subregisters. Due to a bug, tail duplication may add a new operand
// without a necessary subregister, producing an invalid code. This is
// demonstrated by test/CodeGen/Hexagon/tail-dup-subreg-abort.ll.
// Disable tail duplication for this case for now, until the problem is
// fixed.
for (auto SB : TailBB.successors()) {
for (auto &I : *SB) {
if (!I.isPHI())
break;
unsigned Idx = getPHISrcRegOpIdx(&I, &TailBB);
assert(Idx != 0);
MachineOperand &PU = I.getOperand(Idx);
if (PU.getSubReg() != 0)
return false;
}
}
if (HasIndirectbr && PreRegAlloc)
return true;

View File

@ -0,0 +1,28 @@
; RUN: llc -march=hexagon -O2 -disable-cgp < %s
; REQUIRES: asserts
;
; Tail duplication can ignore subregister information on PHI nodes, and as
; a result, generate COPY instructions between registers of different classes.
; This could lead to HexagonInstrInfo::copyPhysReg aborting on an unhandled
; src/dst combination.
;
define i32 @foo(i32 %x, i64 %y) nounwind {
entry:
%a = icmp slt i32 %x, 0
%lo = trunc i64 %y to i32
br i1 %a, label %next, label %tail
tail:
br label %join
next:
%c = icmp eq i32 %x, 0
br i1 %c, label %b1, label %tail
b1:
%t1 = lshr i64 %y, 32
%hi = trunc i64 %t1 to i32
br label %join
join:
%val = phi i32 [ %hi, %b1 ], [ %lo, %tail ]
ret i32 %val
}