diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 3523dda97ea..6f09f794ea4 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -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 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 + // 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 + // 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(), diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 50f1935dcdb..7a10b123bc4 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -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; diff --git a/test/CodeGen/X86/fast-isel-phys.ll b/test/CodeGen/X86/fast-isel-phys.ll index 26011468f78..91dcca57cc2 100644 --- a/test/CodeGen/X86/fast-isel-phys.ll +++ b/test/CodeGen/X86/fast-isel-phys.ll @@ -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 diff --git a/test/CodeGen/X86/fast-isel-trunc.ll b/test/CodeGen/X86/fast-isel-trunc.ll index f70ff1c4196..039f114737b 100644 --- a/test/CodeGen/X86/fast-isel-trunc.ll +++ b/test/CodeGen/X86/fast-isel-trunc.ll @@ -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 diff --git a/test/CodeGen/X86/fast-isel.ll b/test/CodeGen/X86/fast-isel.ll index 9910629211e..cd1e516ac89 100644 --- a/test/CodeGen/X86/fast-isel.ll +++ b/test/CodeGen/X86/fast-isel.ll @@ -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 +}