From e07cd5e40ac06fabfb9d33ea7c79542f138f45ce Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Wed, 2 Nov 2011 18:08:25 +0000 Subject: Add support for comparing integer non-legal types. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143559 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 49 ++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 97d813da21..78bda6c0d3 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -174,7 +174,8 @@ class ARMFastISel : public FastISel { private: bool isTypeLegal(Type *Ty, MVT &VT); bool isLoadTypeLegal(Type *Ty, MVT &VT); - bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value); + bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value, + bool isZExt); bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr); bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr); bool ARMComputeAddress(const Value *Obj, Address &Addr); @@ -1119,7 +1120,7 @@ bool ARMFastISel::SelectBranch(const Instruction *I) { if (ARMPred == ARMCC::AL) return false; // Emit the compare. - if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1))) + if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned())) return false; unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc; @@ -1189,19 +1190,19 @@ bool ARMFastISel::SelectBranch(const Instruction *I) { return true; } -bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value) { - MVT VT; +bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value, + bool isZExt) { Type *Ty = Src1Value->getType(); - if (!isTypeLegal(Ty, VT)) - return false; + EVT SrcVT = TLI.getValueType(Ty, true); + if (!SrcVT.isSimple()) return false; bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy()); if (isFloat && !Subtarget->hasVFP2()) return false; unsigned CmpOpc; - switch (VT.SimpleTy) { - // TODO: Add support for non-legal types (i.e., i1, i8, i16). + bool needsExt = false; + switch (SrcVT.getSimpleVT().SimpleTy) { default: return false; // TODO: Verify compares. case MVT::f32: @@ -1210,19 +1211,36 @@ bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value) { case MVT::f64: CmpOpc = ARM::VCMPED; break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + needsExt = true; + // Intentional fall-through. case MVT::i32: CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr; break; } - unsigned Src1 = getRegForValue(Src1Value); - if (Src1 == 0) return false; - - unsigned Src2 = getRegForValue(Src2Value); - if (Src2 == 0) return false; + unsigned SrcReg1 = getRegForValue(Src1Value); + if (SrcReg1 == 0) return false; + + unsigned SrcReg2 = getRegForValue(Src2Value); + if (SrcReg2 == 0) return false; + + // We have i1, i8, or i16, we need to either zero extend or sign extend. + if (needsExt) { + unsigned ResultReg; + EVT DestVT = MVT::i32; + ResultReg = ARMEmitIntExt(SrcVT, SrcReg1, DestVT, isZExt); + if (ResultReg == 0) return false; + SrcReg1 = ResultReg; + ResultReg = ARMEmitIntExt(SrcVT, SrcReg2, DestVT, isZExt); + if (ResultReg == 0) return false; + SrcReg2 = ResultReg; + } AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc)) - .addReg(Src1).addReg(Src2)); + .addReg(SrcReg1).addReg(SrcReg2)); // For floating point we need to move the result to a comparison register // that we can then use for branches. @@ -1243,7 +1261,7 @@ bool ARMFastISel::SelectCmp(const Instruction *I) { if (ARMPred == ARMCC::AL) return false; // Emit the compare. - if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1))) + if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned())) return false; // Now set a register based on the comparison. Explicitly set the predicates @@ -1962,7 +1980,6 @@ bool ARMFastISel::SelectCall(const Instruction *I) { static_cast(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI); return true; - } bool ARMFastISel::SelectTrunc(const Instruction *I) { -- cgit v1.2.3