Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7684,6 +7684,7 @@ /// Fold a floating-point multiply by power of two into floating-point to /// fixed-point conversion. static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG, + TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget) { if (!Subtarget->hasNEON()) return SDValue(); @@ -7727,10 +7728,16 @@ ResTy = FloatBits == 32 ? MVT::v2i32 : MVT::v2i64; break; case 4: - ResTy = MVT::v4i32; + ResTy = FloatBits == 32 ? MVT::v4i32 : MVT::v4i64; break; } + if (ResTy == MVT::v4i64 && DCI.isBeforeLegalizeOps()) + return SDValue(); + + assert((ResTy != MVT::v4i64 || DCI.isBeforeLegalizeOps()) && + "Illegal vector type after legalization"); + SDLoc DL(N); bool IsSigned = N->getOpcode() == ISD::FP_TO_SINT; unsigned IntrinsicOpcode = IsSigned ? Intrinsic::aarch64_neon_vcvtfp2fxs @@ -9852,7 +9859,7 @@ return performIntToFpCombine(N, DAG, Subtarget); case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: - return performFpToIntCombine(N, DAG, Subtarget); + return performFpToIntCombine(N, DAG, DCI, Subtarget); case ISD::FDIV: return performFDivCombine(N, DAG, Subtarget); case ISD::OR: Index: test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -mtriple=aarch64-linux-eabi -o - | FileCheck %s + +%struct.a= type { i64, i64, i64, i64 } + +; DAG combine will try to perform a transformation that creates a vcvtfp2fxs +; with a v4f64 input. Since v4i64 is not legal we should bail out. We can +; pottentially still create the vcvtfp2fxs node after legalization (but on a +; v2f64). + +; CHECK-LABEL: fun1 +define void @fun1() local_unnamed_addr { +entry: + %mul = fmul <4 x double> zeroinitializer, + %toi = fptosi <4 x double> %mul to <4 x i64> + %ptr = getelementptr inbounds %struct.a, %struct.a* undef, i64 0, i32 2 + %elem = extractelement <4 x i64> %toi, i32 1 + store i64 %elem, i64* %ptr, align 8 + call void @llvm.trap() + unreachable +} + +; Function Attrs: noreturn nounwind +declare void @llvm.trap() +