Handle x86 truncate to i8 with target hook for now.
authorEvan Cheng <evan.cheng@apple.com>
Sun, 7 Sep 2008 08:47:42 +0000 (08:47 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Sun, 7 Sep 2008 08:47:42 +0000 (08:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55877 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FastISel.cpp
test/CodeGen/X86/fast-isel-trunc.ll [new file with mode: 0644]

index 211afd5fc87bdc008880188ab047a72aa0602900..ff8ce88f1f40f04365e0ed7c6bc962763b8ea6b0 100644 (file)
@@ -65,6 +65,8 @@ private:
 
   bool X86SelectSelect(Instruction *I);
 
+  bool X86SelectTrunc(Instruction *I);
+
   unsigned TargetMaterializeConstant(Constant *C, MachineConstantPool* MCP);
 };
 
@@ -557,6 +559,40 @@ bool X86FastISel::X86SelectSelect(Instruction *I) {
   return true;
 }
 
+bool X86FastISel::X86SelectTrunc(Instruction *I) {
+  if (Subtarget->is64Bit())
+    // All other cases should be handled by the tblgen generated code.
+    return false;
+  MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
+  MVT DstVT = TLI.getValueType(I->getType());
+  if (DstVT != MVT::i8)
+    // All other cases should be handled by the tblgen generated code.
+    return false;
+  if (SrcVT != MVT::i16 && SrcVT != MVT::i32)
+    // All other cases should be handled by the tblgen generated code.
+    return false;
+
+  unsigned InputReg = getRegForValue(I->getOperand(0));
+  if (!InputReg)
+    // Unhandled operand.  Halt "fast" selection and bail.
+    return false;
+
+  // First issue a copy to GR16_ or GR32_.
+  unsigned CopyOpc = (SrcVT == MVT::i16) ? X86::MOV16to16_ : X86::MOV32to32_;
+  const TargetRegisterClass *CopyRC = (SrcVT == MVT::i16)
+    ? X86::GR16_RegisterClass : X86::GR32_RegisterClass;
+  unsigned CopyReg = createResultReg(CopyRC);
+  BuildMI(MBB, TII.get(CopyOpc), CopyReg).addReg(InputReg);
+
+  // Then issue an extract_subreg.
+  unsigned ResultReg = FastEmitInst_extractsubreg(CopyReg,1); // x86_subreg_8bit
+  if (!ResultReg)
+    return false;
+
+  UpdateValueMap(I, ResultReg);
+  return true;
+}
+
 bool
 X86FastISel::TargetSelectInstruction(Instruction *I)  {
   switch (I->getOpcode()) {
@@ -578,6 +614,8 @@ X86FastISel::TargetSelectInstruction(Instruction *I)  {
     return X86SelectShift(I);
   case Instruction::Select:
     return X86SelectSelect(I);
+  case Instruction::Trunc:
+    return X86SelectTrunc(I);
   }
 
   return false;
diff --git a/test/CodeGen/X86/fast-isel-trunc.ll b/test/CodeGen/X86/fast-isel-trunc.ll
new file mode 100644 (file)
index 0000000..f70ff1c
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -march=x86 -fast-isel
+; RUN: llvm-as < %s | llc -march=x86-64 -fast-isel
+
+define i8 @t1(i32 %x) signext nounwind  {
+       %tmp1 = trunc i32 %x to i8
+       ret i8 %tmp1
+}
+
+define i8 @t2(i16 signext %x) signext nounwind  {
+       %tmp1 = trunc i16 %x to i8
+       ret i8 %tmp1
+}