[llvm] r276690 - GlobalISel: add generic casts to IRTranslator

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 25 14:01:29 PDT 2016


Author: tnorthover
Date: Mon Jul 25 16:01:29 2016
New Revision: 276690

URL: http://llvm.org/viewvc/llvm-project?rev=276690&view=rev
Log:
GlobalISel: add generic casts to IRTranslator

This adds LLVM's 3 main cast instructions (inttoptr, ptrtoint, bitcast) to the
IRTranslator. The first two are direct translations (with 2 MachineInstr types
each). Since LLT discards information, a bitcast might become trivial and we
emit a COPY in those cases instead.

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
    llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
    llvm/trunk/include/llvm/Target/GenericOpcodes.td
    llvm/trunk/include/llvm/Target/TargetOpcodes.def
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Mon Jul 25 16:01:29 2016
@@ -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);

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Mon Jul 25 16:01:29 2016
@@ -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.
   ///

Modified: llvm/trunk/include/llvm/Target/GenericOpcodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/GenericOpcodes.td?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/GenericOpcodes.td (original)
+++ llvm/trunk/include/llvm/Target/GenericOpcodes.td Mon Jul 25 16:01:29 2016
@@ -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.
 //------------------------------------------------------------------------------

Modified: llvm/trunk/include/llvm/Target/TargetOpcodes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOpcodes.def?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetOpcodes.def (original)
+++ llvm/trunk/include/llvm/Target/TargetOpcodes.def Mon Jul 25 16:01:29 2016
@@ -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)
 

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Mon Jul 25 16:01:29 2016
@@ -100,6 +100,23 @@ bool IRTranslator::translateBr(const Ins
   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 Instr
   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));
 

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Mon Jul 25 16:01:29 2016
@@ -85,6 +85,18 @@ MachineInstr *MachineIRBuilder::buildIns
   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{});

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Mon Jul 25 16:01:29 2016
@@ -568,7 +568,7 @@ void MIPrinter::print(const MachineInstr
     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 <<  ", ";
     }

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll?rev=276690&r1=276689&r2=276690&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Mon Jul 25 16:01:29 2016
@@ -6,7 +6,7 @@ target datalayout = "e-m:o-i64:64-i128:1
 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
+}




More information about the llvm-commits mailing list