Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -13633,6 +13633,27 @@ Known.One &= Mask; return; } + case ARMISD::VGETLANEs: + case ARMISD::VGETLANEu: { + const SDValue &SrcSV = Op.getOperand(0); + Known = DAG.computeKnownBits(SrcSV, Depth + 1); + EVT VT = Op.getValueType(); + EVT EltVT = SrcSV.getValueType(); + const unsigned DstSz = VT.getScalarSizeInBits(); + const unsigned SrcSz = EltVT.getVectorElementType().getSizeInBits(); + + assert(SrcSz == Known.getBitWidth()); + if (DstSz > SrcSz) { + if (Op.getOpcode() == ARMISD::VGETLANEs) + Known = Known.sext(DstSz); + else { + Known = Known.zext(DstSz); + Known.Zero.setBitsFrom(SrcSz); + } + } + break; + } + assert(DstSz == Known.getBitWidth()); } } Index: test/CodeGen/ARM/dagcombine-anyexttozeroext.ll =================================================================== --- test/CodeGen/ARM/dagcombine-anyexttozeroext.ll +++ test/CodeGen/ARM/dagcombine-anyexttozeroext.ll @@ -21,19 +21,19 @@ ; CHECK-LABEL: g: define float @g(<4 x i16>* nocapture %in) { - ; CHECK: vldr +; CHECK: vldr d16, [r0] %1 = load <4 x i16>, <4 x i16>* %in - ; For now we're generating a vmov.16 and a uxth instruction. - ; The uxth is redundant, and we should be able to extend without - ; having to generate cross-domain copies. Once we can do this - ; we should modify the checks below. - - ; CHECK: uxth + ; FIXME: We should be able to extend without + ; having to generate cross-domain copies. +; CHECK-NEXT: vmov.u16 r0, d16[0] +; CHECK-NEXT: vmov s0, r0 %2 = extractelement <4 x i16> %1, i32 0 - ; CHECK: vcvt.f32.u32 +; CHECK-NEXT: vcvt.f32.u32 s0, s0 %3 = uitofp i16 %2 to float ret float %3 +; CHECK-NEXT: vmov r0, s0 +; CHECK-NEXT: bx lr } ; Make sure we generate zext from <4 x i8> to <4 x 32>.