diff options
author | Silviu Baranga <silviu.baranga@arm.com> | 2016-08-08 13:13:57 +0000 |
---|---|---|
committer | Silviu Baranga <silviu.baranga@arm.com> | 2016-08-08 13:13:57 +0000 |
commit | fa00ba3c1a43b52779d9d23fd9baef57601f6ea1 (patch) | |
tree | 235246bf654323f00681bbb0ffcabdd72cf51b54 | |
parent | 4ec22ec6b19d341af8106db2dc1964729510558d (diff) | |
download | bcm5719-llvm-fa00ba3c1a43b52779d9d23fd9baef57601f6ea1.tar.gz bcm5719-llvm-fa00ba3c1a43b52779d9d23fd9baef57601f6ea1.zip |
[AArch64] PR28877: Don't assume we're running after legalization when creating vcvtfp2fxs
Summary:
The DAG combine transformation that was generating the
aarch64_neon_vcvtfp2fxs node was assuming that all
inputs where legal and wasn't accounting that the input
could be a v4f64 if we're trying to do the transformation
before legalization. We now bail out in this case.
All illegal types besides v4f64 were already rejected.
Fixes https://llvm.org/bugs/show_bug.cgi?id=28877.
Reviewers: jmolloy
Subscribers: aemerson, rengolin, llvm-commits
Differential Revision: https://reviews.llvm.org/D23261
llvm-svn: 278002
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 11 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll | 24 |
2 files changed, 33 insertions, 2 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 4928f167e18..03c474c4456 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7684,6 +7684,7 @@ static SDValue performIntToFpCombine(SDNode *N, SelectionDAG &DAG, /// 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 @@ static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG, 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 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N, 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: diff --git a/llvm/test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll b/llvm/test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll new file mode 100644 index 00000000000..a71b5e86138 --- /dev/null +++ b/llvm/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, <double 6.553600e+04, double 6.553600e+04, double 6.553600e+04, double 6.553600e+04> + %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() + |