diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h | 8 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | 9 | ||||
-rw-r--r-- | llvm/include/llvm/Target/GenericOpcodes.td | 19 | ||||
-rw-r--r-- | llvm/include/llvm/Target/TargetOpcodes.def | 10 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRPrinter.cpp | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll | 60 |
8 files changed, 135 insertions, 10 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index b61f5bbcdd0..656e327fedc 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -93,6 +93,14 @@ private: /// \return true if the translation succeeded. bool translate(const Instruction &Inst); + /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is + /// emitted. + bool translateBitCast(const CastInst &CI); + + /// Translate one of LLVM's cast instructions into MachineInstrs, with the + /// given generic Opcode. + bool translateCast(unsigned Opcode, const CastInst &CI); + /// Translate alloca instruction (i.e. one of constant size and in the first /// basic block). bool translateStaticAlloca(const AllocaInst &Inst); diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 55eafb372f9..c835be06e2d 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -116,6 +116,15 @@ public: MachineInstr *buildInstr(unsigned Opcode, LLT Ty, unsigned Res, unsigned Op0, unsigned Op1); + /// Build and insert \p Res<def> = \p Opcode {[\p Tys]} \p Op0, \p Op1. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre Tys empty or isPreISelGenericOpcode(Opcode) + /// + /// \return The newly created instruction. + MachineInstr *buildInstr(unsigned Opcode, ArrayRef<LLT> Tys, unsigned Res, + unsigned Op0); + /// Build and insert \p Res<def> = \p Opcode \p Op0, \p Op1. /// I.e., instruction with a non-generic opcode. /// diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 4c297322aa7..0f846e743c3 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -22,6 +22,25 @@ def G_FRAME_INDEX : Instruction { let hasSideEffects = 0; } +def G_INTTOPTR : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let hasSideEffects = 0; +} + +def G_PTRTOINT : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let hasSideEffects = 0; +} + +def G_BITCAST : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let hasSideEffects = 0; +} + + //------------------------------------------------------------------------------ // Binary ops. //------------------------------------------------------------------------------ diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def index 297ff82ccfd..61668770329 100644 --- a/llvm/include/llvm/Target/TargetOpcodes.def +++ b/llvm/include/llvm/Target/TargetOpcodes.def @@ -180,6 +180,16 @@ HANDLE_TARGET_OPCODE(G_EXTRACT) /// larger register. HANDLE_TARGET_OPCODE(G_SEQUENCE) +/// Generic pointer to int conversion. +HANDLE_TARGET_OPCODE(G_PTRTOINT) + +/// Generic int to pointer conversion. +HANDLE_TARGET_OPCODE(G_INTTOPTR) + +/// Generic bitcast. The source and destination types must be different, or a +/// COPY is the relevant instruction. +HANDLE_TARGET_OPCODE(G_BITCAST) + /// Generic BRANCH instruction. This is an unconditional branch. HANDLE_TARGET_OPCODE(G_BR) diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 82cec258fa6..f7db60f59b5 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -100,6 +100,23 @@ bool IRTranslator::translateBr(const Instruction &Inst) { return true; } +bool IRTranslator::translateBitCast(const CastInst &CI) { + if (LLT{*CI.getDestTy()} == LLT{*CI.getSrcTy()}) { + MIRBuilder.buildInstr(TargetOpcode::COPY, getOrCreateVReg(CI), + getOrCreateVReg(*CI.getOperand(0))); + return true; + } + return translateCast(TargetOpcode::G_BITCAST, CI); +} + +bool IRTranslator::translateCast(unsigned Opcode, const CastInst &CI) { + unsigned Op = getOrCreateVReg(*CI.getOperand(0)); + unsigned Res = getOrCreateVReg(CI); + MIRBuilder.buildInstr(Opcode, {LLT{*CI.getDestTy()}, LLT{*CI.getSrcTy()}}, + Res, Op); + return true; +} + bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) { assert(AI.isStaticAlloca() && "only handle static allocas now"); MachineFunction &MF = MIRBuilder.getMF(); @@ -138,6 +155,14 @@ bool IRTranslator::translate(const Instruction &Inst) { case Instruction::Ret: return translateReturn(Inst); + // Casts + case Instruction::BitCast: + return translateBitCast(cast<CastInst>(Inst)); + case Instruction::IntToPtr: + return translateCast(TargetOpcode::G_INTTOPTR, cast<CastInst>(Inst)); + case Instruction::PtrToInt: + return translateCast(TargetOpcode::G_PTRTOINT, cast<CastInst>(Inst)); + case Instruction::Alloca: return translateStaticAlloca(cast<AllocaInst>(Inst)); diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 2b91584c75d..f18467c4bb4 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -85,6 +85,18 @@ MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty, return NewMI; } +MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef<LLT> Tys, + unsigned Res, unsigned Op0) { + MachineInstr *NewMI = buildInstr(Opcode, Tys[0]); + for (unsigned i = 1; i < Tys.size(); ++i) + NewMI->setType(Tys[i], i); + + MachineInstrBuilder(getMF(), NewMI) + .addReg(Res, RegState::Define) + .addReg(Op0); + return NewMI; +} + MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res, unsigned Op0) { MachineInstr *NewMI = buildInstr(Opcode, LLT{}); diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp index f738385adcc..7946fc2676f 100644 --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -568,7 +568,7 @@ void MIPrinter::print(const MachineInstr &MI) { assert(MI.getType().isValid() && "Generic instructions must have a type"); OS << " { "; for (unsigned i = 0; i < MI.getNumTypes(); ++i) { - MI.getType().print(OS); + MI.getType(i).print(OS); if (i + 1 != MI.getNumTypes()) OS << ", "; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 032a527e3e7..2bcfc6c4a25 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -6,7 +6,7 @@ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" target triple = "aarch64-apple-ios" ; Tests for add. -; CHECK: name: addi64 +; CHECK-LABEL: name: addi64 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_ADD { s64 } [[ARG1]], [[ARG2]] @@ -18,7 +18,7 @@ define i64 @addi64(i64 %arg1, i64 %arg2) { } ; Tests for alloca -; CHECK: name: allocai64 +; CHECK-LABEL: name: allocai64 ; CHECK: stack: ; CHECK-NEXT: - { id: 0, name: ptr1, offset: 0, size: 8, alignment: 8 } ; CHECK-NEXT: - { id: 1, name: ptr2, offset: 0, size: 8, alignment: 1 } @@ -34,7 +34,7 @@ define void @allocai64() { } ; Tests for br. -; CHECK: name: uncondbr +; CHECK-LABEL: name: uncondbr ; CHECK: body: ; ; Entry basic block. @@ -56,7 +56,7 @@ end: } ; Tests for or. -; CHECK: name: ori64 +; CHECK-LABEL: name: ori64 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_OR { s64 } [[ARG1]], [[ARG2]] @@ -67,7 +67,7 @@ define i64 @ori64(i64 %arg1, i64 %arg2) { ret i64 %res } -; CHECK: name: ori32 +; CHECK-LABEL: name: ori32 ; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 ; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_OR { s32 } [[ARG1]], [[ARG2]] @@ -79,7 +79,7 @@ define i32 @ori32(i32 %arg1, i32 %arg2) { } ; Tests for and. -; CHECK: name: andi64 +; CHECK-LABEL: name: andi64 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_AND { s64 } [[ARG1]], [[ARG2]] @@ -90,7 +90,7 @@ define i64 @andi64(i64 %arg1, i64 %arg2) { ret i64 %res } -; CHECK: name: andi32 +; CHECK-LABEL: name: andi32 ; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 ; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_AND { s32 } [[ARG1]], [[ARG2]] @@ -102,7 +102,7 @@ define i32 @andi32(i32 %arg1, i32 %arg2) { } ; Tests for sub. -; CHECK: name: subi64 +; CHECK-LABEL: name: subi64 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1 ; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_SUB { s64 } [[ARG1]], [[ARG2]] @@ -113,7 +113,7 @@ define i64 @subi64(i64 %arg1, i64 %arg2) { ret i64 %res } -; CHECK: name: subi32 +; CHECK-LABEL: name: subi32 ; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0 ; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1 ; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_SUB { s32 } [[ARG1]], [[ARG2]] @@ -123,3 +123,45 @@ define i32 @subi32(i32 %arg1, i32 %arg2) { %res = sub i32 %arg1, %arg2 ret i32 %res } + +; CHECK-LABEL: name: ptrtoint +; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 +; CHECK: [[RES:%[0-9]+]](64) = G_PTRTOINT { s64, p0 } [[ARG1]] +; CHECK: %x0 = COPY [[RES]] +; CHECK: RET_ReallyLR implicit %x0 +define i64 @ptrtoint(i64* %a) { + %val = ptrtoint i64* %a to i64 + ret i64 %val +} + +; CHECK-LABEL: name: inttoptr +; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 +; CHECK: [[RES:%[0-9]+]](64) = G_INTTOPTR { p0, s64 } [[ARG1]] +; CHECK: %x0 = COPY [[RES]] +; CHECK: RET_ReallyLR implicit %x0 +define i64* @inttoptr(i64 %a) { + %val = inttoptr i64 %a to i64* + ret i64* %val +} + +; CHECK-LABEL: name: trivial_bitcast +; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 +; CHECK: [[RES:%[0-9]+]](64) = COPY [[ARG1]] +; CHECK: %x0 = COPY [[RES]] +; CHECK: RET_ReallyLR implicit %x0 +define i64* @trivial_bitcast(i8* %a) { + %val = bitcast i8* %a to i64* + ret i64* %val +} + +; CHECK-LABEL: name: bitcast +; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0 +; CHECK: [[RES1:%[0-9]+]](64) = G_BITCAST { <2 x s32>, s64 } [[ARG1]] +; CHECK: [[RES2:%[0-9]+]](64) = G_BITCAST { s64, <2 x s32> } [[RES1]] +; CHECK: %x0 = COPY [[RES2]] +; CHECK: RET_ReallyLR implicit %x0 +define i64 @bitcast(i64 %a) { + %res1 = bitcast i64 %a to <2 x i32> + %res2 = bitcast <2 x i32> %res1 to i64 + ret i64 %res2 +} |