[llvm] r278303 - GlobalISel: support same ConstantExprs as Instructions.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 10 16:02:41 PDT 2016


Author: tnorthover
Date: Wed Aug 10 18:02:41 2016
New Revision: 278303

URL: http://llvm.org/viewvc/llvm-project?rev=278303&view=rev
Log:
GlobalISel: support same ConstantExprs as Instructions.

It's more than just inttoptr, but the others can't be tested until we have
support for non-trivial constants (they currently get unavoidably folded to a
ConstantInt).

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.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=278303&r1=278302&r2=278303&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Wed Aug 10 18:02:41 2016
@@ -109,47 +109,128 @@ private:
 
   /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is
   /// emitted.
-  bool translateBitCast(const CastInst &CI);
+  bool translateBitCast(const User &U);
 
   /// Translate an LLVM load instruction into generic IR.
-  bool translateLoad(const LoadInst &LI);
+  bool translateLoad(const User &U);
 
   /// Translate an LLVM store instruction into generic IR.
-  bool translateStore(const StoreInst &SI);
+  bool translateStore(const User &U);
 
   /// Translate call instruction.
-  /// \pre \p Inst is a call instruction.
-  bool translateCall(const CallInst &Inst);
+  /// \pre \p U is a call instruction.
+  bool translateCall(const User &U);
 
   /// Translate one of LLVM's cast instructions into MachineInstrs, with the
   /// given generic Opcode.
-  bool translateCast(unsigned Opcode, const CastInst &CI);
+  bool translateCast(unsigned Opcode, const User &U);
 
   /// Translate static alloca instruction (i.e. one  of constant size and in the
   /// first basic block).
   bool translateStaticAlloca(const AllocaInst &Inst);
 
   /// Translate a phi instruction.
-  bool translatePhi(const PHINode &PI);
+  bool translatePHI(const User &U);
 
   /// Add remaining operands onto phis we've translated. Executed after all
   /// MachineBasicBlocks for the function have been created.
   void finishPendingPhis();
 
   /// Translate \p Inst into a binary operation \p Opcode.
-  /// \pre \p Inst is a binary operation.
-  bool translateBinaryOp(unsigned Opcode, const BinaryOperator &Inst);
+  /// \pre \p U is a binary operation.
+  bool translateBinaryOp(unsigned Opcode, const User &U);
 
   /// Translate branch (br) instruction.
-  /// \pre \p Inst is a branch instruction.
-  bool translateBr(const BranchInst &Inst);
+  /// \pre \p U is a branch instruction.
+  bool translateBr(const User &U);
 
+  bool translateAdd(const User &U) {
+    return translateBinaryOp(TargetOpcode::G_ADD, U);
+  }
+  bool translateSub(const User &U) {
+    return translateBinaryOp(TargetOpcode::G_SUB, U);
+  }
+  bool translateAnd(const User &U) {
+    return translateBinaryOp(TargetOpcode::G_AND, U);
+  }
+  bool translateMul(const User &U) {
+    return translateBinaryOp(TargetOpcode::G_MUL, U);
+  }
+  bool translateOr(const User &U) {
+    return translateBinaryOp(TargetOpcode::G_OR, U);
+  }
+  bool translateXor(const User &U) {
+    return translateBinaryOp(TargetOpcode::G_XOR, U);
+  }
+  bool translateAlloca(const User &U) {
+    return translateStaticAlloca(cast<AllocaInst>(U));
+  }
+  bool translateIntToPtr(const User &U) {
+    return translateCast(TargetOpcode::G_INTTOPTR, U);
+  }
+  bool translatePtrToInt(const User &U) {
+    return translateCast(TargetOpcode::G_PTRTOINT, U);
+  }
+  bool translateTrunc(const User &U) {
+    return translateCast(TargetOpcode::G_TRUNC, U);
+  }
+  bool translateUnreachable(const User &U) { return true; }
 
   /// Translate return (ret) instruction.
   /// The target needs to implement CallLowering::lowerReturn for
   /// this to succeed.
-  /// \pre \p Inst is a return instruction.
-  bool translateReturn(const ReturnInst &Inst);
+  /// \pre \p U is a return instruction.
+  bool translateRet(const User &U);
+
+  // Stubs to keep the compiler happy while we implement the rest of the
+  // translation.
+  bool translateSwitch(const User &U) { return false; }
+  bool translateIndirectBr(const User &U) { return false; }
+  bool translateInvoke(const User &U) { return false; }
+  bool translateResume(const User &U) { return false; }
+  bool translateCleanupRet(const User &U) { return false; }
+  bool translateCatchRet(const User &U) { return false; }
+  bool translateCatchSwitch(const User &U) { return false; }
+  bool translateFAdd(const User &U) { return false; }
+  bool translateFSub(const User &U) { return false; }
+  bool translateFMul(const User &U) { return false; }
+  bool translateUDiv(const User &U) { return false; }
+  bool translateSDiv(const User &U) { return false; }
+  bool translateFDiv(const User &U) { return false; }
+  bool translateURem(const User &U) { return false; }
+  bool translateSRem(const User &U) { return false; }
+  bool translateFRem(const User &U) { return false; }
+  bool translateShl(const User &U) { return false; }
+  bool translateLShr(const User &U) { return false; }
+  bool translateAShr(const User &U) { return false; }
+  bool translateGetElementPtr(const User &U) { return false; }
+  bool translateFence(const User &U) { return false; }
+  bool translateAtomicCmpXchg(const User &U) { return false; }
+  bool translateAtomicRMW(const User &U) { return false; }
+  bool translateSExt(const User &U) { return false; }
+  bool translateZExt(const User &U) { return false; }
+  bool translateFPToUI(const User &U) { return false; }
+  bool translateFPToSI(const User &U) { return false; }
+  bool translateUIToFP(const User &U) { return false; }
+  bool translateSIToFP(const User &U) { return false; }
+  bool translateFPTrunc(const User &U) { return false; }
+  bool translateFPExt(const User &U) { return false; }
+  bool translateAddrSpaceCast(const User &U) { return false; }
+  bool translateCleanupPad(const User &U) { return false; }
+  bool translateCatchPad(const User &U) { return false; }
+  bool translateICmp(const User &U) { return false; }
+  bool translateFCmp(const User &U) { return false; }
+  bool translateSelect(const User &U) { return false; }
+  bool translateUserOp1(const User &U) { return false; }
+  bool translateUserOp2(const User &U) { return false; }
+  bool translateVAArg(const User &U) { return false; }
+  bool translateExtractElement(const User &U) { return false; }
+  bool translateInsertElement(const User &U) { return false; }
+  bool translateShuffleVector(const User &U) { return false; }
+  bool translateExtractValue(const User &U) { return false; }
+  bool translateInsertValue(const User &U) { return false; }
+  bool translateLandingPad(const User &U) { return false; }
+
   /// @}
 
   // Builder for machine instruction a la IRBuilder.

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=278303&r1=278302&r2=278303&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Wed Aug 10 18:02:41 2016
@@ -84,25 +84,25 @@ MachineBasicBlock &IRTranslator::getOrCr
   return *MBB;
 }
 
-bool IRTranslator::translateBinaryOp(unsigned Opcode,
-                                     const BinaryOperator &Inst) {
+bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U) {
   // FIXME: handle signed/unsigned wrapping flags.
 
   // Get or create a virtual register for each value.
   // Unless the value is a Constant => loadimm cst?
   // or inline constant each time?
   // Creation of a virtual register needs to have a size.
-  unsigned Op0 = getOrCreateVReg(*Inst.getOperand(0));
-  unsigned Op1 = getOrCreateVReg(*Inst.getOperand(1));
-  unsigned Res = getOrCreateVReg(Inst);
-  MIRBuilder.buildInstr(Opcode, LLT{*Inst.getType()})
+  unsigned Op0 = getOrCreateVReg(*U.getOperand(0));
+  unsigned Op1 = getOrCreateVReg(*U.getOperand(1));
+  unsigned Res = getOrCreateVReg(U);
+  MIRBuilder.buildInstr(Opcode, LLT{*U.getType()})
       .addDef(Res)
       .addUse(Op0)
       .addUse(Op1);
   return true;
 }
 
-bool IRTranslator::translateReturn(const ReturnInst &RI) {
+bool IRTranslator::translateRet(const User &U) {
+  const ReturnInst &RI = cast<ReturnInst>(U);
   const Value *Ret = RI.getReturnValue();
   // The target may mess up with the insertion point, but
   // this is not important as a return is the last instruction
@@ -110,7 +110,8 @@ bool IRTranslator::translateReturn(const
   return CLI->lowerReturn(MIRBuilder, Ret, !Ret ? 0 : getOrCreateVReg(*Ret));
 }
 
-bool IRTranslator::translateBr(const BranchInst &BrInst) {
+bool IRTranslator::translateBr(const User &U) {
+  const BranchInst &BrInst = cast<BranchInst>(U);
   unsigned Succ = 0;
   if (!BrInst.isUnconditional()) {
     // We want a G_BRCOND to the true BB followed by an unconditional branch.
@@ -131,7 +132,8 @@ bool IRTranslator::translateBr(const Bra
   return true;
 }
 
-bool IRTranslator::translateLoad(const LoadInst &LI) {
+bool IRTranslator::translateLoad(const User &U) {
+  const LoadInst &LI = cast<LoadInst>(U);
   assert(LI.isSimple() && "only simple loads are supported at the moment");
 
   MachineFunction &MF = MIRBuilder.getMF();
@@ -147,7 +149,8 @@ bool IRTranslator::translateLoad(const L
   return true;
 }
 
-bool IRTranslator::translateStore(const StoreInst &SI) {
+bool IRTranslator::translateStore(const User &U) {
+  const StoreInst &SI = cast<StoreInst>(U);
   assert(SI.isSimple() && "only simple loads are supported at the moment");
 
   MachineFunction &MF = MIRBuilder.getMF();
@@ -164,28 +167,30 @@ bool IRTranslator::translateStore(const
   return true;
 }
 
-bool IRTranslator::translateBitCast(const CastInst &CI) {
-  if (LLT{*CI.getDestTy()} == LLT{*CI.getSrcTy()}) {
-    unsigned &Reg = ValToVReg[&CI];
+bool IRTranslator::translateBitCast(const User &U) {
+  if (LLT{*U.getOperand(0)->getType()} == LLT{*U.getType()}) {
+    unsigned &Reg = ValToVReg[&U];
     if (Reg)
-      MIRBuilder.buildCopy(Reg, getOrCreateVReg(*CI.getOperand(0)));
+      MIRBuilder.buildCopy(Reg, getOrCreateVReg(*U.getOperand(0)));
     else
-      Reg = getOrCreateVReg(*CI.getOperand(0));
+      Reg = getOrCreateVReg(*U.getOperand(0));
     return true;
   }
-  return translateCast(TargetOpcode::G_BITCAST, CI);
+  return translateCast(TargetOpcode::G_BITCAST, U);
 }
 
-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()}})
+bool IRTranslator::translateCast(unsigned Opcode, const User &U) {
+  unsigned Op = getOrCreateVReg(*U.getOperand(0));
+  unsigned Res = getOrCreateVReg(U);
+  MIRBuilder
+      .buildInstr(Opcode, {LLT{*U.getType()}, LLT{*U.getOperand(0)->getType()}})
       .addDef(Res)
       .addUse(Op);
   return true;
 }
 
-bool IRTranslator::translateCall(const CallInst &CI) {
+bool IRTranslator::translateCall(const User &U) {
+  const CallInst &CI = cast<CallInst>(U);
   auto TII = MIRBuilder.getMF().getTarget().getIntrinsicInfo();
   const Function *F = CI.getCalledFunction();
 
@@ -246,7 +251,8 @@ bool IRTranslator::translateStaticAlloca
   return true;
 }
 
-bool IRTranslator::translatePhi(const PHINode &PI) {
+bool IRTranslator::translatePHI(const User &U) {
+  const PHINode &PI = cast<PHINode>(U);
   MachineInstrBuilder MIB = MIRBuilder.buildInstr(TargetOpcode::PHI);
   MIB.addDef(getOrCreateVReg(PI));
 
@@ -277,59 +283,11 @@ void IRTranslator::finishPendingPhis() {
 bool IRTranslator::translate(const Instruction &Inst) {
   MIRBuilder.setDebugLoc(Inst.getDebugLoc());
   switch(Inst.getOpcode()) {
-  // Arithmetic operations.
-  case Instruction::Add:
-    return translateBinaryOp(TargetOpcode::G_ADD, cast<BinaryOperator>(Inst));
-  case Instruction::Sub:
-    return translateBinaryOp(TargetOpcode::G_SUB, cast<BinaryOperator>(Inst));
-
-  // Bitwise operations.
-  case Instruction::And:
-    return translateBinaryOp(TargetOpcode::G_AND, cast<BinaryOperator>(Inst));
-  case Instruction::Mul:
-    return translateBinaryOp(TargetOpcode::G_MUL, cast<BinaryOperator>(Inst));
-  case Instruction::Or:
-    return translateBinaryOp(TargetOpcode::G_OR, cast<BinaryOperator>(Inst));
-  case Instruction::Xor:
-    return translateBinaryOp(TargetOpcode::G_XOR, cast<BinaryOperator>(Inst));
-
-  // Branch operations.
-  case Instruction::Br:
-    return translateBr(cast<BranchInst>(Inst));
-  case Instruction::Ret:
-    return translateReturn(cast<ReturnInst>(Inst));
-
-  // Calls
-  case Instruction::Call:
-    return translateCall(cast<CallInst>(Inst));
-
-  // Casts and allied operations
-  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::Trunc:
-    return translateCast(TargetOpcode::G_TRUNC, cast<CastInst>(Inst));
-
-  // Memory ops.
-  case Instruction::Load:
-    return translateLoad(cast<LoadInst>(Inst));
-  case Instruction::Store:
-    return translateStore(cast<StoreInst>(Inst));
-
-  case Instruction::Alloca:
-    return translateStaticAlloca(cast<AllocaInst>(Inst));
-
-  case Instruction::PHI:
-    return translatePhi(cast<PHINode>(Inst));
-
-  case Instruction::Unreachable:
-    return true;
-
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+    case Instruction::OPCODE: return translate##OPCODE(Inst);
+#include "llvm/IR/Instruction.def"
   default:
-    llvm_unreachable("Opcode not supported");
+    llvm_unreachable("unknown opcode");
   }
 }
 
@@ -338,7 +296,15 @@ bool IRTranslator::translate(const Const
     EntryBuilder.buildConstant(LLT{*CI->getType()}, Reg, CI->getZExtValue());
   else if (isa<UndefValue>(C))
     EntryBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF).addDef(Reg);
-  else
+  else if (auto CE = dyn_cast<ConstantExpr>(&C)) {
+    switch(CE->getOpcode()) {
+#define HANDLE_INST(NUM, OPCODE, CLASS)                         \
+      case Instruction::OPCODE: return translate##OPCODE(*CE);
+#include "llvm/IR/Instruction.def"
+    default:
+      llvm_unreachable("unknown opcode");
+    }
+  } else
     llvm_unreachable("unhandled constant kind");
 
   return true;

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=278303&r1=278302&r2=278303&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Wed Aug 10 18:02:41 2016
@@ -389,3 +389,11 @@ define i32 @constant_int_start() {
 define i32 @test_undef() {
   ret i32 undef
 }
+
+; CHECK-LABEL: name: test_constant_inttoptr
+; CHECK: [[ONE:%[0-9]+]](64) = G_CONSTANT s64 1
+; CHECK: [[PTR:%[0-9]+]](64) = G_INTTOPTR { p0, s64 } [[ONE]]
+; CHECK: %x0 = COPY [[PTR]]
+define i8* @test_constant_inttoptr() {
+  ret i8* inttoptr(i64 1 to i8*)
+}




More information about the llvm-commits mailing list