diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h @@ -42,11 +42,6 @@ unsigned SrcReg, DenseMap &VRBaseMap); - /// getDstOfCopyToRegUse - If the only use of the specified result number of - /// node is a CopyToReg, return its destination register. Return 0 otherwise. - unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, - unsigned ResNo) const; - void CreateVirtualRegisters(SDNode *Node, MachineInstrBuilder &MIB, const MCInstrDesc &II, diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -186,24 +186,6 @@ assert(isNew && "Node emitted out of order - early"); } -/// getDstOfCopyToRegUse - If the only use of the specified result number of -/// node is a CopyToReg, return its destination register. Return 0 otherwise. -unsigned InstrEmitter::getDstOfOnlyCopyToRegUse(SDNode *Node, - unsigned ResNo) const { - if (!Node->hasOneUse()) - return 0; - - SDNode *User = *Node->use_begin(); - if (User->getOpcode() == ISD::CopyToReg && - User->getOperand(2).getNode() == Node && - User->getOperand(2).getResNo() == ResNo) { - unsigned Reg = cast(User->getOperand(1))->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return Reg; - } - return 0; -} - void InstrEmitter::CreateVirtualRegisters(SDNode *Node, MachineInstrBuilder &MIB, const MCInstrDesc &II, @@ -285,14 +267,11 @@ if (Op.isMachineOpcode() && Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) { // Add an IMPLICIT_DEF instruction before every use. - unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo()); // IMPLICIT_DEF can produce any type of result so its MCInstrDesc // does not include operand register class info. - if (!VReg) { - const TargetRegisterClass *RC = - TLI->getRegClassFor(Op.getSimpleValueType()); - VReg = MRI->createVirtualRegister(RC); - } + const TargetRegisterClass *RC = + TLI->getRegClassFor(Op.getSimpleValueType()); + unsigned VReg = MRI->createVirtualRegister(RC); BuildMI(*MBB, InsertPos, Op.getDebugLoc(), TII->get(TargetOpcode::IMPLICIT_DEF), VReg); return VReg; @@ -1007,14 +986,23 @@ case ISD::TokenFactor: // fall thru break; case ISD::CopyToReg: { - unsigned SrcReg; + unsigned DestReg = cast(Node->getOperand(1))->getReg(); SDValue SrcVal = Node->getOperand(2); + if (TargetRegisterInfo::isVirtualRegister(DestReg) && + SrcVal.isMachineOpcode() && + SrcVal.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) { + // Instead building a COPY to that vreg destination, build an + // IMPLICIT_DEF instruction instead. + BuildMI(*MBB, InsertPos, Node->getDebugLoc(), + TII->get(TargetOpcode::IMPLICIT_DEF), DestReg); + break; + } + unsigned SrcReg; if (RegisterSDNode *R = dyn_cast(SrcVal)) SrcReg = R->getReg(); else SrcReg = getVR(SrcVal, VRBaseMap); - unsigned DestReg = cast(Node->getOperand(1))->getReg(); if (SrcReg == DestReg) // Coalesced away the copy? Ignore. break; diff --git a/llvm/test/CodeGen/AMDGPU/i1-copy-phi.ll b/llvm/test/CodeGen/AMDGPU/i1-copy-phi.ll --- a/llvm/test/CodeGen/AMDGPU/i1-copy-phi.ll +++ b/llvm/test/CodeGen/AMDGPU/i1-copy-phi.ll @@ -37,3 +37,28 @@ declare i32 @llvm.amdgcn.workitem.id.x() #0 attributes #0 = { nounwind readnone } + +; Make sure this won't crash. +define <4 x float> @foo(<4 x float> addrspace(1)* %p0, <4 x float> addrspace(1)* %p1, <4 x float> %c, <4 x float> %d, i64 %len) { +entry: + br label %loop.body + +loop.body: + %all = phi <4 x i1> [ undef, %entry ], [ %all.next, %loop.body ] + %i = phi i64 [ 0, %entry ], [ %i.next, %loop.body ] + %pa = phi <4 x float> addrspace(1)* [ %p0, %entry ], [ %p0.next, %loop.body ] + %pb = phi <4 x float> addrspace(1)* [ %p1, %entry ], [ %p1.next, %loop.body ] + %a = load <4 x float>, <4 x float> addrspace(1)* %pa + %b = load <4 x float>, <4 x float> addrspace(1)* %pb + %cmp = fcmp one <4 x float> %a, %b + %all.next = or <4 x i1> %all, %cmp + %i.next = add i64 %i, 1 + %p0.next = getelementptr <4 x float>, <4 x float> addrspace(1)* %pa, i64 1 + %p1.next = getelementptr <4 x float>, <4 x float> addrspace(1)* %pb, i64 1 + %cond = icmp ult i64 %i.next, %len + br i1 %cond, label %loop.body, label %loop.exit + +loop.exit: + %ret = select <4 x i1> %all, <4 x float> %c, <4 x float> %d + ret <4 x float> %ret +}