From 443c244cff6ac43735654b2d2c74ca06e7bab102 Mon Sep 17 00:00:00 2001 From: Dominik Montada Date: Thu, 9 Apr 2020 14:33:59 +0200 Subject: [PATCH] [GlobalISel] translate freeze to new generic G_FREEZE Summary: As a follow up to https://reviews.llvm.org/D29014, add translation support for freeze. Introduce a new generic instruction G_FREEZE and translate freeze to it. Reviewers: dsanders, aqjune, arsenm, aditya_nandakumar, t.p.northover, lebedev.ri, paquette, aemerson Reviewed By: aqjune, arsenm Subscribers: fhahn, lebedev.ri, wdng, rovka, hiraditya, jfb, volkan, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77795 --- .../llvm/CodeGen/GlobalISel/IRTranslator.h | 4 +-- .../CodeGen/GlobalISel/MachineIRBuilder.h | 5 ++++ llvm/include/llvm/Support/TargetOpcodes.def | 3 ++ llvm/include/llvm/Target/GenericOpcodes.td | 6 ++++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 15 ++++++++++ .../AArch64/GlobalISel/arm64-irtranslator.ll | 30 ++++++++++++++++++- .../GlobalISel/legalizer-info-validation.mir | 4 +++ 7 files changed, 63 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 490a3a184f9dd..4b116284513d2 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -452,6 +452,7 @@ class IRTranslator : public MachineFunctionPass { bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder); bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder); bool translateFence(const User &U, MachineIRBuilder &MIRBuilder); + bool translateFreeze(const User &U, MachineIRBuilder &MIRBuilder); // Stubs to keep the compiler happy while we implement the rest of the // translation. @@ -482,9 +483,6 @@ class IRTranslator : public MachineFunctionPass { bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) { return false; } - bool translateFreeze(const User &U, MachineIRBuilder &MIRBuilder) { - return false; - } /// @} diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 4a646e0b26cd3..19f65468791d4 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -1270,6 +1270,11 @@ class MachineIRBuilder { /// Build and insert `G_FENCE Ordering, Scope`. MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope); + /// Build and insert \p Dst = G_FREEZE \p Src + MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src) { + return buildInstr(TargetOpcode::G_FREEZE, {Dst}, {Src}); + } + /// Build and insert \p Res = G_BLOCK_ADDR \p BA /// /// G_BLOCK_ADDR computes the address of a basic block. diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 6d5bef112cdbb..5ab88f367ed3a 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -279,6 +279,9 @@ HANDLE_TARGET_OPCODE(G_INTTOPTR) /// COPY is the relevant instruction. HANDLE_TARGET_OPCODE(G_BITCAST) +/// Generic freeze. +HANDLE_TARGET_OPCODE(G_FREEZE) + /// INTRINSIC trunc intrinsic. HANDLE_TARGET_OPCODE(G_INTRINSIC_TRUNC) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index d314d7d2f862f..441f1580dd254 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -203,6 +203,12 @@ def G_DYN_STACKALLOC : GenericInstruction { let hasSideEffects = 1; } +def G_FREEZE : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Binary ops. //------------------------------------------------------------------------------ diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 34b8ab7fe42ff..74f6a2f383ffc 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2103,6 +2103,21 @@ bool IRTranslator::translateFence(const User &U, return true; } +bool IRTranslator::translateFreeze(const User &U, + MachineIRBuilder &MIRBuilder) { + const ArrayRef DstRegs = getOrCreateVRegs(U); + const ArrayRef SrcRegs = getOrCreateVRegs(*U.getOperand(0)); + + assert(DstRegs.size() == SrcRegs.size() && + "Freeze with different source and destination type?"); + + for (unsigned I = 0; I < DstRegs.size(); ++I) { + MIRBuilder.buildFreeze(DstRegs[I], SrcRegs[I]); + } + + return true; +} + void IRTranslator::finishPendingPhis() { #ifndef NDEBUG DILocationVerifier Verifier; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index c023b8d2f9e11..3426270c61e1b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -2360,4 +2360,32 @@ define i64 @test_readcyclecounter() { ret i64 %res } -!0 = !{ i64 0, i64 2 } +define i64 @test_freeze(i64 %a) { + ; CHECK-LABEL: name: test_freeze + ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_FREEZE [[COPY]] + ; CHECK-NEXT: $x0 = COPY [[RES]] + ; CHECK-NEXT: RET_ReallyLR implicit $x0 + %res = freeze i64 %a + ret i64 %res +} + +define {i8, i32} @test_freeze_struct({ i8, i32 }* %addr) { + ; CHECK-LABEL: name: test_freeze_struct + ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4 + ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]] + ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) + ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s8) = G_FREEZE [[LOAD]] + ; CHECK-NEXT: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[LOAD1]] + ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[FREEZE]] + ; CHECK-NEXT: $w0 = COPY [[ANYEXT]] + ; CHECK-NEXT: $w1 = COPY [[FREEZE1]] + ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 + %load = load { i8, i32 }, { i8, i32 }* %addr + %res = freeze {i8, i32} %load + ret {i8, i32} %res +} + +!0 = !{ i64 0, i64 2 } \ No newline at end of file diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index 7163ecee5f6e3..a07304a094b87 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -116,6 +116,10 @@ # DEBUG-NEXT: .. the first uncovered type index: 2, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK # +# DEBUG-NEXT: G_FREEZE (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# # DEBUG-NEXT: G_INTRINSIC_TRUNC (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected