diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 264a91ba4cb..49fd21e9728 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -793,7 +793,10 @@ public: && getOperand(1).isImm(); } - bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } + bool isPHI() const { + return getOpcode() == TargetOpcode::PHI || + getOpcode() == TargetOpcode::G_PHI; + } bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index 0b304dd6216..0481006db12 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -415,6 +415,13 @@ def G_INTRINSIC_W_SIDE_EFFECTS : Instruction { let mayStore = 1; } +// PHI node bearing an LLT. +def G_PHI : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins variable_ops); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Branches. //------------------------------------------------------------------------------ diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def index 48d6c74715b..cc54d6cae30 100644 --- a/include/llvm/Target/TargetOpcodes.def +++ b/include/llvm/Target/TargetOpcodes.def @@ -336,6 +336,9 @@ HANDLE_TARGET_OPCODE(G_UITOFP) /// Generic type specifier for untyped registers. HANDLE_TARGET_OPCODE(G_TYPE) +/// Generic PHI node (so that the type of the vreg can be set). +HANDLE_TARGET_OPCODE(G_PHI) + /// Generic BRANCH instruction. This is an unconditional branch. HANDLE_TARGET_OPCODE(G_BR) diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index a27d53941a4..f0ac16712a5 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -405,7 +405,7 @@ bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) { bool IRTranslator::translatePHI(const User &U) { const PHINode &PI = cast(U); - MachineInstrBuilder MIB = MIRBuilder.buildInstr(TargetOpcode::PHI); + auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, LLT{*U.getType()}); MIB.addDef(getOrCreateVReg(PI)); PendingPHIs.emplace_back(&PI, MIB.getInstr()); diff --git a/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/lib/CodeGen/GlobalISel/MachineLegalizer.cpp index cc3d4ecd7c6..5a15f65c45e 100644 --- a/lib/CodeGen/GlobalISel/MachineLegalizer.cpp +++ b/lib/CodeGen/GlobalISel/MachineLegalizer.cpp @@ -30,8 +30,10 @@ MachineLegalizer::MachineLegalizer() : TablesInitialized(false) { DefaultActions[TargetOpcode::G_ANYEXT] = Legal; DefaultActions[TargetOpcode::G_TRUNC] = Legal; - // G_TYPE is essentially an annotated COPY so it's always legal. + // G_TYPE and G_PHI are essentially an annotated COPY/PHI instructions so + // they're always legal. DefaultActions[TargetOpcode::G_TYPE] = Legal; + DefaultActions[TargetOpcode::G_PHI] = Legal; DefaultActions[TargetOpcode::G_INTRINSIC] = Legal; DefaultActions[TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS] = Legal; diff --git a/lib/Target/AArch64/AArch64InstructionSelector.cpp b/lib/Target/AArch64/AArch64InstructionSelector.cpp index 779b624b0f7..26342a19546 100644 --- a/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -235,6 +235,12 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { return true; } + case TargetOpcode::G_PHI: { + I.setDesc(TII.get(TargetOpcode::PHI)); + I.removeTypes(); + return true; + } + case TargetOpcode::G_FRAME_INDEX: { // allocas and G_FRAME_INDEX are only supported in addrspace(0). if (I.getType() != LLT::pointer(0)) { diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 0e79eed86d3..c95fb59d5dd 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -325,7 +325,7 @@ define void @intrinsics(i32 %cur, i32 %bits) { ; CHECK: [[FALSE]]: ; CHECK: [[RES2:%[0-9]+]](32) = G_LOAD { s32, p0 } -; CHECK: [[RES:%[0-9]+]](32) = PHI [[RES1]], %[[TRUE]], [[RES2]], %[[FALSE]] +; CHECK: [[RES:%[0-9]+]](32) = G_PHI s32 [[RES1]], %[[TRUE]], [[RES2]], %[[FALSE]] ; CHECK: %w0 = COPY [[RES]] define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) { br i1 %tst, label %true, label %false