diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 5fe5a76ca45..2d282809c9d 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -456,6 +456,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT, Expand); } + setOperationAction(ISD::ConstantFP, MVT::f32, Custom); + if (Subtarget->hasNEON()) { addDRTypeForNEON(MVT::v2f32); addDRTypeForNEON(MVT::v8i8); @@ -3673,6 +3675,27 @@ static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) { return Result; } +SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG, + const ARMSubtarget *ST) const { + if (!ST->useNEONForSinglePrecisionFP() || !ST->hasVFP3() || ST->hasD16()) + return SDValue(); + + ConstantFPSDNode *CFP = cast(Op); + assert(Op.getValueType() == MVT::f32 && + "ConstantFP custom lowering should only occur for f32."); + + APFloat FPVal = CFP->getValueAPF(); + int ImmVal = ARM_AM::getFP32Imm(FPVal); + if (ImmVal == -1) + return SDValue(); + + DebugLoc DL = Op.getDebugLoc(); + SDValue NewVal = DAG.getTargetConstant(ImmVal, MVT::i32); + SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32, NewVal); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant, + DAG.getConstant(0, MVT::i32)); +} + /// isNEONModifiedImm - Check if the specified splat value corresponds to a /// valid vector constant for a NEON instruction with a "modified immediate" /// operand (e.g., VMOV). If so, return the encoded value. @@ -5109,6 +5132,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG); case ISD::CTTZ: return LowerCTTZ(Op.getNode(), DAG, Subtarget); case ISD::SETCC: return LowerVSETCC(Op, DAG); + case ISD::ConstantFP: return LowerConstantFP(Op, DAG, Subtarget); case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget); case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG); diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 7f122935260..b46abda94b6 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -434,6 +434,8 @@ namespace llvm { SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG, + const ARMSubtarget *ST) const; SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST) const; diff --git a/test/CodeGen/ARM/2009-11-07-SubRegAsmPrinting.ll b/test/CodeGen/ARM/2009-11-07-SubRegAsmPrinting.ll index 7aae3acd76e..a8afc20bc13 100644 --- a/test/CodeGen/ARM/2009-11-07-SubRegAsmPrinting.ll +++ b/test/CodeGen/ARM/2009-11-07-SubRegAsmPrinting.ll @@ -1,4 +1,4 @@ -; RUN: llc -mcpu=cortex-a8 < %s | FileCheck %s +; RUN: llc -mcpu=cortex-a8 -mattr=-neonfp < %s | FileCheck %s ; PR5423 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64" diff --git a/test/CodeGen/ARM/2010-12-07-PEIBug.ll b/test/CodeGen/ARM/2010-12-07-PEIBug.ll index 23e1aa15a88..770ad4466af 100644 --- a/test/CodeGen/ARM/2010-12-07-PEIBug.ll +++ b/test/CodeGen/ARM/2010-12-07-PEIBug.ll @@ -4,36 +4,12 @@ define hidden void @foo() nounwind ssp { entry: ; CHECK: foo: -; CHECK: push {r7, lr} -; CHECK-NEXT: mov r7, sp +; CHECK: mov r7, sp ; CHECK-NEXT: vpush {d8} ; CHECK-NEXT: vpush {d10, d11} - %tmp40 = load <4 x i8>* undef - %tmp41 = extractelement <4 x i8> %tmp40, i32 2 - %conv42 = zext i8 %tmp41 to i32 - %conv43 = sitofp i32 %conv42 to float - %div44 = fdiv float %conv43, 2.560000e+02 - %vecinit45 = insertelement <4 x float> undef, float %div44, i32 2 - %vecinit46 = insertelement <4 x float> %vecinit45, float 1.000000e+00, i32 3 - store <4 x float> %vecinit46, <4 x float>* undef - br i1 undef, label %if.then105, label %if.else109 - -if.then105: ; preds = %entry - br label %if.end114 - -if.else109: ; preds = %entry - br label %if.end114 - -if.end114: ; preds = %if.else109, %if.then105 - %call185 = call float @bar() - %vecinit186 = insertelement <4 x float> undef, float %call185, i32 1 - %call189 = call float @bar() - %vecinit190 = insertelement <4 x float> %vecinit186, float %call189, i32 2 - %vecinit191 = insertelement <4 x float> %vecinit190, float 1.000000e+00, i32 3 - store <4 x float> %vecinit191, <4 x float>* undef + tail call void asm sideeffect "","~{d8},~{d10},~{d11}"() nounwind ; CHECK: vpop {d10, d11} ; CHECK-NEXT: vpop {d8} -; CHECK-NEXT: pop {r7, pc} ret void }