Improve FastISel's handling of truncates to i1, and implement
authorDan Gohman <gohman@apple.com>
Fri, 13 Mar 2009 23:53:06 +0000 (23:53 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 13 Mar 2009 23:53:06 +0000 (23:53 +0000)
ptrtoint and inttoptr in X86FastISel. These casts aren't always
handled in the generic FastISel code because X86 sometimes needs
custom code to do truncation and zero-extension.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66988 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/FastISel.cpp
lib/Target/X86/X86FastISel.cpp
test/CodeGen/X86/fast-isel-phys.ll
test/CodeGen/X86/fast-isel-trunc.ll
test/CodeGen/X86/fast-isel.ll

index 3523dda97eaf02824817bcfb005268a44387ddee..6f09f794ea4df45451507457f432835fccc845ce 100644 (file)
@@ -477,33 +477,41 @@ bool FastISel::SelectCast(User *I, ISD::NodeType Opcode) {
   MVT DstVT = TLI.getValueType(I->getType());
     
   if (SrcVT == MVT::Other || !SrcVT.isSimple() ||
-      DstVT == MVT::Other || !DstVT.isSimple() ||
-      !TLI.isTypeLegal(DstVT))
+      DstVT == MVT::Other || !DstVT.isSimple())
     // Unhandled type. Halt "fast" selection and bail.
     return false;
     
+  // Check if the destination type is legal. Or as a special case,
+  // it may be i1 if we're doing a truncate because that's
+  // easy and somewhat common.
+  if (!TLI.isTypeLegal(DstVT))
+    if (DstVT != MVT::i1 || Opcode != ISD::TRUNCATE)
+      // Unhandled type. Halt "fast" selection and bail.
+      return false;
+
   // Check if the source operand is legal. Or as a special case,
   // it may be i1 if we're doing zero-extension because that's
-  // trivially easy and somewhat common.
-  if (!TLI.isTypeLegal(SrcVT)) {
-    if (SrcVT == MVT::i1 && Opcode == ISD::ZERO_EXTEND)
-      SrcVT = TLI.getTypeToTransformTo(SrcVT);
-    else
+  // easy and somewhat common.
+  if (!TLI.isTypeLegal(SrcVT))
+    if (SrcVT != MVT::i1 || Opcode != ISD::ZERO_EXTEND)
       // Unhandled type. Halt "fast" selection and bail.
       return false;
-  }
-    
+
   unsigned InputReg = getRegForValue(I->getOperand(0));
   if (!InputReg)
     // Unhandled operand.  Halt "fast" selection and bail.
     return false;
 
   // If the operand is i1, arrange for the high bits in the register to be zero.
-  if (I->getOperand(0)->getType() == Type::Int1Ty) {
+  if (SrcVT == MVT::i1) {
+   SrcVT = TLI.getTypeToTransformTo(SrcVT);
    InputReg = FastEmitZExtFromI1(SrcVT.getSimpleVT(), InputReg);
    if (!InputReg)
      return false;
   }
+  // If the result is i1, truncate to the target's type for i1 first.
+  if (DstVT == MVT::i1)
+    DstVT = TLI.getTypeToTransformTo(DstVT);
 
   unsigned ResultReg = FastEmit_r(SrcVT.getSimpleVT(),
                                   DstVT.getSimpleVT(),
index 50f1935dcdbc0d7e9909768a71d3fe9a76b9133c..7a10b123bc42f4ffc1c865aedefa30ad3d461655 100644 (file)
@@ -1413,6 +1413,19 @@ X86FastISel::TargetSelectInstruction(Instruction *I)  {
     return X86SelectFPTrunc(I);
   case Instruction::ExtractValue:
     return X86SelectExtractValue(I);
+  case Instruction::IntToPtr: // Deliberate fall-through.
+  case Instruction::PtrToInt: {
+    MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
+    MVT DstVT = TLI.getValueType(I->getType());
+    if (DstVT.bitsGT(SrcVT))
+      return X86SelectZExt(I);
+    if (DstVT.bitsLT(SrcVT))
+      return X86SelectTrunc(I);
+    unsigned Reg = getRegForValue(I->getOperand(0));
+    if (Reg == 0) return false;
+    UpdateValueMap(I, Reg);
+    return true;
+  }
   }
 
   return false;
index 26011468f78dd47aa31ebb454dc05d717cad88f2..91dcca57cc2b713a45cba7cff61a409df65e43e5 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -fast-isel -march=x86
+; RUN: llvm-as < %s | llc -fast-isel -fast-isel-abort -march=x86
 
 define i8 @t2(i8 %a, i8 %c) nounwind {
        %tmp = shl i8 %a, %c
index f70ff1c41960724335cc12d276c688921f67baf9..039f114737bb1c352586d169e831a35d29aa6fc2 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llvm-as < %s | llc -march=x86 -fast-isel
-; RUN: llvm-as < %s | llc -march=x86-64 -fast-isel
+; RUN: llvm-as < %s | llc -march=x86 -fast-isel -fast-isel-abort
+; RUN: llvm-as < %s | llc -march=x86-64 -fast-isel -fast-isel-abort
 
 define i8 @t1(i32 %x) signext nounwind  {
        %tmp1 = trunc i32 %x to i8
index 9910629211e5689bc0aa63eb2629e141ac839827..cd1e516ac89260434c240b348b1454cfdb28ec69 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -fast-isel -march=x86 -mattr=sse2
+; RUN: llvm-as < %s | llc -fast-isel -fast-isel-abort -march=x86 -mattr=sse2
 
 ; This tests very minimal fast-isel functionality.
 
@@ -47,3 +47,12 @@ entry:
        %tmp2 = bitcast i32 0 to i32
        ret i32 %tmp2
 }
+
+define i1 @ptrtoint(i8* %p) nounwind {
+  %t = ptrtoint i8* %p to i1
+  ret i1 %t
+}
+define i8* @inttoptr(i1 %p) nounwind {
+  %t = inttoptr i1 %p to i8*
+  ret i8* %t
+}